04.08.2013 Views

The Windows Scripting Host - dFPUG-Portal

The Windows Scripting Host - dFPUG-Portal

The Windows Scripting Host - dFPUG-Portal

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Print Article<br />

Issue Date: FoxTalk January 1999<br />

<strong>The</strong> <strong>Windows</strong> <strong>Scripting</strong> <strong>Host</strong><br />

John V. Petersen<br />

Remember batch files? <strong>The</strong>y were easy to program and very<br />

productive in that many tasks could be automated. That's what<br />

<strong>Windows</strong> has been missing -- the ability to easily create and use<br />

batch files. This gap has been filled by the <strong>Windows</strong> <strong>Scripting</strong> <strong>Host</strong>,<br />

an engine that allows script code to be run by the OS. Not only is the<br />

<strong>Windows</strong> <strong>Scripting</strong> <strong>Host</strong> a powerful engine for running script code, it<br />

also (surprise!) sports a powerful object model as well. This column<br />

will introduce you to the basics of how the scripting host works and<br />

how you can incorporate its features into your VFP applications.<br />

<strong>The</strong> <strong>Windows</strong> <strong>Scripting</strong> <strong>Host</strong> (WSH) is a language-independent scripting engine. <strong>Scripting</strong> languages such as VBScript and<br />

JScript can be used to drive many processes. <strong>The</strong> same language you use to create client-side scripts in Internet Explorer (IE)<br />

or server-side scripts in Internet Information Server (IIS) can now be hosted by the <strong>Windows</strong> operating system itself.<br />

Prior to the release of the WSH, the only scripting language that existed for <strong>Windows</strong> was MS-DOS batch files. Although<br />

powerful, batch files lack the control over the <strong>Windows</strong> operating system that's really desired. <strong>The</strong> WSH provides this<br />

capability.<br />

What you need to get started<br />

Before I go much further, I should mention that all of the files required to work with the WSH can be downloaded from the<br />

Microsoft Web site at http://msdn.microsoft.com/scripting/. In addition to the core scripting engine, a series of white papers,<br />

code samples, and technical articles can be downloaded as well.<br />

Once you've downloaded the scripting files and run the installer program, you're off to the races!<br />

<strong>Scripting</strong> files<br />

Unlike scripting in Active Server Pages, where the language can be specified with tags embedded in the file itself, the same<br />

isn't true for script files used by the WSH. Rather, the WSH relies on the file extension to determine which language to use. If<br />

the script file ends in VBS, VBScript is used. If the script file ends in JS, JScript is used.<br />

<strong>The</strong> following simple "hello world" example points out the differences between VBScript and JScript:<br />

VBSscript:<br />

'hello world.vbs<br />

Dim WSHShell<br />

Set WSHShell = WScript.CreateObject("WScript.Shell")<br />

WSHShell.Popup "Hello World"<br />

JScript:<br />

// hello world.js<br />

var WSHShell = WScript.CreateObject("WScript.Shell");<br />

WSHShell.Popup("Hello World")<br />

<strong>The</strong> following is a more complex example that uses scripting to open and control Microsoft Excel:<br />

'This VBScript File opens Excel and creates a workbook<br />

Dim objXL,oWorkbook<br />

Set objXL = WScript.CreateObject("Excel.Application")<br />

objXL.Visible = TRUE<br />

Set oWorkbook = objXL.WorkBooks.Add<br />

With objXL<br />

.Cells(1,1) = oWorkbook.Sheets.Count<br />

End With<br />

Seite 1 von 6<br />

Running these script files is a very simple task. In Explorer, you can click the right mouse key over the file, and select Open.<br />

Alternatively, you can double-click the item in Explorer as well. Yet another alternative is to use the Run method of the<br />

<strong>Windows</strong> <strong>Scripting</strong> Shell object. This technique will be illustrated when the Shell Object is discussed in detail.<br />

http://foxtalknewsletter.com/ME2/Audiences/Segments/Publications/Print.asp?Module=...<br />

31.01.06


Print Article<br />

A quick word about debugging and handling errors<br />

No programming environment is complete without a full-featured debugging environment. <strong>The</strong> WSH is no exception, as it also<br />

has a full-featured debugger. As far as error handling is concerned, VBScript doesn't have a global error handler. Rather,<br />

errors need to be handled on an in-line basis. <strong>The</strong> following code demonstrates how to deal with errors on an in-line basis:<br />

