Internet Applications

Overview

Communication and application protocols form the foundation of Internet applications, which have also been implemented in other applications and operating systems that we use every day. Two of these protocols are HTTP and FTP.

Web page serving is provided using the HTTP protocol, while the pages that are presented use the HTML markup language, which allows for a rich graphical interface. The latest Internet Explorer (IE) browser implements dynamic HTML (DHTML) and the Document Object Model (DOM), which exposes Web page elements through a structured object model. The properties of these elements, such as color and content, can be manipulated through this model dynamically.

The IE application itself is a container for a browser control object, which provides the functionality of rendering HTML pages and facilitating communications between remote computers. This browser control exposes the functionality for any application that can manipulate COM objects, such as Windows Script Host (WSH).

Using the objects that are exposed by IE, you can perform HTTP operations, such as PUTting and GETting information. Scripts can use IE to integrate graphical interfaces into scripts, thus providing a more attractive and flexible alternative to the limited graphical Windows commands that are included with VBScript, such as Popup and InputLine. Because the whole DHTML object model is accessible through the browser component, forms can be manipulated by scripts. This enables powerful, event-driven data entry applications to be implemented, providing the WSH scripting environment with a much-needed graphical user interface (GUI) capability.

In addition to the functionality that is exposed through the IE objects, file transfer using the FTP protocol and IP diagnostics utilities such as address resolving (DNS) and pinging are also covered in this chapter. In addition, automating the MSN Messenger messaging functionality is demonstrated.

Displaying HTML

Problem

You want to use Internet Explorer (IE) to display information.

Solution

To use IE to display information, create an instance of IE using the ProgID InternetExplorer.Application and reference the Document object.

The following script starts IE and displays the message "hello world":

Dim objIE
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Navigate "about:blank"
objIE.Visible = True
objIE.Document.Write "hello world"

Discussion

WSH does not provide native GUI interface capabilities, apart from limited text input and display using the MsgBox and InputLine functions.

Internet Explorer (IE) provides a flexible GUI interface for WSH to output information. Any content sent to the browser can be formatted using existing HTML elements.

The Document object exposes the writeln and write methods, which can be used to output information to the browser. Their syntax is as follows:

objDocument.writeln | write strOutput

The difference between the writeln and write methods is that writeln adds a linefeed at the end of each line.

In the Solution script, the Navigate method is used to start a page. A page must first be navigated to before any document output can be generated.

