How Can I Retrieve the Path to the Program Files Folder on a Computer?

How Can I Retrieve the Path to the Program Files Folder on a Computer?

  • Comments 2
  • Likes
Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I retrieve the path to the Program Files folder on a computer?

-- CC

SpacerHey, Scripting Guy! AnswerScript Center

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 = &H80000002

strComputer = "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?

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hi, Scripting guy. Is there a way to do the same thing for Program Files (x86)?

    Thanks,

    --Norexx

  • For the record, the path to "(x86)" is stored under HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion