Working with Windows Scripting Host (WSH) from Python

Credit: Kevin Altis

Problem

You need to use the Windows Scripting Host (WSH) to perform the same tasks as in the classic WSH examples, but you must do so by driving the WSH from within a normal Python script.

Solution

Python’s abilities on Windows are greatly enhanced by win32all’s ability to access COM automation servers, such as the WSH. First, we connect to the Windows shell’s COM automation interface:

import sys, win32com.client
shell = win32com.client.Dispatch("WScript.Shell")

Then, we launch Notepad to edit this script in the simplest way (basically, with the same functionality as os.system). This script’s name is, of course, sys.argv[0], since we’re driving from Python:

shell.Run("notepad " + sys.argv[0])

For a .pys script driven from WSH, it would be WScript.ScriptFullName instead. shell.Run has greater functionality than the more portable os.system. To show it off, we can set the window type, wait until Notepad is shut down by the user, and get the code returned from Notepad when it is shut down before proceeding:

ret = shell.Run("notepad " + sys.argv[0], 1, 1)
print "Notepad return code:", ret

Now, we open a command window, change the path to C:\, and execute a dir:

shell.Run("cmd /K CD C:\ & Dir")

Note that cmd works only on Windows NT/2000/XP; on Windows 98/ME, you need to run Command instead, and this does not support the & joiner to execute two consecutive commands. The shell object has many more methods besides the Run method used throughout this recipe. For example, we can get any environment string (similar to accessing os.environ):

print shell.ExpandEnvironmentStrings("%windir%")

Discussion

This recipe shows three Windows Scripting Host (WSH) examples converted to Python. WSH documentation can be found at http://msdn.microsoft.com/library/en-us/script56/html/wsoriWindowsScriptHost.asp.

Note that this recipe shows a Python program driving WSH, so save the code to a file with extension .py rather than .pys. Extension .pys would be used if WSH was driving (i.e., via cscript.exe)—and, thus, if Python was being used via the ActiveScripting protocol. But the point of the recipe is that you don’t need to rely on ActiveScripting: you can use WSH system-specific functionality, such as SendKeys and ExpandEnvironmentStrings, from within a regular Python program, further enhancing the use of Python for system administration and automating tasks in a Windows environment.

Note that you do not need to worry about closing the COM objects you create. Python’s garbage collection takes care of them quite transparently. For example, if and when you want to explicitly close (release) a COM object, you can use a del statement (in this case, you need to ensure that you remove or rebind all references to the COM object that you want to release).

See Also

Documentation for pythoncom and win32com.client in win32all (http://starship.python.net/crew/mhammond/win32/Downloads.html) or ActivePython (http://www.activestate.com/ActivePython/); Windows API documentation available from Microsoft (http://msdn.microsoft.com); Python Programming on Win32, by Mark Hammond and Andy Robinson (O’Reilly).

Get Python Cookbook now with the O’Reilly learning platform.

O’Reilly members experience live online training, plus books, videos, and digital content from nearly 200 publishers.