The Navigate method requires a URL as the parameter. The URL can be in HTTP format (http://www.acme.com/default.htm) or file path format (D:datadefault.htm).

Manually building HTML formatting statements can be repetitive and time-consuming, and it can also generate large scripts. The following component, HTMLGen, simplifies the generation of HTML by encapsulating the core generation logic in a Windows Script Component:






 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 



To use the component, create an instance of the object using the ENTWSH.HTMLGen ProgID.

The StartDoc function starts building the HTML document. The first parameter specifies the title for the document, while the second is a Boolean parameter that if True will create an instance of IE.

Data can be added to the document by using the WritePara or WriteLine functions. Each of these functions requires a parameter that specifies the information you want to add to the document. The WritePara function adds an HTML paragraph tag (

) to the parameter, while WriteLine adds the line to the document without any additional formatting.

The following sample creates an instance of the HTMLGen component and outputs some text to the browser:

Set objIE = CreateObject("ENTWSH.HTMLGen")
 objIE.StartDOC "Hello World", True
 objIE.WriteLine "

Hello World

" objIE.WritePara "The quick brown dog. etc.. etc.." objIE.EndDOC

HTMLGen simplifies the creation of tables through the StartTable, WriteRow, and EndTable functions.

To create a table, call the StartTable function. It requires two parameters: the first is an array of values identifying the width of each cell, and the second is a value specifying the width of the table border.

Rows are added to the table using the WriteRow function. WriteRow takes two parameters: The first is an array of values for each cell in the row, and the second is a string of formatting characters that is applied to the whole row.

Once the table is built, use the EndTable function to complete the table.

Set objIE = CreateObject("ENTWSH.HTMLGen")
 objIE.StartDOC "Phone List", True

 'start a table with 3 columns and border width 0.
 objIE.StartTable (Array(100, 300)), "0"
 objIE.WriteRow (Array("Folder Name", "Size")), "bgcolor=""#FFFF00"""
 objIE.EndDOC
 objIE.WriteLine "

Phone List

" objIE.WritePara "The quick brown dog.. etc.. etc.." objIE.EndDOC

The following script uses the WSHCB.HTMLGen component to build a list of all directories over a certain size:


'dirinfo.vbs
Dim objIE, objFSO
Dim objFolder, objSrcFolder
Set objIE = CreateObject("ENTWSH.HTMLGen")
Set objFSO = CreateObject("Scripting.FileSystemObject")
On Error Resume Next
 objIE.StartDOC "Folder Size", True
objIE.WriteLine "

User Folder Size, over 5 megs

" objIE.StartTable Array(100, 300), "0" objIE.WriteRow Array("Folder Name", "Size"), "bgcolor=""#FFFF00""" For Each objFolder In objFSO.GetFolder("d:").SubFolders If objFolder.Size > 5000000 Then objIE.WriteRow Array(objFolder.Name, objFolder.Size), "" End If Next objIE.EndTable objIE.EndDOC strHTML = objIE.HTML

11 3 Displaying an HTML Logon Message

Problem

You want to display an HTML message at logon.

Solution

You can create an instance of IE and sink IE events by specifying the second parameter to the WScript.CreateObject method. This will allow the script to process actions performed by IE, such as when IE is exited. This allows scripts to process events generated by other applications—in this case, determining when IE is exited.

The Solution script displays the following welcome.htm HTML page:


Welcome To Acme

Welcome To Acme's Home Page

The script creates an instance of Internet Explorer and customizes the appearance by removing the application menu and toolbar, as well as setting a custom window width and height. This hides the identity of the browser application from the users. The welcome.htm Web page is then displayed, and the script will not exit until the window is closed or the Continue button is clicked in the page:


'logon.vbs
 Option Explicit
 Dim objIE, bDone, objDoc
'create an instance of the IE browser. Allow IE events to be caught
'by specifying the second parameter, ie_
Set objIE = WScript.CreateObject("InternetExplorer.Application","ie_")
 'turn off all on screen 'clutter'
 objIE.MenuBar = False
 objIE.ToolBar = 0
 objIE.Height = 350 'resize browser form
 objIE.Width = 550
 'select the page to display
 objIE.Navigate "d:datawshiewelome.htm" 'wait to load page
 While objIE.Busy
 WScript.Sleep 100
 Wend
 objIE.Visible = True
 bDone = False
 'link to the browser document
 Set objDoc = objIE.Document
 'assign the onclick event of the HTML pages cmdContinue button to the
 'cmdContinue_OnClick sub routine in this script
 Set objDOC.All("cmdContinue").onclick = GetRef("cmdContinue_OnClick")
 'loop until done
 While Not bDone
 wscript.sleep 100
 Wend

 'this event is fired when IE is exited
 Sub ie_OnQuit
 bDone = True
 End Sub
 Sub cmdContinue_OnClick
 objIE.Quit
 bDone = True
 End Sub

Discussion

Internet Explorer (IE) exposes a number of events that can be accessed through WSH.

In order to attach to IE events, known as sinking, specify the second parameter for the WScript.CreateObject method. Specifying this parameter makes the script an event sink. The script will "listen" to events generated by the object, and it can optionally trap the events in subroutines. This parameter identifies what will be prefixed to the name of the event subroutines. The subroutines are associated with events fired from the object, in this case IE.

In the following sample an instance of IE is started and events are sinked to subroutines prefixed with ie_:


'create an instance of the IE browser. Allow IE events to be caught
'by specifying the second parameter, ie_
 Set objIE = WSscript.CreateObject("InternetExplorer.Application","ie_")

When an event in IE is fired, the WSH script looks for a subroutine with the name of the event prefixed with ie_. When IE is shut down, it fires an OnQuit event. If you wanted to trap it in the script, you would create a subroutine called ie_OnQuit. This subroutine would execute in the script when IE was closed down.

The script starts by opening a "welcome" Web page through the Navigate method. This operation is asynchronous, which means the script will not wait until the page is loaded, so a loop is added to wait until the page is successfully loaded.

If this loop was not added and a reference was made to the Document property of IE before the requested page was generated, an error would occur. Note that even with this loop, IE can indicate the page is loaded before it has actually completed, thus generating an error, so additional logic may have to be added to trap any errors generated. In the previous example, a WSscript.Sleep statement is used to prevent this.

Once the page is displayed, the script will stop in a loop and not continue until the bDone variable is True. This is set when Internet Explorer is closed, which occurs when the OnQuit event fires, which will call the ie_OnQuit subroutine in the script.

Table 11-2 lists a number of events that IE exposes.

Table 11-2: IE Events

EVENT

DESCRIPTION

DocumentComplete

Fires when a document has completed and displayed in browser

DownloadBegin

Fires when a document has been requested for download

DownloadComplete

Fires when a download is complete but has not been displayed yet

OnQuit

Fires when IE application is terminated

Table 11-3 lists a few of the methods that IE exposes.

Table 11-3: IE Methods

METHOD

DESCRIPTION

Stop

Stops the current IE operation

Quit

Exits IE

Table 11-4 lists a few of the properties that IE exposes.

Table 11-4: IE Properties

PROPERTY

DESCRIPTION

AddressBar, MenuBar, ToolBar

Boolean values. If True, the browser element the property represents is displayed. If False, the element is not shown.

Height, Width

Height and width of the browser in pixels.

Top, Left

Location of the browser in pixels.

The preceding tables do not list all methods, events, and properties exposed by the IE object. The best way to determine all available object attributes is to use the object browser integrated into Microsoft Office applications or Visual Basic, or the separate object browser available from Microsoft (see Solution 9.1). The script also traps the events from the HTML Continue button. Solution 11.4 covers capturing events from HTML elements.

See Also

For more information, read the MSDN Library article "Reusing the WebBrowser Control" (http://msdn.microsoft.com/workshop/browser/webbrowser/WebBrowser.asp).

11 4 Creating an HTML Form

Problem

You want to create a data entry form using Internet Explorer (IE).

Solution

The code for this HTML page is used as the source for the Solution script. Save it as calcage.htm:


Calculate AgeFirst Name:
Last Name:
Date of birth:
Age  

The following sample displays the calcage.htm HTML page. The page queries for the user's name and birth date and calculates the user's age based on his or her birth date. Events from HTML elements such as buttons and fields are trapped by the script, allowing the script to execute subroutines when certain events occur on the page, such as buttons being clicked, the mouse moving in and out of fields, and on the change of values in a field:


'calcage.vbs
Dim objIE, objDoc, bDone
'create an instance of the IE browser
Set objIE = WScript.CreateObject("InternetExplorer.Application","ie_")
'turn off all menus/toolbars and set window size
objIE.AddressBar= False
 objIE.MenuBar= False
 objIE.ToolBar= 0
 objIE.Width = 400
 objIE.Height = 250

 'go to the page
 objIE.Navigate "e:datawshwshchapter 11calcage.htm"
 'wait to load page
 While objIE.Busy
 Wend
 objIE.Visible = True 'display page
 Set objDoc = objIE.Document.All
 'assign HTML form buttons to subroutines
 Set objDOC("cmdQuit").onclick = GetRef("cmdQuit_OnQuit")
 Set objDOC("cmdCalculate").onclick = GetRef("cmdCalculate_OnClick")
 Set objDOC("txtBirthDate").OnChange = GetRef("txtBirthDate_OnChange")
 Set objDOC("txtBirthDate").OnMouseOver = GetRef("txtStatus_Change")
 Set objDOC("txtBirthDate").OnMouseDown = GetRef("txtStatus_Change")
 Set objDOC("txtBirthDate").OnMouseUp = GetRef("txtStatus_Change")

 bDone = False
 While Not bDone
 WScript.Sleep 100
 Wend

 Sub txtStatus_Change
 objDOC("txtBirthDate").value = Date
 End Sub

 'event fires when IE is exited.
 Sub cmdQuit_OnQuit
 objIE.Quit
 bDone = True
 End Sub

 'event fires when value in birth date field is changed
 Sub txtBirthDate_OnChange
 Call CalculateAge()
 End Sub

 'event fires when value in Full Name field is changed
 Sub cmdCalculate_OnClick
 If CalculateAge() Then
 WScript.Echo objDOC("txtFirstName").value & " "& _
 objDOC("txtLastName").value & " is "& _
 objDOC("txtAge").value
 End If
 End Sub

'validates date field and calculates age
Function CalculateAge
 Dim strDate
 'get the birthdate entered on the form
 strDate = objDoc("txtBirthDate").value
 'validate date and calulate age
 If Not IsDate(strDate) Then
 MsgBox "You must enter a valid date"
 CalculateAge = False
 Else
 objDoc("txtAge").value = DateDiff("yyyy",CDate(strDate), Date)
 CalculateAge = True
 End If
End Function

Discussion

Using Internet Explorer and standard HTML forms, WSH can perform sophisticated data entry operations, allowing for an event-driven forms environment similar to that provided by Microsoft Visual Basic or Access.

Internet Explorer (IE) provides the ability to host complex HTML forms. These forms can be composed of any number of fields and other form objects, such as drop-down lists, radio buttons, and check boxes.

Create an HTML form using a standard HTML editor such as FrontPage or Dreamweaver, or even Notepad. Make note of the names given to any fields, buttons, or other HTML interface elements you want to reference from your script.

Open the page in the script using the Navigate method and get a reference to the HTML page. The URL for the page can be a remote Web server or a local file.

All elements in an IE form—actually, all elements in any HTML document— are exposed through an object model called the Document Object Model (DOM). This model exposes the structure of an HTML document, allowing elements to be enumerated and manipulated.

The ability to access DOM elements is particularly useful for HTML forms, because the values of form fields can be updated or read as required:


'create an instance of the IE browser
Set objIE = CreateObject("InternetExplorer.Application")

'build a page containing a text field prompting for a date
objIE.Navigate "about:Date: 

A field is displayed in the browser prompting for a date value. The script sets the value of the field by setting the DOM object's Value property to today's date.

The names used to reference the HTML DOM elements are the ones associated with the elements when creating the HTML document. A consistent naming convention for the elements can be useful when building the HTML forms, allowing the type of elements to be easily identified in the script. In the examples in this section, text fields are prefixed with txt. For example, Figure 11-1 shows the Microsoft FrontPage Text Box Properties dialog box, which displays the name that has been assigned to an HTML text box field.

click to expand
Figure 11-1: Microsoft FrontPage text box name assignment

DOM elements also expose events. When a form button is clicked or form fields are modified, an event is generated. Unfortunately, you cannot sink DOM events using the WSscript.Create method in the same way as the IE object. Because you cannot create instances of HTML Document objects, you cannot specify an event prefix to bind document events to, as you can with IE events.

You can use the GetRef function to get the reference to the function in the script to which you want to bind. The syntax is as follows:


Set objDOMElement.event = GetRef(strFunction)

The objDOMElement object represents an HTML Document Object Model (DOM) element object to bind the subroutine to. This may be a button, a text field, or any other HTML object on a Web page. event identifies the DOM object event, while strFunction identifies the name of the VBScript subroutine the event is to bind to.

DOM events can be bound to any input element (buttons, text boxes, and so on) on an HTML page. The following sample binds the HTML element txtDescription's onchange event to the txtDescription_OnChange subroutine:


Set objDOC.All("txtDescription").onchange = _
 GetRef("txtDescription_OnChange")

When the value of the HTML field txtDescription changes, the subroutine txtDescription_OnChange in the script is executed.

Multiple events can be bound to the same subroutine. Table 11-5 lists commonly used events.

Table 11-5: HTML Events

EVENT

DESCRIPTION

onclick, ondblclick

Fires when an element is clicked or double-clicked

onchange

Fires when a change is made to an element, such as a text or check box

onmouseover, onmouseout

Fires when the mouse moves over or out of an element

onmousedown, onmouseup

Fires when the mouse button is clicked and depressed

GetRef is specific to VBScript and the functionality provided by it may be implemented differently in other scripting languages. JScript can reference function pointers by directly referencing the function name. The following VBScript and JScript statements provide the equivalent functionality of assigning a subroutine for the onclick event of a DHTML element.

VBScript:


'VBScript
Set objDOC("cmdQuit").onclick = GetRef("cmdQuit_OnQuit")

JScript:


//JScript
objDOC("cmdQuit").onclick = cmdQuit_OnQuit;

See Also

For more information, read the MSDN Library article "Reusing the WebBrowser Control" (http://msdn.microsoft.com/workshop/browser/webbrowser/WebBrowser.asp).

11 5 Enumerating HTML Elements

Problem

You want to download a Web page, including any images in the page.

Solution

You can get a reference to the Document object for the page you want to download and then list the images collection for each image in the page. Use the GetImage function created in Solution 11.1 to download the images:





 

Discussion

All elements in HTML documents can be accessed through automation. This allows for specific parts of an HTML document to be listed.

The Document object exposes a number of collections that store elements associated with the page, such as the images and links collections. The images collection stores all images stored in the document, while the links collection stores any links to other pages. The Solution script uses the images collection to list all images for a specified page.

As well as specific collections, the whole DHTML structure of a document can be enumerated. The Document object's All property is a collection of all elements within a page.

The following sample command-line script, htmlelem.vbs, opens the HTML document specified in the command line and outputs all DHTML elements in the document:


'htmlelem.vbs
 'lists all elements in document specified by command line argument
 Dim objIE, objDoc
 If WScript.Arguments.Count <> 1 Then
 WScript.StdErr.WriteLine "You must specify a URL to process"
 WScript.Quit
 End If

 'create an instance of the IE browser
 Set objIE = CreateObject("InternetExplorer.Application")

 'go to the page
 objIE.Navigate Wscript.Arguments(0)
 'wait to load page
 While objIE.Busy : Wend
 Set objDoc = objIE.Document.All
 'loop through all elements in the HTML document
 For Each objItem In objDOC
 'check if the element is an input element (input box, check box etc.)
 If TypeName(objItem) = "HTMLInputElement" Then
 Wscript.Echo objItem.value, objItem.name, objItem.type
 Else
 Wscript.Echo TypeName(objItem) 'just output the HTML object type
 End If
 Next

The htmlelem.vbs script requires a URL to the page you want to enumerate. The URL can point to a page on a Web server or a local path. The script uses the TypeName function to determine the name of the object being referenced.

Many of the properties exposed through the HTML object can be modified. In the Solution script, the source for each image in the HTML page, identified by the src property, is modified to point to a local path for the downloaded image.

Each DHTML element can expose a number of properties, methods, and events, which vary from element to element. To determine the functionality exposed by any given event, use the object browser included with Microsoft Office 97/2000 applications or Visual Basic.

To browse DHTML elements from an Office 97/2000 application, follow these steps:

  1. Start an Office application, such as Word or Excel.
  2. Choose Tools > Macro > Visual Basic Editor.
  3. Select Tools > References. From the list of available objects, find the Microsoft HTML Object Library and click the check box.
  4. Click OK.
  5. At any time within the Visual Basic Editor, press the F2 key. This will display the object browser.
  6. From the Project/Library drop-down in the upper-left corner, select MSHTML Library.

You will now see a list of HTML objects. Associated events, methods, and properties appear in the left pane and all properties, methods, and events appear in the right pane, as shown in Figure 11-2.

click to expand
Figure 11-2: MSHTML Library Object Browser

The next script, ieadmin.vbs, uses an administrative HTML form, adminform.htm, to build a batch file to create a new user. Figure 11-3 shows the completed form.

click to expand
Figure 11-3: IE Create User form

The script generates the command-line commands required to generate a new user based on the criteria entered into the form. The output is sent to standard output and contains information required to create a new user account and optionally create a home directory and shares as well as Exchange mail accounts.

The commands generated by the script use command-line scripts built in other chapters to perform these operations:


'ieadmin.vbs
Dim objIE, objFSO, objDoc, objTS, strLine, nPos, objElem
'create an instance of the IE browser
Set objIE = Wscript.CreateObject("InternetExplorer.Application","ie_")
'objIE.FullScreen = True
'turn off all on screen 'clutter'
objIE.AddressBar= False
objIE.MenuBar= False
objIE.ToolBar= 0
objIE.Navigate "e:datawshwshchapter 11adminform.htm"
 'wait to load page
 While objIE.Busy
 WScript.Sleep 100
 Wend
Set objDoc = objIE.Document
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTS = objFSO.OpenTextFile("settings.ini",1)
Do While Not objTS.AtEndOfStream
 strLine = objTS.ReadLine
 nPos = Instr(strLine,"=")
 If nPos > 0 Then
 Set objItem = objDoc.all(Trim(Left(strLine,nPos-1)))
 If objItem.type = "checkbox" Then
 objItem.checked = Cbool(Mid(strLine,nPos+1))
 Else
 'objDoc.all(Trim(Left(strLine,nPos-1))).value = Mid(strLine,nPos+1)
 objItem.value = Mid(strLine,nPos+1)
 End If
 End If
Loop

Set objDOC.All("cmdCreateUser").onclick = GetRef("cmdCreateUser_OnClick")
Set objDOC.All("cmdQuit").onclick = GetRef("Quit_OnQuit")
Set objDOC.All("cmdSaveSettings").onclick = _
 GetRef("cmdSaveSettings_OnChange")
Set objDOC.All("txtUserName").OnChange = GetRef("txtUserName_OnChange")
Set objDOC.All("txtFullName").OnChange = GetRef("txtFullName_OnChange")
Set objDOC.All("txtDescription").OnChange = GetRef("txtDescription_OnChange")
objIE.Visible = True

bDone = False
 While Not bDone
 wscript.sleep 100
 Wend

Sub Quit_OnQuit
 objIE.Quit
 bDone = True
End Sub

'event fires when value in Full Name field is changed
Sub txtUserName_OnChange
 objDoc.all("txtExchangeAlias").value = objDoc.all("txtUserName").value
 objDoc.all("txtUserDirectory").value = _
 objDoc.all("txtDirectoryPath").value _
 & objDoc.all("txtUserName").value
 objDoc.all("txtUserShare").value = objDoc.all("txtShareComputer").value _
 & objDoc.all("txtUserName").value & "$"
 End Sub

 'event fires when value in Full Name field is changed
 Sub txtFullName_OnChange
 Dim aName, nCount
 'split values into array
 aName = Split(objDoc.all("txtFullName").value)

 nCount = Ubound(aName)
 'check if any values in array
 If nCount > 0 Then
 'set Exchange user first name to first element
 objDoc.all("txtFirstName").value = aName(0)
 'set last name element
 If nCount=1 Then
 objDoc.all("txtLastName").value = aName(1)
 Else
 objDoc.all("txtLastName").value = aName(2)
 objDoc.all("txtUserInitials").value = aName(1)
 End If
 End If
 End Sub
'event fires when value of Description field changes
 Sub txtDescription_OnChange
 'set Exchange Title field to value of account description
 objDoc.all("txtTitle").value = objDoc.all("txtDescription").value
 End Sub

'event fires when Create User button is clicked
 Sub cmdSaveSettings_OnChange
 'open settings file
 Set objFSO = CreateObject("Scripting.FileSystemObject")
 Set objTS = objFSO.OpenTextFile("settings.ini",2,True)
 'loop through all elements in the HTML document
 For Each objItem In objDOC.All
 'check if the element is an input element (input box, check box etc.)
 'and contains a value
 If TypeName(objItem) = "HTMLInputElement" Then
 If (objItem.type = "text") _
 And objItem.value<>"" Then
 'write the value to the settings file
 objTS.WriteLine objItem.name & "=" & objItem.value
 ElseIf objItem.type = "checkbox" Then
 objTS.WriteLine objItem.name & "=" & objItem.checked
 End If
 End If
 Next
 objTS.Close
End Sub

 Sub cmdCreateUser_OnClick()
 Dim strLine, objD, objTS
 Set objD = objDOC.All
 Set objTS = WScript.Stdout
 strLine = "usermnt.wsf "& objD("txtUserName").value & _
 " /p:Description """ & objD("txtDescription").value _
 & """" & "/p:FullName """ & objD("txtFullName").value _
 & """" & "/p:Password """ & objD("txtPassword").value _
 & """" & vbCrLf

 'check if a home directory should be created
 If objDOC.All("chkHomeDirectory").checked Then
 strLine = strLine & "usermnt.wsf "& objD("txtUserName").value & _
 " /u /p:HomeDirDrive """ & objD("txtHomeDirectory").value _
 & """" & "/p:HomeDirectory """ & _
 objD("txtUserShare").value & """" & vbCrLf

 strLine = strLine & "md "& objD("txtUserDirectory").value & vbCrLf
 End If

 'check if an Exchange account should be created
 If objDOC.All("chkCreateExchangeAccount").checked Then
 strLine = strLine & "createxuser.wsf " _
 & objD("txtExchangeServer").value & _
 " "& objD("txtExchangeSite").value & " "& _
 objD("txtExchangeAlias").value & """" & _
 objD("txtDisplayName").value & """" & _
 objD("txtSMTPAddress").value & " "_
 & objD("txtDomain").value & " " & objD("txtUserName").value _
 & vbCrLf
'createxuser.ws server site alias displayname SMTPAddress domain accountName
 End If
 objTS.WriteLine strLine
 End Sub

Default settings are saved by selecting the Save Current Settings button on the HTML form. The values are stored in the file settings.ini. These values are loaded into the page when the script is started. Each element in the HTML document is checked to see if it is an input element (text or check box), and if it contains a value it is written to the settings file.

To store the results generated by the script, redirect the output to a file:


cscript ieadmin.vbs > newusers.bat

All output generated by the script will be appended to the file newusers.bat. This allows for scripting logic for multiple users to be generated at one time. Once the creation of users is completed, exit the ieadmin script and run the newusers.bat file from the command line.

See Also

Solution 11.4.

11 6 Creating a GUI Menu

Problem

You want to create a generic GUI menu that displays a list of selections and then passes the result to a batch file or another WSH script.

Solution

You can use the following script, guimenu.vbs, to display a graphical menu:


'guimenu.vbs
 'build menu in IE based on command line parameter
 Option Explicit
 Dim objIE, objDoc, aMenuItems, nReturnValue
 Dim nReturn, nF, bDone
 If WScript.Arguments.Count <> 1 Then
 WScript.StdErr.WriteLine _
 "You must specify a list of menu items seperated by semicolons"
 Wscript.Quit -1
 End If
'create an instance of the IE browser
 Set objIE = WScript.CreateObject("InternetExplorer.Application", "ie_")
 'get the menu items
 aMenuItems = Split(WScript.Arguments(0),";")
 'turn off all on screen elements
 objIE.AddressBar= False
 objIE.MenuBar= False
 objIE.ToolBar= 0
 objIE.Navigate "about:blank"
 'wait to load page
 While objIE.Busy : Wend
 Set objDoc = objIE.Document

'build HTML page based on menu items
For nF = 0 To Ubound(aMenuItems)
 objDoc.Write "

" Set objDOC.All(Cstr(nF)).onclick = GetRef("OnButton_Click") Next objIE.Height = 60 * nF + 35 objIE.Width = 300 objIE.Visible=True bDone = False While Not bDone WScript.Sleep 100 Wend Wscript.Stdout.WriteLine nReturnValue nReturn = nReturnValue 'check if menu button selected, exit IE If nReturnValue <> -1 Then objIE.Quit WScript.Quit nReturn 'event fires when IE is exited Sub ie_OnQuit nReturnValue = -1 bDone = True End Sub 'this subroutine is called when a menu button is clicked Sub OnButton_Click nReturnValue = objdoc.activeelement.name bDone = True End Sub

Discussion

Traditionally, command-line scripts have implemented simple text menus. The GUI menu script provides similar functionality, but instead opens an Internet Explorer (IE) window and displays a list of options specified on the command line.

The Solution script builds a menu using IE based on command-line options. The syntax is as follows:


guimenu.vbs menuoptions

The menuoptions parameter contains the menu items to be displayed. The items are separated by semicolons.

Menu items are represented as HTML buttons. When a menu item is clicked, it outputs the value to standard output as well as setting the DOS errorlevel value, which allows menus to return values to DOS batch files. The item selected is identified as a number, starting sequentially from 0.

If IE is terminated before a menu item is selected, the value -1 is returned.

The following batch file displays two menu options and performs an operation based on which menu item was selected:


Rem Display menu and perform appropriate action
Rem based on selected option
@echo off
guimenu "Create User;List Process"
Rem check errorlevel
If errorlevel -1 goto quit
If errorlevel 0 goto option1
If errorlevel 1 goto option2

:option0
Echo Option 0 selected
goto quit

:option1
Echo Option 1 selected
goto quit
:quit

To use guimenu with another WSH script, pipe the results of guimenu to the script you are using to check the selected menu items. In the following sample, two menu items are displayed and the results are piped to the opt.vbs script:


cscript guimenu.vbs "Create User;List Process" | cscript opt.vbs

The opt.vbs script reads the menu selection from the standard input:


'opt.vbs
'performs operation based on selected menu item
Dim strOption
strOption = WScript.Stdin.ReadLine

Select Case strOption
 Case "0"
 Wscript.Echo "Option 0 was selected. . ."
 Case 111"
 Wscript.Echo "Option 1 was selected. . ."
End Select

11 7 Transferring Files Using FTP

Problem

You want to transfer a directory from an FTP server to your local machine.

Solution

WSH does not include any FTP component, nor are there any flexible FTP freeware components available. Mabry Software (http://www.mabry.com/) sells an FTP COM (FTP/X) object that provides FTP file transfer functionality.

The Solution code uses the Mabry FTP component to transfer files from an FTP server to a local directory:


'ftpget.vbs
'copies files from FTP directory to local directory
Const SynchronousMode = 1
Dim objFTP, nF, strName
 Set objFTP = CreateObject("Mabry.FtpXObj")
'connect to FTP server Thor
 objFTP.Blocking = SynchronousMode
 objFTP.LogonName = "administrator"
objFTP.LogonPassword = "downunder"
 objFTP.host = "thor" 'hostname
 objFTP.Connect

If Err Then
 WScript.Echo "Error connecting to FTP host"
End If
 'get a directory listing for remote machine
 objFTP.GetDirList "/"
 For nF = 0 To objFTP.DirItems - 1
 'get item from array
 strName = objFTP.DirItem(nf)
 'check if item is not a directory
 If Not InStr(strName, "

") > 0 Then 'get the name of the file, which for IIS starts at position 40 strName = Mid(strName, 40) 'strip off carriage return/line feed from end of string strName = Left(strName, Len(strName) - 2) 'get file, store in local drive objFTP.GetFile strSrcDir & strName, "d:data" & strName End If Next objFTP.Disconnect

Discussion

The Mabry FTP object performs standard FTP operations, such as file upload and download, in addition to file and directory maintenance operations (directory creation and file/directory deletion operations).

To use the object, create an instance using the ProgID Mabry.FtpXObj. Before you can perform any operations, you must first connect to an FTP server.

To connect to a server, identify the server you want to use by setting the Host property. This can be either a fully qualified domain name (e.g., ftp.acme.com) or an IP address.

Call the Connect method to open a connection to the server. The Connect method can take the LogonName, LogonPassword, and Account parameters.

The LogonName and LogonPassword parameters identify the logon user ID and optional password. The Account parameter is also optional and is specific to certain FTP servers.

Parameters for the Connect method are optional and can be set using the corresponding LogonName and LogonPassword properties, as demonstrated in the Solution.

Once connected, you can send and receive files using the GetFile and PutFile methods. Both methods require a source and destination path for the file to be specified.

For the GetFile method, the source is the file on the remote FTP server and the destination is a local file path. When using the PutFile method, this is reversed: The source is a local file and the destination is the path to the remote FTP server. You must specify the exact path for both source and destination files and you cannot use wildcards in the file paths to specify multiple files.

The following sample implements a command-line script that copies the contents of a local directory, including all subdirectories and files, to an FTP server:


 'ftpxcopy.vbs
 'copies directory and all sub directories to FTP server
Const SynchronousMode = 1
 Dim objFile, objFSO, objFTP, strUser
 Dim strSrcRoot, nStart, strDstRoot

If Not WScript.Arguments.Count = 5 Then
 ShowUsage
 Wscript.Quit
 End If
 'get user id, host, password and source/destination directories
 strSrcRoot = Wscript.Arguments(3)
 strDstRoot = Wscript.Arguments(4)
 If Not Right(strSrcRoot,1) = "" Then strSrcRoot = strSrcRoot & ""
 If strDstRoot = "/" Then strDstRoot = ""

 nStart = Len(strSrcRoot)
 Set objFSO = CreateObject("Scripting.FileSystemObject")
 Set objEvent = Wscript.CreateObject ("ENTWSH.RecurseDir","ev_")
 Set objFTP = CreateObject("Mabry.FtpXObj")
 objFTP.Blocking = SynchronousMode
 objFTP.host = Wscript.Arguments(0)
 objFTP.Connect Wscript.Arguments(1), Wscript.Arguments(2)
 objEvent.Path = strSrcRoot
 Set objFSO = CreateObject("Scripting.FileSystemObject")
 Call objEvent.Process()
 objFTP.Disconnect

 Sub ShowUsage
WScript.Echo "ftpxcopy.vbs copies local directory to FTP server" _
 & vbLf & "Syntax:" & vbCrLf & _
 "ftpxcopy host user password source destination "& vbCrLf & _
 "host FTP server to copy to" & vbCrLf & _
 "user user name to log on to FTP server" & vbCrLf & _
 "password password to logon onto FTP server" & vbCrLf & _
 "source local path to source directory" & vbCrLf & _
 "destination path to FTP directory" & vbCrLf & _
 "Example: ftpxcopy acme freds sderf d:datawebsiteacme /webroot/acme"
 End Sub

 Sub ev_FoundFile(strPath)
 On Error Resume Next
 'get a reference to specifed file
 Set objFile = objFSO.GetFile(strPath)

 'convert file path to corresponding FTP directory
 strFTPDir = Mid(objFile.ParentFolder, nStart)
 strFTPDir = strDstRoot & Replace(strFTPDir, "","/")

 If Not Right(strFTPDir,1) = "/" Then strFTPDir = strFTPDir & "/"
 objFTP.PutFile strPath, strFTPDir & objFile.Name

 If Not objFTP.LastError = 0 Then
 MakeDirPath (Left(strFTPDir,Len(strFTPDir)-1))
 objFTP.PutFile strPath, strFTPDir & "/" & objFile.Name
 End If
End Sub

'Procedure MakeDirPath
'Description
'Creates a directory path on remote FTP server
'Parameters
'strPath FTP directory path to create
Sub MakeDirPath(strPath)
Dim nF, strRest, strNextPath
On Error Resume Next
bDone = False
strNextPath = strPath

 Do While Not bDone
 'check if directory exists
 objFTP.ChangeDir strNextPath ', strRest
 'if directory doesn't exist, then parse next level in path
 If Not objFTP.LastError = 0 Then
 nF = InStrRev(strNextPath, "/")
 strRest = Mid(strNextPath, nF) & strRest
 strNextPath = Left(strNextPath, nF - 1)
 Else
 'directory found, create path below it
 strRest = Mid(strRest,2) & "/"
 nF = 0
 Do While True
 nF = Instr(strRest,"/")
 strNextPath = strNextPath & "/" & Left(strRest, nF - 1)
 objFTP.CreateDir strNextPath
 WScript.Echo "Creating directory " & strNextPath
 If nF = Len(strRest) Then Exit Do
 strRest = Mid(strRest, nF + 1)
 Loop
 bDone = True
 End If
 Loop
End Sub

The ftpxcopy script copies all files and subdirectories over. If the subdirectory does not exist on the FTP server, it is created. The FTP protocol does not provide the ability to copy directories, so the directory structure is recursively copied using the ENTWSH.RecurseDir component created in Solution 5.10.

Directories that don't exist on the FTP server are built using the MakeDirPath subroutine using the FTP component's CreateDir method.

No method exists to determine if a directory already exists, so the FTP component's ChangeDir method is used to change the directory. If the directory does not exist, an error will occur, which is checked using LastError. The directory is then created.

The syntax for the command-line script is as follows:


ftpxcopy host user password source destination

The host parameter specifies the FTP server to connect to, by either fully qualified domain name or IP address. FTP Logon credentials are specified by the user and password parameters. The local source and remote destination directories are identified by the source and destination parameters, respectively.

The following command line copies the local directory from d:datawebsiteacme to the FTP directory /webroot/acme on server ftp.acme.com:


ftpxcopy ftp.acme.com freds sderf d:datawebsiteacme /webroot/acme

Note that the FTP server you are connecting to must be configured for write access and allow for the creation of directories.

If you just require the ability to send and receive individual files, you can use the free ASPInet FTP control that you can download from http://www.serverobjects.com/. The control must be registered using the regsvr32.exe program on each computer you want to use it. This control allows for sending and receiving individual files:


Const FTP_TRANSFER_TYPE_ASCII = 1
Const FTP_TRANSFER_TYPE_BINARY = 2
Dim objFTP
Set objFTP = CreateObject("AspInet.FTP")
If objFTP.FTPGetFile("ftp.acme.com", "userid", "password", _
 "/data.txt", "d:datadata.txt", True, FTP_TRANSFER_TYPE_ASCII) Then
 WScript.Echo "File download succeeded"
End If

If objFTP.FTPPutFile("ftp.acme.com", "userid", "password", _
 "/data.txt", "d:datadata.txt", FTP_TRANSFER_TYPE_ASCII) Then
 Wscript.Echo "File download succeeded"
End If

The ASPInet object exposes two methods: FTPGetFile and FTPPutFile. FTPGetFile retrieves a file from a FTP server, while FTPPutFile downloads a text file to an FTP server.


result=objFTP.FTPGetFile(Host,Userid,Password,Remotefile,Localfile,Overwrite,Type)
result = objFTP.FTPPutFile(Host, Userid, Password, Remotefile, Localfile, Type)

Both methods share the first five parameters: Host, Userid, Password, Remotefile, and Localfile. The Host parameter is the address of the FTP server, and Userid and Password are the FTP logon user ID and password associated with the account, respectively. Remotefile is the path to the file on the FTP server and Localfile is the path to the local file.

FTPGetFile provides a Boolean Overwrite parameter. If True, the local destination file is overwritten if it already exists. The Type parameter identifies the data type of the file being transferred-if the value is 1, the file is ASCII, if the value is 2, the file is binary.

See Also

For more information on the FTP/X COM component, visit http://www.mabry.com, and for information on the ASPInet component, visit http://www.serverobjects.com.

11 8 Domain Name Resolution

Problem

You want to translate an IP address to a domain name.

Solution

WSH doesn't provide any IP lookup capabilities. A third-party freeware component, the System Scripting Runtime object from Netal (http://www.netal.com/), provides this functionality:


Dim objIP, strAddress
'create an instance of the scripting host object
Set objIP = CreateObject("SScripting.IPNetwork")
'lookup the domain name for a IP address
strAddress = objIP.DNSLookup("207.46.230.219")
WScript.Echo "The FQDN for the address is "& strAddress

Discussion

Reverse lookup is the process of translating an IP address to a domain name and vice versa. There is no support for reverse lookups supplied by the standard WSH objects.

Netal (http://www.netal.com/) provides a freeware component library, System Scripting Runtime, which is an element of their commercial System Script Host scripting environment product. The component must be registered using the regsvr32.exe program on each computer you want use it. Once registered, an instance of the object can be created using the SScripting.IPNetwork ProgID.

System Scripting Runtime provides a number of IP- and system-related operations. Address lookups are provided by the DNSLookup method. The syntax is as follows:


strAddress = objSSIP.DNSLookup(strHost)

strHost represents the address to look up. It can be either an IP address (for example, 192.168.1.100) or a domain name (e.g., http://www.acme.com). The method returns a resolved address if successful. If not successful, it returns an empty string. No error is generated if the host address cannot be resolved.

The following script opens an IIS log file and performs a reverse lookup on each IP address in the file. A count is maintained for each valid address that is referenced, providing a simple page hit counter mechanism.


Dim objFSO, objTxtStrm, strLine
 Dim objRegExp, objIP, objDict
 Dim strResolve, strKey
 'create dictionary, FSO and IPnetwork objects..
 Set objDict = CreateObject("Scripting.Dictionary")
 Set objIP = CreateObject("SScripting.IPNetwork")
 Set objFSO = CreateObject("Scripting.FileSystemObject")
 'create Regular expression
 Set objRegExp = CreateObject("Vbscript.RegExp")
 'set pattern to validate ip address.. x.x.x.x
 objRegExp.Pattern = "(d+(.|)){4}"

 'open log file
 Set objTxtStrm = _
 objFSO.OpenTextFile("d:winntsystem32logfilesw3svc1ex990611.log")
 'loop through and process each line
 Do While Not objTxtStrm.AtEndOfStream
 strLine = objTxtStrm.ReadLine
 'test line against regular expression
 If objRegExp.test(strLine) Then
 'reverse lookup IP address in line
 strResolve = _
 objIP.DNSLookup(Mid(strLine, 10, InStr(10, strLine, "") - 10))
 'if resolved to valid domain address add to dictionary
 If Not strResolve = "" Then
 'if already exists, increase count
 If objDict.Exists(strResolve) Then
 objDict(strResolve) = objDict(strResolve) + 1
 Else
 objDict.add strResolve, 1
 End If
 End If
 End If
 Loop

 'loop through and list domain name hit counts
 For Each strKey In objDict.Keys
 WScript.Echo strKey & ""& objDict.item(strKey)
 Next

See Also

The System Scripting Runtime download, documentation, and examples are available at http://www.netal.com/ssr.htm.

11 9 Pinging a Computer

Problem

You want to ping a computer.

Solution

WSH doesn't provide any ping capabilities through its object model. There are a number of freeware COM controls, however, that provide this functionality. One example is the System Scripting Runtime object from Netal:


Dim objIP

 'create IPnetwork object
 Set objIP = CreateObject("SScripting.IPNetwork")
 'check if machine 'elvis' is
 If objIP.Ping("elvis") = 0 Then
 WScript.Echo "Elvis is alive!"
 End If

Discussion

Ping functionality is available through the freeware System Scripting Runtime component available from http://www.netal.com/. The syntax is as follows:


nResult = objIP.Ping(Address, [Response,] [Source,] [Timeout,] [TTL,]
[BufferSize])

Table 11-6 lists Ping method arguments.

Table 11-6: Ping Method Arguments

PARAMETER

DESCRIPTION

Address

Machine to ping. Can be either a fully qualified domain name or an IP address.

Response

Response time in milliseconds.

Source

IP address from which response was sent.

Timeout

Response timeout in milliseconds. Default is 1,000.

TTL

Time-to-live of the request packet. Uses system default value.

BufferSize

Number of bytes to send in each echo request packet. Size in bytes. Default is 32.

All parameters except Address are optional.

If the control is not available, the good old command ping included with all versions of Windows will do. The results of a ping can be piped to a WSH script, which can then interpret the results.

The following script processes the results of a Windows NT ping:


'pingit.vbs
Dim strLine, nCount, objTextStream, strComp, bBad
nCount = 0
'loop until the end of the text stream has been encountered
Do While Not WScript.StdIn.AtEndOfStream
 strLine = Wscript.StdIn.ReadLine
 'check if bad IP address encountered
 If Left(strLine, 14) = "Bad IP address" Then
 bBad = True
 Exit Do
 End If

 If Left(strLine, 10) = "Reply from" Then
 nCount = nCount + 1
 End If
 If Left(strLine, 7) = "Pinging" Then
 strComp = Mid(strLine, 9, Instr(strLine, "]") - 8)
 End If
Loop
'check if bad IP address encountered
If bBad Then
 WScript.Echo "Bad IP address:" & Mid(strLine,15)
Else
 Wscript.Echo nCount & "replies received from "& strComp
End If

To use the script, pipe the results of ping to the script:


ping www.acme.com | cscript pingit.vbs

The script checks each line piped from the ping command. Each successful reply is accumulated.

See Also

The System Scripting Runtime download, documentation, and examples are available from http://www.netal.com/ssr.htm.

11 10 Sending an MSN Messenger Message

Problem

You want to send a message to another Microsoft Network (MSN) Messenger client.

Solution

MSN Messenger operations are exposed through a Messenger COM object. The following file contains Messenger support code that is used throughout this chapter:


Const MSS_NOT_LOGGED_ON = 1
Const MSS_LOGGED_ON =0
Const MSTATE_ONLINE = 2
Const MLIST_CONTACT =0
Const MLIST_ALLOW = 1
Const MLIST_BLOCK = 2
Const MLIST_REVERSE = 3

Const MMSGTYPE_NO_RESULT = 0
Const MMSGTYPE_ERRORS_ONLY =1
Const MMSGTYPE_ALL_RESULTS = 2
Const MSGR_E_FAIL = -2147467259
Const MSGR_S_OK = 0
Dim MsgHeader
MsgHeader = "Mime-Version: 1.0" & vbCrLf & _
 "Content-Type: text/plain; charset=UTF-8" & vbCrLf & vbCrLf
'creates a MSN messenger object and logs in if
'not already connected
'Parameters:
'strUserID User ID to connect
'strPassword password to connect with
'Returns
'Messenger object if successful, Nothing if not
'successful
Function StartMessenger(strUserID, strPassword)
 Dim objMessenger
 Set objMessenger = CreateObject("Messenger.Msgrobject")

 'if user not logged on then log on
 If objMessenger.Services.PrimaryService.Status = MSS_NOT_LOGGED_ON Then
 objMessenger.Logon strUserID, strPassword, _
 objMessenger.Services.PrimaryService

 'wait until successfully logged on
 Do While Not objMessenger.Services.PrimaryService.Status = MSS_LOGGED_ON
 'if primary service is logged off then logon attempt unsuccessful
 If objMessenger.Services.PrimaryService.Status = MSS_NOT_LOGGED_ON Then
 StartMessenger = Nothing
 Exit Function
 End If
 WScript.Sleep 100
 Loop
 End If
 Set StartMessenger = objMessenger
End Function

The following script logs onto an MSN Messenger session and sends a message:





 

Discussion

The MSN Messenger service application is a messaging application that allows for instant communication between clients anywhere in the world.

It uses centralized services to relay messages between clients. MSN Messenger exposes an automation interface that provides access to messaging features through any programming environment that can manipulate COM objects (such as WSH).

An instance of the Messenger client can be created using the Messenger.Msgrobject ProgID. The object returned is either a new instance of the application or a reference to an already running copy of MSN Messenger.

The most recent version of Messenger (version 3.5, as of this writing) supports multiple services. A service provides the transport mechanism for Messenger clients. Currently, this can be through either the publicly accessed MSN Messenger servers or an Exchange 2000 server, which would most likely be accessed within individual organizations.

Installed client services are accessible through the Services property, which is a collection of Service objects.

Each Service object contains details about the service. You can use the Service object's Status property to determine if a client is logged. This property returns a value identifying if Messenger is logged on or not. Table 11-7 lists the values the Status property can return.

Table 11-7: The Service Object's Status Property Values

NAME

VALUE

DESCRIPTION

MSS_LOGGED_ON

0

User logged on

MSS_NOT_LOGGED_ON

1

User not logged on

MSS_LOGGING_ON

2

User in the process of logging on

MSS_LOGGING_OFF

3

User in the process of logging off

Messenger requires a default service to be selected if you are using more than one service (such as Exchange or MSN). This becomes the "primary" or default service, and it can be referenced using the Messenger object's Services property, the PrimaryService property. If you are only using one service, you only need the PrimaryService property.

Messenger must be logged on before it can perform any operations. Use the Messenger object's Logon method to log onto a service. The syntax is as follows:


objMessenger.Logon strUserID, strPassword, objService

strUserID and strPassword identify the user ID and password to log on with. If the user is a MSN Hotmail account, the user ID would be the e-mail address to that account (e.g., freds@hotmail.com).

The objService property is a reference to the service you are logging onto. If you are only using one service, pass the Messenger object's Services property's PrimaryService property. The following code snippet creates an instance of the Messenger object and logs on if user is not currently connected:


Const MSS_NOT_LOGGED_ON = 1
Const MSS_LOGGED_ON = 0
Dim objMessenger
Set objMessenger = CreateObject("Messenger.msgrobject")
'if not logged on then log on
If objMessenger.Services.PrimaryService.Status = MSS_NOT_LOGGED_ON Then
 Set objMessenger = StartMessenger("Freds@hotmail.com", "sderf!@#")
 objMessenger.Logon "freds@hotmail.com ", "wirehead", _
 objMessenger.Services.PrimaryService
 'wait until successfully logged on
 Do While Not objMessenger.Services.PrimaryService.Status = MSS_LOGGED_ON
 WScript.Sleep 100
 Loop
End If

The Messenger object's status is checked because if a copy of Messenger is already running, a user might already be logged on. The logon process is asynchronous, which means the code continues executing after the method is called, even if the authentication process has not finished.

As a result, it is necessary to perform a loop after the Logon method to wait for the authentication process to complete. The loop checks if the Service object's status changes to logged on. No error is returned if the logon authentication fails—you must check the Status property to determine if the operation was successful.

Once you are logged on, you are now ready to perform messaging operations. The main operation you probably want to perform with a messaging application is to send messages (surprise).

To send a message, you first get a reference to the user to whom you want to send a message. You can "create" a reference to a user or use your "buddy" list of existing users to send a message.

You can use the Messenger object's CreateUser method to send a message to a person. The person does not have to be on your buddy list to send a message using the CreateUser method. The syntax is as follows:


objUser = objMessenger.CreateUser(strUserId, objService)

strUserId represents the ID of the user to send the message to. For MSN clients, this is the e-mail address of the user (e.g., freds@hotmail.com).

objService is the client service used to send the message with. This could be MSN or an Exchange 2000 server. If there is only one service being used, use Messenger object's Services property's PrimaryService property to get the default service.

CreateUser returns a User object. The Solution script uses the CreateUser method to reference a user to send a message to. CreateUser does not attempt to add a user to your buddy list if he or she does not already exist.

The Messenger application can create lists of commonly accessed users, known as buddy lists. These lists can be accessed programmatically, allowing messages to be sent to any one of the users defined in your buddy list.

The lists are accessed through the Messenger object's List property. This property returns a collection of User objects for a specific list type. The syntax is as follows:


objUsers = objMessenger.List(nListType)

The nListType argument represents the type of list, which is shown in Table 11-8.

Table 11-8: User List Types

TYPE

VALUE

DESCRIPTION

MLIST_CONTACT

0

All users listed in contact list

MLIST_ALLOW

1

Users who are allowed to send messages to you

MLIST_BLOCK

2

Users who are blocked from sending messages to you

MLIST_REVERSE

3

Users who have added you to their contact list

The User object exposes a number of properties related to the MSN user. The FriendlyName property displays the user's name as it appears in the Messenger application and LogonName returns the user's MSN logon ID. You can determine if the user is online and available by checking the User object's State property. Table 11-9 lists the possible returned values.

Table 11-9: User Object's State Property Values

NAME

VALUE

DESCRIPTION

IM_STATE_UNKNOWN

0

State unknown

IM_STATE_OFFLINE

1

Client not connected to Messenger service

IM_STATE_ONLINE

2

Client is online

IM_STATE_INVISIBLE

6

Client is invisible

IM_STATE_BUSY

10

Client state is set to Busy

IM_STATE_BE_RIGHT_BACK

14

Client state is set to Be Right Back

IM_STATE_IDLE

18

No activity detected for client

IM_STATE_AWAY

34

Client state is set to Away

IM_STATE_ON_THE_PHONE

50

Client state set to On The Phone

IM_STATE_OUT_TO_LUNCH

66

Client state is set to Out To Lunch

IM_STATE_LOCAL_FINDING_SERVER

256

Local client is trying to find a Messenger server

IM_STATE_LOCAL_CONNECTING_TO_SERVER

512

Local client is trying to connect to a server

SYNCHRONIZING_WITH_SERVER

768

Local client is trying to synchronize with the server

DISCONNECTING_FROM_SERVER

1024

Local client is trying to synchronize to disconnect from the server

The following example connects with and logs on to MSN and lists all users that are allowed to send messages to you:





 

To send a message, invoke the User object's SendText method:


nCookie = objUser.SendText(strHeader, strMsg, nAction)

strHeader identifies the format of the message. This can be either text or HTML. Using the HTML format currently doesn't display the text any differently. This value must be passed exactly as either of the following constants:


MsgHeader = "Mime-Version: 1.0" & vbCrLf & "Content-Type: text/plain
MsgHeaderHTML = "Mime-Version: 1.0" & vbCrLf & _
 "Content-Type: text/html; charset=UTF-8" & vbCrLf & vbCrLf

strMsg is the message to send.

nAction controls how and if Messenger fires an event upon completion of the operation. The SendText method doesn't wait for the operation to complete, and an error does not occur if the message is not successfully sent. Instead, Messenger will fire events upon completion of the operation. The nAction argument controls in what condition the events will be fired. Table 11-10 lists the possible values for this argument.

Table 11-10: Send Message Action Types

ACTION

VALUE

DESCRIPTION

MMSGTYPE_NO_RESULT

0

Don't fire any event upon completion.

MMSGTYPE_ERRORS_ONLY

1

Only fire an event if an error occurs when sending a message.

MMSGTYPE_ALL_RESULTS

2

Always fire an event.

The Send method returns an integer "cookie" value. This value is used to uniquely identify the sent message in the current Messenger session. In order to determine if a message was sent successfully, you must sink to the Messenger object's OnSendResult event. You can sink events by creating the object using the Wscript.CreateObject or Wscript.ConnectObject method.

The OnSendResult event is passed two arguments: the result and the cookie for the sent message. If the result is successful, the result argument will contain 0 (MSGR_S_OK), otherwise it's an error and will return the value -2147467259 (MSGR_E_FAIL).

The following code attempts to send a message to a specified user and exits after a send confirmation has occurred or Messenger has exited:





 

Another useful event is the OnTextReceived method, which fires when a message is received from another user. The syntax for the method is as follows:


OnTextReceived(objSess, objUser, strHeader, strMsgText , bPf)

The objSess argument is the Session object that received the event, objUser is a User object for the user who sent the message, strHeader is the message header, strMsgText is the message text, and bPf is a Boolean value that if True indicates that another process has received the message.

The following script lists the message and user who sent it for all messages received:





 

The Messenger object exposes over 40 events. Coverage of all of these events is beyond the scope of this chapter. The easiest way to explore these events is to use an object browser, such as the one included in the MS Office VBA environment. To browse the object model, follow the steps in Solution 11.5 on how to browse the IE DOM object model, substituting the Microsoft HTML model with Messenger Type Library.

MSN Messenger can be configured to send messages to other messaging devices, such as pagers and mobile phones.

To send a message to or page these services, call the Messenger object's SendPage method. The syntax is as follows:


nCookie = objMessenger.SendPage(objUser, strMessage, nType)

objUser is a User object for the user you want to page, strMessage is the message to send, and nType is the type, which currently must be -1. The following script sends a page to a user:





 

The SendPage method returns an integer value that uniquely represents the page within the current Messenger session. Because the SendPage method is used to send messages to services that are outside the control of the MSN Messenger service, there is no way to guarantee that a page operation is successful.

Chapter 12 Messaging Operations



Managing Enterprise Systems with the Windows Script Host
Managing Enterprise Systems with the Windows Script Host
ISBN: 1893115674
EAN: 2147483647
Year: 2005
Pages: 242
Authors: Stein Borge

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net