The Windows Scripting Host John V. Petersen

Print Article Seite 1 von 6 Issue Date: FoxTalk January 1999 The Windows Scripting Host John V. Petersen Remember batch files? They were easy to p...
6 downloads 4 Views 29KB Size
Print Article

Seite 1 von 6

Issue Date: FoxTalk January 1999

The Windows Scripting Host John V. Petersen

Remember batch files? They were easy to program and very productive in that many tasks could be automated. That's what Windows has been missing -- the ability to easily create and use batch files. This gap has been filled by the Windows Scripting Host, an engine that allows script code to be run by the OS. Not only is the Windows Scripting Host a powerful engine for running script code, it also (surprise!) sports a powerful object model as well. This column will introduce you to the basics of how the scripting host works and how you can incorporate its features into your VFP applications. The Windows Scripting Host (WSH) is a language-independent scripting engine. Scripting languages such as VBScript and JScript can be used to drive many processes. The same language you use to create client-side scripts in Internet Explorer (IE) or server-side scripts in Internet Information Server (IIS) can now be hosted by the Windows operating system itself. Prior to the release of the WSH, the only scripting language that existed for Windows was MS-DOS batch files. Although powerful, batch files lack the control over the Windows operating system that's really desired. The WSH provides this capability. What you need to get started Before I go much further, I should mention that all of the files required to work with the WSH can be downloaded from the Microsoft Web site at http://msdn.microsoft.com/scripting/. In addition to the core scripting engine, a series of white papers, code samples, and technical articles can be downloaded as well. Once you've downloaded the scripting files and run the installer program, you're off to the races! Scripting files Unlike scripting in Active Server Pages, where the language can be specified with tags embedded in the file itself, the same 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 the script file ends in VBS, VBScript is used. If the script file ends in JS, JScript is used. The following simple "hello world" example points out the differences between VBScript and JScript: VBSscript: 'hello world.vbs Dim WSHShell Set WSHShell = WScript.CreateObject("WScript.Shell") WSHShell.Popup "Hello World" JScript: // hello world.js var WSHShell = WScript.CreateObject("WScript.Shell"); WSHShell.Popup("Hello World") The following is a more complex example that uses scripting to open and control Microsoft Excel: 'This VBScript File opens Excel and creates a workbook Dim objXL,oWorkbook Set objXL = WScript.CreateObject("Excel.Application") objXL.Visible = TRUE Set oWorkbook = objXL.WorkBooks.Add With objXL .Cells(1,1) = oWorkbook.Sheets.Count End With Running these script files is a very simple task. In Explorer, you can click the right mouse key over the file, and select Open. Alternatively, you can double-click the item in Explorer as well. Yet another alternative is to use the Run method of the Windows Scripting Shell object. This technique will be illustrated when the Shell Object is discussed in detail.

http://foxtalknewsletter.com/ME2/Audiences/Segments/Publications/Print.asp?Module=... 31.01.06

Print Article

Seite 2 von 6

A quick word about debugging and handling errors No programming environment is complete without a full-featured debugging environment. The WSH is no exception, as it also has a full-featured debugger. As far as error handling is concerned, VBScript doesn't have a global error handler. Rather, errors need to be handled on an in-line basis. The following code demonstrates how to deal with errors on an in-line basis: On Error Resume Next dim objxl Set objXL = WScript.CreateObject("Excel.Application") objxl.foo ' reference a non-existent Excel Method If Err.Number > 0 Then Call ErrorProc End If Sub ErrorProc msgbox err.description End Sub If no error trapping exists, you'll be prompted with a dialog box asking if you wish to debug the application. Figure 1 illustrates how the code will appear in the script debugger. Figure 1. The Microsoft Script Debugger uses the same IDE as Visual InterDev and Visual J++ 6.0.

The WSH objects There are two primary objects contained within the WSH. The following code illustrates how these objects can be created: WSHshell = CreateObject("Wscript.Shell") WSHNetwork = CreateObject("Wscript.Network") Both the shell and network objects are hosted by the wshom.ocx ActiveX Control. Complete documentation for the WSHShell and WSHNetwork Objects can be found by navigating to the following URLs:

n http://www.microsoft.com/iis/support/iishelp/iis/htm/asp/wsho7t84.htm for the WSHShell object n http://www.microsoft.com/iis/support/iishelp/iis/htm/asp/wsho20qc.htm for the WSHNetwork object

