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.
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.
METHOD |
DESCRIPTION |
---|---|
Stop |
Stops the current IE operation |
Quit |
Exits IE |
Table 11-4 lists a few of the properties that IE exposes.
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.
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.
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:
- Start an Office application, such as Word or Excel.
- Choose Tools > Macro > Visual Basic Editor.
- Select Tools > References. From the list of available objects, find the Microsoft HTML Object Library and click the check box.
- Click OK.
- At any time within the Visual Basic Editor, press the F2 key. This will display the object browser.
- 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.
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.
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.
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.
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.
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.
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.
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
Категории