On Error Resume Next<br />

dim objxl<br />

Set objXL = WScript.CreateObject("Excel.Application")<br />

objxl.foo ' reference a non-existent Excel Method<br />

If Err.Number > 0 <strong>The</strong>n<br />

Call ErrorProc<br />

End If<br />

Sub ErrorProc<br />

msgbox err.description<br />

End Sub<br />

If no error trapping exists, you'll be prompted with a dialog box asking if you wish to debug the application. Figure 1 illustrates<br />

how the code will appear in the script debugger.<br />

Figure 1. <strong>The</strong> Microsoft Script Debugger uses the same IDE as Visual InterDev and Visual J++ 6.0.<br />

<strong>The</strong> WSH objects<br />

<strong>The</strong>re are two primary objects contained within the WSH. <strong>The</strong> following code illustrates how these objects can be created:<br />

WSHshell = CreateObject("Wscript.Shell")<br />

WSHNetwork = CreateObject("Wscript.Network")<br />

Both the shell and network objects are hosted by the wshom.ocx ActiveX Control.<br />

Complete documentation for the WSHShell and WSHNetwork Objects can be found by navigating to the following URLs:<br />

http://www.microsoft.com/iis/support/iishelp/iis/htm/asp/wsho7t84.htm for the WSHShell object<br />

http://www.microsoft.com/iis/support/iishelp/iis/htm/asp/wsho20qc.htm for the WSHNetwork object<br />

Seite 2 von 6<br />

Shell object properties and methods<br />

Environment<br />

This property provides access to the environment collection. Information such as number of processors, paths, OS, and so<br />

forth can be determined from this collection.<br />

http://foxtalknewsletter.com/ME2/Audiences/Segments/Publications/Print.asp?Module=...<br />

31.01.06


Print Article<br />

oEnv = wshshell.environment<br />

For Each x In oEnv<br />

?oEnv<br />

Next x<br />

<strong>The</strong> following is a partial listing of some typical environmental variables:<br />

NUMBER_OF_PROCESSORS<br />

OS<br />

PROCESSOR_ARCHITECTURE<br />

PROCESSOR_IDENTIFIER<br />

WINDIR<br />

So, to find out the number of processors:<br />

Numprocessors = oEnv.Item("NUMBER_OF_PROCESSORS")<br />

Like most collections, if you want to find out how many members are contained in the collection, you can refer to the Count<br />

property:<br />

Numitems = oEnv.Count<br />

To be compliant with the Java language, collections in the WSH also support the Length property, which provides the same<br />

functionality as the Count property:<br />

Numitems = oEnv.Length<br />

SpecialFolders<br />

This property provides access to the collection of <strong>Windows</strong> Shell folders. <strong>The</strong> following is a listing of folders:<br />

AllUsersDesktop<br />

AllUsersStartMenu<br />

AllUsersPrograms<br />

AllUsersStartup<br />

Desktop<br />

Favorites<br />

Fonts<br />

MyDocuments<br />

NetHood<br />

PrintHood<br />

Programs<br />

Recent<br />

SendTo<br />

StartMenu<br />

Startup<br />

Templates<br />

To find the actual path of the desktop folder, issue this line of code:<br />

DesktopPath = WSHShell.SpecialFolders("Desktop")<br />

CreateShortcut (strPathname)<br />

This method creates and returns a shortcut object. <strong>The</strong> following block of code illustrates how to create a desktop shortcut:<br />

*/ Read desktop path using WshSpecialFolders object<br />

DesktopPath = WSHShell.SpecialFolders("Desktop")<br />

*/ Create a shortcut object on the desktop<br />

MyShortcut = ;<br />

WSHShell.CreateShortcut(DesktopPath + ;<br />

"\Shortcut to MyFile.lnk")<br />

*/ Set shortcut object properties and save it<br />

FileName = GetFile()<br />

If !Empty(FileName)<br />

FileDir = JustPath(FileName)<br />

With MyShortcut<br />

.TargetPath = Filename<br />

.WorkingDirectory = FileDir<br />

.Save<br />

EndWith<br />

Endif<br />

Seite 3 von 6<br />

<strong>The</strong> CreateShortcut method returns a WSHShortcut object. This object is only exposed through the CreateShortcut method.<br />

<strong>The</strong> WSHShortcut object has the following properties:<br />

