Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Program Files folder path (not Program Files (x86)) from 32bit WOW process?

I need to get the path to the native (rather than the WOW) program files directory from a 32bit WOW process.

When I pass CSIDL_PROGRAM_FILES (or CSIDL_PROGRAM_FILESX86) into SHGetSpecialFolderPath it returns the WOW (Program Files (x86)) folder path.

I'd prefer to avoid using an environment variable if possible.

I want to compare some values I read from the registry, if the values point to the path of either the WOW or native version of my app then my code does something, if not it does something else. To figure out where the native and WOW versions of my app are expected to be I need to get the paths to "Program Files (x86)" and "Program Files".

like image 919
s d Avatar asked Jan 14 '09 23:01

s d


People also ask

Why does my Program Files say x86?

The Windows separated and created two different directories of the 32-bit program and 64-bit program. The Program Files stores all the 64-bit programs and the Program Files (x86) stores all the 32-bit programs. x86 stands for different processor types, i.e. 286, 386, 486, 586/Pentium.

Does 32-bit have Program Files x86?

The regular Program Files folder holds 64-bit applications, while "Program Files (x86)" is used for 32-bit applications.

Where do I put Program Files or Program Files x86?

On Windows editions that support x86 emulation, there are two directories for program files. The C:\Program Files directory is for programs in the native system bitness, and the the C:\Program Files (x86) directory is for programs that run under the x86-32 emulator.

Can I move Program Files x86 to Program Files?

Much depends on what the data is in the Program Files (x86) folder. If it's a system-related file, then please don't do that as moving it may break Windows. But if some application is installed in Program Files (x86), it is safe to move it.


2 Answers

I appreciate all the help and, especially, the warnings in this thread. However, I really do need this path and this is how I got it in the end:

(error checking removed for clarity, use at your own risk, etc)

WCHAR szNativeProgramFilesFolder[MAX_PATH];
ExpandEnvironmentStrings(L"%ProgramW6432%", 
                       szNativeProgramFilesFolder, 
                       ARRAYSIZE(szNativeProgramFilesFolder);
like image 152
s d Avatar answered Sep 28 '22 04:09

s d


Let me quote Raymond Chen's excellent blogpost on the issue:

On 64-bit Windows, 32-bit programs run in an emulation layer. This emulation layer simulates the x86 architecture, virtualizing the CPU, the file system, the registry, the environment variables, the system information functions, all that stuff. If a 32-bit program tries to look at the system, it will see a 32-bit system. For example, if the program calls the GetSystemInfo function to see what processor is running, it will be told that it's running on a 32-bit processor, with a 32-bit address space, in a world with a 32-bit sky and 32-bit birds in the 32-bit trees.

And that's the point of the emulation: To keep the 32-bit program happy by simulating a 32-bit execution environment.

...

The question is "What is the way of finding the x64 Program Files directory from a 32-bit application?"

The answer is "It is better to work with the system than against it." If you're a 32-bit program, then you're going to be fighting against the emulator each time you try to interact with the outside world. Instead, just recompile your installer as a 64-bit program. Have the 32-bit installer detect that it's running on a 64-bit system and launch the 64-bit installer instead. The 64-bit installer will not run in the 32-bit emulation layer, so when it tries to copy a file or update a registry key, it will see the real 64-bit file system and the real 64-bit registry.

If you still want to do this, I recommend reading the comments on this blogpost as they contain some good hints.

like image 44
Tamas Czinege Avatar answered Sep 28 '22 02:09

Tamas Czinege