Shell object properties and methods Environment This property provides access to the environment collection. Information such as number of processors, paths, OS, and so forth can be determined from this collection.

http://foxtalknewsletter.com/ME2/Audiences/Segments/Publications/Print.asp?Module=... 31.01.06

Print Article

Seite 3 von 6

oEnv = wshshell.environment For Each x In oEnv ?oEnv Next x The following is a partial listing of some typical environmental variables: NUMBER_OF_PROCESSORS OS PROCESSOR_ARCHITECTURE PROCESSOR_IDENTIFIER WINDIR So, to find out the number of processors: Numprocessors = oEnv.Item("NUMBER_OF_PROCESSORS") Like most collections, if you want to find out how many members are contained in the collection, you can refer to the Count property: Numitems = oEnv.Count To be compliant with the Java language, collections in the WSH also support the Length property, which provides the same functionality as the Count property: Numitems = oEnv.Length SpecialFolders This property provides access to the collection of Windows Shell folders. The following is a listing of folders: AllUsersDesktop AllUsersStartMenu AllUsersPrograms AllUsersStartup Desktop Favorites Fonts MyDocuments NetHood PrintHood Programs Recent SendTo StartMenu Startup Templates To find the actual path of the desktop folder, issue this line of code: DesktopPath = WSHShell.SpecialFolders("Desktop") CreateShortcut (strPathname) This method creates and returns a shortcut object. The following block of code illustrates how to create a desktop shortcut: */ Read desktop path using WshSpecialFolders object DesktopPath = WSHShell.SpecialFolders("Desktop") */ Create a shortcut object on the desktop MyShortcut = ; WSHShell.CreateShortcut(DesktopPath + ; "\Shortcut to MyFile.lnk") */ Set shortcut object properties and save it FileName = GetFile() If !Empty(FileName) FileDir = JustPath(FileName) With MyShortcut .TargetPath = Filename .WorkingDirectory = FileDir .Save EndWith Endif The CreateShortcut method returns a WSHShortcut object. This object is only exposed through the CreateShortcut method. The WSHShortcut object has the following properties:

http://foxtalknewsletter.com/ME2/Audiences/Segments/Publications/Print.asp?Module=... 31.01.06

Print Article

Seite 4 von 6

Arguments

Parameters to a shortcut object

Description

A description of a shortcut object

Hotkey

The hot key of a shortcut object

IconLocation

The icon location of a shortcut object

TargetPath

The target path of a shortcut object

WindowStyle

The window style of a shortcut object

WorkingDirectory

The working directory of a shortcut object

The WSHShortcut object only has one method -- Save() -- which saves the shortcut object to the file system. ExpandEnvironmentSettings (strString) This method expands a process environment variable and returns the result. A typical environment variable is WINDIR. The following code illustrates how this method works: Fullpath = WSHShell.ExpandEnvironmentStrings ; ("%windir%\notepad.exe, 0") Popup (strText, [natSecondsToWait], [strTitle], [natType]) This method displays the Window MessageBox. Unlike the existing MessageBox function, the Popup method accepts an optional argument to clear the dialog box after a specified amount of time. The following line of code illustrates how the Popup method works: WSHShell.Popup("Message",1,"Title",64) Run(strCommand, [intWindowStyle], [blnWaitOnReturn]) The Run method creates a new process that executes a specified command with a specified window style. In addition to being able to specify the command and the window style, a third parameter can be used to determine whether script execution should pause until the new process has terminated. Applications windows can be started in several states. The following outlines the various options available: SW_HIDE SW_MINIMIZE SW_RESTORE SW_SHOW SW_SHOWMAXIMIZED SW_SHOWMINIMIZED SW_SHOWMINNOACTIVE SW_SHOWNA SW_SHOWNOACTIVATE SW_SHOWNORMAL

0 6 9 5 3 2 7 8 4 1

The following code starts Notepad with a normal window: WSHshell.Run("notepad",1) The following code starts Notepad with a maximized window. In addition, the user must close Notepad before control will return to VFP: WSHshell.Run("notepad",3,.T.) Fully qualified paths can be used to denote a file to execute. The following code starts Visio: WSHshell.Run("D:\VISIO\VISIO32.EXE") Also, script files can be executed with the Run method as well: WSHshell.Run("hello world.vbs") WSHshell.Run("hello world.js") Network object properties and methods ComputerName This property denotes the name of the computer: ComputerName = WSHNetwork.ComputerName UserDomain

