views:

380

answers:

3

I'm struggling with a problem of how to determine the location of 64-bit Program Files directory on 64-bit Windows Vista from a 32-bit application.

Calls to SHGetKnownFolderPath( FOLDERID_ProgramFilesX64 ) do not return anything. MSDN website also states that this particular call with FOLDERID_ProgramFilesX64 is not supported for 32-bit apps. (http://msdn.microsoft.com/en-us/library/bb762584%28VS.85%29.aspx)

I would like to avoid as much as possible hardcoding the path to "C:\Program Files". Doing something like GetWindowsDirectory(), extracting drive from the return value and adding "\Program Files" to it is not appealing either.

Can anyone provide clues to how 32-bit app can properly get the location of the folder from 64-bit Vista?

+1  A: 

If you read that page carefully you will see that FOLDERID_ProgramFilesX64 is supported for 32 bits apps on a 64 bit OS. It's NOT supported on a 32 bit OS, which makes complete sense.

Have you actually tried it and seen it fail?

Jeff Paquette
The official part of the page states that it works on 64-bit OS.However at the bottom of the page there is a comment (which I assume is there because Microsoft did not reject it), saying that for 32-bit caller the method succeeds however does not return anything.And yes, I tried it from 32-bit caller and no path is returned (error code 0x80070002).The environment variable %ProgramW6432% does not get expanded either from 32-bit app.
Karen Gabrielyan
+2  A: 

As you mentioned, using SHGetKnownFolderPath from a 32-bit application will not work on a 64-bit operating system. This is because Wow64 emulation is in effect.

You can however use RegOpenKeyEx passing in the flag KEY_WOW64_64KEY and then read the program files directory from registry.

The location in registry:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion

You are interested in the string value:

ProgramFilesDir

Brian R. Bondy
Thanks for your answer Brian, this worked. Appreciate your help
Karen Gabrielyan
A: 

FOLDERID_ProgramFilesX64 is supported...

MSDN says it is supported, but Microsoft's "WOW64" best practices document says it is not. See http://download.microsoft.com/download/A/F/7/AF7777E5-7DCD-4800-8A0A-B18336565F5B/wow64_bestprac.docx

To quote:

• Some variables work only if the process is 64-bit. For example, FOLDERID_ProgramFilesX64 does not work for 32-bit callers. In versions of Windows earlier than Windows 7, %ProgramW6432% did not work in the context of 32-bit processes. An application must determine whether it is running in a 64-bit process before it uses these variables.

Under Windows 7 x64, running a 32-bit app in the Visual Studio debugger, I also get a return code of 0x80070002 (and a NULL pointer). Running the same code compiled as 64-bit returns the value S_OK and the path is properly filled in.

I've used the registry hack as listed above since I can't find any other workaround.

Gimble

related questions