http://foxtalknewsletter.com/ME2/Audiences/Segments/Publications/Print.asp?Module=...<br />

31.01.06


Print Article<br />

Arguments Parameters to a shortcut object<br />

Description A description of a shortcut object<br />

Hotkey <strong>The</strong> hot key of a shortcut object<br />

IconLocation <strong>The</strong> icon location of a shortcut object<br />

TargetPath <strong>The</strong> target path of a shortcut object<br />

WindowStyle <strong>The</strong> window style of a shortcut object<br />

WorkingDirectory <strong>The</strong> working directory of a shortcut object<br />

<strong>The</strong> WSHShortcut object only has one method -- Save() -- which saves the shortcut object to the file system.<br />

ExpandEnvironmentSettings (strString)<br />

This method expands a process environment variable and returns the result. A typical environment variable is WINDIR. <strong>The</strong><br />

following code illustrates how this method works:<br />

Fullpath = WSHShell.ExpandEnvironmentStrings ;<br />

("%windir%\notepad.exe, 0")<br />

Popup (strText, [natSecondsToWait], [strTitle], [natType])<br />

This method displays the Window MessageBox. Unlike the existing MessageBox function, the Popup method accepts an<br />

optional argument to clear the dialog box after a specified amount of time. <strong>The</strong> following line of code illustrates how the Popup<br />

method works:<br />

WSHShell.Popup("Message",1,"Title",64)<br />

Run(strCommand, [intWindowStyle], [blnWaitOnReturn])<br />

<strong>The</strong> Run method creates a new process that executes a specified command with a specified window style. In addition to being<br />

able to specify the command and the window style, a third parameter can be used to determine whether script execution<br />

should pause until the new process has terminated.<br />

Applications windows can be started in several states. <strong>The</strong> following outlines the various options available:<br />

SW_HIDE 0<br />

SW_MINIMIZE 6<br />

SW_RESTORE 9<br />

SW_SHOW 5<br />

SW_SHOWMAXIMIZED 3<br />

SW_SHOWMINIMIZED 2<br />

SW_SHOWMINNOACTIVE 7<br />

SW_SHOWNA 8<br />

SW_SHOWNOACTIVATE 4<br />

SW_SHOWNORMAL 1<br />

<strong>The</strong> following code starts Notepad with a normal window:<br />

WSHshell.Run("notepad",1)<br />

<strong>The</strong> following code starts Notepad with a maximized window. In addition, the user must close Notepad before control will<br />

return to VFP:<br />

WSHshell.Run("notepad",3,.T.)<br />

Fully qualified paths can be used to denote a file to execute. <strong>The</strong> following code starts Visio:<br />

WSHshell.Run("D:\VISIO\VISIO32.EXE")<br />

Also, script files can be executed with the Run method as well:<br />

WSHshell.Run("hello world.vbs")<br />

WSHshell.Run("hello world.js")<br />

Network object properties and methods<br />

ComputerName<br />

This property denotes the name of the computer:<br />

ComputerName = WSHNetwork.ComputerName<br />

UserDomain<br />

http://foxtalknewsletter.com/ME2/Audiences/Segments/Publications/Print.asp?Module=...<br />

Seite 4 von 6<br />

31.01.06


Print Article<br />

This property denotes the domain to which the user belongs:<br />

DomainName = WSHNetwork.UserDomain<br />

UserName<br />

This property denotes the ID of the currently logged-in user:<br />

UserName = WSHNetwork.UserName<br />

AddPrinterConnection(strLocalName, strRemoteName, [bUpdateProfile], [strUser], [strPassword] )<br />

This method maps a network printer to a local resource.<br />