http://foxtalknewsletter.com/ME2/Audiences/Segments/Publications/Print.asp?Module=... 31.01.06

Print Article

Seite 5 von 6

This property denotes the domain to which the user belongs: DomainName = WSHNetwork.UserDomain UserName This property denotes the ID of the currently logged-in user: UserName = WSHNetwork.UserName AddPrinterConnection(strLocalName, strRemoteName, [bUpdateProfile], [strUser], [strPassword] ) This method maps a network printer to a local resource. WSHNetwork.AddPrinterConnection("LPT1","\\server\ ; printer_share",.T.,"UserID","Password") Of special interest here is the third parameter -- bUpdateProfile. If this parameter is set to .T., the user profile for the local machine is updated to restore the printer mapping the next time the user logs onto the machine and network. EnumNetworkDrives This method returns a collection of drive mappings. The following code loops through the collection of network drive mappings: oDrives = WSHNetwork.EnumDriveMappings item = -1 For Each x In oDrives item = item + 1 If Mod(item,2) = 0 ?"Drive Letter: ",x Else ?"Network Resource: ",x Endif Next x Like other collections, the drive mapping collection supports both the Count and Length properties as well as the Item() method. EnumPrinterConnections This method works just like the EnumNetworkDrives, with the difference being that the collection returned represents printers, not drive mappings: item = -1 For Each x In oPrinters item = item + 1 If Mod(item,2) = 0 ?"Printer Name: ",x Else ?"Network Resource: ",x Endif Next x MapNetworkDrive(strLocalName, strRemoteName, [bUpdateProfile], [strUser], [strPassword] ) This method works just like the AddPrinterConnection Method, with the exception that a local drive to a network resource is created: WSHNetwork.MapNetworkDrive("z:","\\server\ ; server_share",.T.,"User","Password") RemoveNetworkDrive(strName, [bForce], [bUpdateProfile] ) This method removes a specified network drive mapping. Optionally, you can force the removal even if the resource is being used. An optional third parameter specifies whether the user profile should be updated: WSHNetwork.RemoveNetworkDrive("z:",.T.,.T.) or WSHNetwork.RemoveNetworkDrive("\\server\ ; server_share",.T.,.T.) RemovePrinterConnection(strName, [bForce], [bUpdateProfile] ) This method works just like the RemoveNetworkDrive method, with the exception that a printer resource is being removed: WSHNetwork.RemovePrinerConnection("LPT1",.T.,.T.)

http://foxtalknewsletter.com/ME2/Audiences/Segments/Publications/Print.asp?Module=... 31.01.06

Print Article

Seite 6 von 6

or WSHNetwork.RemovePrinterConnection("\\server\ ; printer_share",.T.,.T.) SetDefaultPrinter(strName) This method sets the default printer: WSHNetwork.SetDefaultPrinter("\\server\printer_share") Conclusion The ability to work with the Windows Registry, create desktop shortcuts, and map and view network resources all required you to know how to use extensive Windows API functions, or a third-party DLL. The WSH provides a simple and elegant set of objects with simple interfaces that allow you to accomplish many tasks. Perhaps your application requires special Registry entries. Perhaps you've been tasked with developing a utility that modifies the default printer or dynamically maps network resources. All of these tasks can easily be accomplished with the WSH. The good news is that the WSH will be a standard part of the operating system beginning with Windows 2000. Until the release of Windows 2000, you'll need to make sure the WSH is installed on any client workstation that uses your application. 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 isn't, prompt the user through the process of both downloading and installing the WSH. The Windows Scripting Host -- yet another valuable tool to add to your toolbox!

Sidebar: VFP Bug Alert! While the documentation states that the second argument in the Popup method specifies a timeout interval in which the MessageBox will be cleared, it doesn't work in VFP. I tested this code in Visual Basic, and the expected behavior occurred. This behavior has been reported to the VFP team and hopefully will be fixed in the next release. The WSH Shell object provides three methods for working with the Windows Registry:

n RegWrite(strName, anyValue, [strType] ) n RegDelete(strName) n RegRead(strName)

With these methods, entries can be created, written, read, and deleted. If you attempt to write to a key that doesn't exist, the key will be created. The code in code).

Listing 1 illustrates how these three methods work (click on the Listing link for the

http://foxtalknewsletter.com/ME2/Audiences/Segments/Publications/Print.asp?Module=... 31.01.06