Hey, Scripting Guy! How can I retrieve the path to the Program Files folder on a computer?
— CC
Hey, CC. How can you retrieve the path to the Program Files folder on a computer? Well, to be honest, not as easily as we thought you could. If you’re trying to retrieve the Program Files path on the local computer, well, that’s easy; retrieving the Program Files path on a remote machine turned out to be a bit of a sticky wicket. But, we did find a way to do this.
Let’s start by looking at the easy scenario. Here’s a script that uses the Shell object to retrieve the path to the Program Files folder on the local computer:
Const PROGRAM_FILES = &H26&Set objShell = CreateObject(“Shell.Application”) Set objFolder = objShell.Namespace(PROGRAM_FILES) Set objFolderItem = objFolder.Self Wscript.Echo objFolderItem.Path
The script begins by defining a constant named PROGRAM_FILES and setting the value to &H26&; we’ll use this constant to tell the script which “special folder” we want to work with. (Are there other special folders we can work with? You bet there are, and the Script Center Script Repository has a few dozen scripts that show how to do this.) We create an instance of the Shell.Application object, and then use the Namespace method to bind to the Program Files folder (note that we pass the constant PROGRAM_FILES to the Namespace method):
Set objShell = CreateObject(“Shell.Application”) Set objFolder = objShell.Namespace(PROGRAM_FILES)
Now we encounter one of the little idiosyncrasies of the Shell object. Although we have bound ourselves to the Folder object that represents the Program Files folder, we can’t directly retrieve the path to the folder. Instead, we have to create a FolderItemObject for the folder; that’s something we can do using the Self method (which basically just binds the folder to itself):
Set objFolderItem = objFolder.Self
Weird, but once we have a FolderItemObject we can echo back the value of the Path property:
Wscript.Echo objFolderItem.Path
As you might expect, the value of the Path property will be the path to the Program Files folder.
Now that’s great … as long as you’re trying to find the Program Files folder on the local computer. If you’re trying to determine the path to the Program Files folder on a remote computer, however, it’s a different story: that’s because the Shell object won’t run against remote machines. On top of that, we couldn’t find a WMI method or property that we can use to retrieve the path. (We thought for sure there’d be such a property, but ….) And while there is a %programfiles% environment variable, we can’t readily retrieve the value of that environment variable from a remote computer either. In other words, we can’t use the Shell object, we can’t use WMI, and we can’t use the %programfiles% environment variable. Uh-oh.
All we can say about this is, “Thank goodness for the registry.” (We never thought we’d say that, either.) As it turns out, the path to the Program Files folder is stored in the following registry value:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir
That means that we can use WMI to read the registry on a remote computer and return the path:
HKEY_LOCAL_MACHINE = &H80000002strComputer = “atl-ws-01” Set objReg = GetObject(“winmgmts:\\” & strComputer & “\root\default:StdRegProv”)
strKeyPath = “SOFTWARE\Microsoft\Windows\CurrentVersion” ValueName = “ProgramFilesDir”
objReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, ValueName, strValue Wscript.Echo strValue
So what are we doing with this script? Well, we begin by defining a constant named HKEY_LOCAL_MACHINE and setting the value to &H80000002; that tells our script which registry hive to work with. We then use these two lines of code to connect to the WMI service on a remote computer named atl-ws-01:
strComputer = “atl-ws-01” Set objReg = GetObject(“winmgmts:\\” & strComputer & “\root\default:StdRegProv”)
Still with us? Good. Next we assign values to two variables, strKeyPath and ValueName:
strKeyPath = “SOFTWARE\Microsoft\Windows\CurrentVersion” ValueName = “ProgramFilesDir”
It should come as no surprise that strKeyPath represents the path within the HKLM registry hive, while ValueName represents the name of the registry value we want to read (ProgramFilesDir).
Now we’re ready to call the GetStringValue method and read the registry:
objReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, ValueName, strValue
Notice that we pass GetStringValue four parameters: HKEY_LOCAL_MACHINE, strKey, ValueName, and strValue. The first three parameters are a constant and two variables that we defined earlier. But what the heck is strValue?
Well, strValue is an “out parameter.” We don’t specify a value for an out parameter; instead, the method supplies the value. Think of strValue as being a container of sorts; we give GetStringValue the container and GetStringValue then fills that container with the information it reads from the registry. In other words, the answer to our problem – the path to the Program Files folder – will be stored in the out parameter strValue.
Which, in turn, means all we have to do now is echo back that value:
Wscript.Echo strValue
And there you have it. It might not have been the most obvious and intuitive way to get the path to the Program Files folder but, hey, any port in a storm, right?
0 comments