WSHNetwork.AddPrinterConnection("LPT1","\\server\ ;<br />

printer_share",.T.,"UserID","Password")<br />

Of special interest here is the third parameter -- bUpdateProfile. If this parameter is set to .T., the user profile for the local<br />

machine is updated to restore the printer mapping the next time the user logs onto the machine and network.<br />

EnumNetworkDrives<br />

This method returns a collection of drive mappings. <strong>The</strong> following code loops through the collection of network drive<br />

mappings:<br />

oDrives = WSHNetwork.EnumDriveMappings<br />

item = -1<br />

For Each x In oDrives<br />

item = item + 1<br />

If Mod(item,2) = 0<br />

?"Drive Letter: ",x<br />

Else<br />

?"Network Resource: ",x<br />

Endif<br />

Next x<br />

Like other collections, the drive mapping collection supports both the Count and Length properties as well as the Item()<br />

method.<br />

EnumPrinterConnections<br />

This method works just like the EnumNetworkDrives, with the difference being that the collection returned represents printers,<br />

not drive mappings:<br />

item = -1<br />

For Each x In oPrinters<br />

item = item + 1<br />

If Mod(item,2) = 0<br />

?"Printer Name: ",x<br />

Else<br />

?"Network Resource: ",x<br />

Endif<br />

Next x<br />

MapNetworkDrive(strLocalName, strRemoteName, [bUpdateProfile], [strUser], [strPassword] )<br />

This method works just like the AddPrinterConnection Method, with the exception that a local drive to a network resource is<br />

created:<br />

WSHNetwork.MapNetworkDrive("z:","\\server\ ;<br />

server_share",.T.,"User","Password")<br />

RemoveNetworkDrive(strName, [bForce], [bUpdateProfile] )<br />

This method removes a specified network drive mapping. Optionally, you can force the removal even if the resource is being<br />

used. An optional third parameter specifies whether the user profile should be updated:<br />

WSHNetwork.RemoveNetworkDrive("z:",.T.,.T.)<br />

or<br />

WSHNetwork.RemoveNetworkDrive("\\server\ ;<br />

server_share",.T.,.T.)<br />

RemovePrinterConnection(strName, [bForce], [bUpdateProfile] )<br />

This method works just like the RemoveNetworkDrive method, with the exception that a printer resource is being removed:<br />

WSHNetwork.RemovePrinerConnection("LPT1",.T.,.T.)<br />

http://foxtalknewsletter.com/ME2/Audiences/Segments/Publications/Print.asp?Module=...<br />

Seite 5 von 6<br />

31.01.06


Print Article<br />

or<br />

WSHNetwork.RemovePrinterConnection("\\server\ ;<br />

printer_share",.T.,.T.)<br />

SetDefaultPrinter(strName)<br />

This method sets the default printer:<br />

WSHNetwork.SetDefaultPrinter("\\server\printer_share")<br />

Conclusion<br />

<strong>The</strong> ability to work with the <strong>Windows</strong> Registry, create desktop shortcuts, and map and view network resources all required you<br />

to know how to use extensive <strong>Windows</strong> API functions, or a third-party DLL. <strong>The</strong> WSH provides a simple and elegant set of<br />

objects with simple interfaces that allow you to accomplish many tasks. Perhaps your application requires special Registry<br />

entries. Perhaps you've been tasked with developing a utility that modifies the default printer or dynamically maps network<br />

resources. All of these tasks can easily be accomplished with the WSH.<br />

<strong>The</strong> good news is that the WSH will be a standard part of the operating system beginning with <strong>Windows</strong> 2000. Until the<br />

release of <strong>Windows</strong> 2000, you'll need to make sure the WSH is installed on any client workstation that uses your application.<br />

One approach to this problem is to add a method to your application class that tests to see whether the WSH is installed. If it<br />

isn't, prompt the user through the process of both downloading and installing the WSH.<br />

<strong>The</strong> <strong>Windows</strong> <strong>Scripting</strong> <strong>Host</strong> -- yet another valuable tool to add to your toolbox!<br />

Sidebar: VFP Bug Alert!<br />

While the documentation states that the second argument in the Popup method specifies a timeout interval in which the<br />

MessageBox will be cleared, it doesn't work in VFP. I tested this code in Visual Basic, and the expected behavior occurred.<br />

This behavior has been reported to the VFP team and hopefully will be fixed in the next release.<br />

<strong>The</strong> WSH Shell object provides three methods for working with the <strong>Windows</strong> Registry:<br />

RegWrite(strName, anyValue, [strType] )<br />

RegDelete(strName)<br />

RegRead(strName)<br />

With these methods, entries can be created, written, read, and deleted. If you attempt to write to a key that doesn't exist, the<br />

key will be created. <strong>The</strong> code in Listing 1 illustrates how these three methods work (click on the Listing link for the<br />

code).<br />

http://foxtalknewsletter.com/ME2/Audiences/Segments/Publications/Print.asp?Module=...<br />

Seite 6 von 6<br />

31.01.06

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!