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

前端 未结 6 2392
我寻月下人不归
我寻月下人不归 2021-02-19 05:42

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)

相关标签:
6条回答
  • 2021-02-19 05:55

    You're on the right path - Use the KNOWNFOLDERID of FOLDERID_ProgramFilesX64

    The SHGetKnownFolderPath function can be used to retrieve the full path of a given KnownFolder.

    0 讨论(0)
  • 2021-02-19 06:04

    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.

    0 讨论(0)
  • 2021-02-19 06:07

    The best and universal way to get path to "Program Files", is to query it from the registry:

    64-Bit-Process can query: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir to get "C:\Program Files" HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\ProgramFilesDir to get "C:\Program Files (x86)"

    32-Bit-Process (Wow64) can query: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir to get "C:\Program Files (x86)" HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir with KEY_WOW64_64KEY option! to get "C:\Program Files"

    Pseudo-code:

    OpenKey(hKey, HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", KEY_READ | KEY_WOW64_64KEY);
    QueryStringValue(hKey, L"ProgramFilesDir", sValue);
    
    0 讨论(0)
  • 2021-02-19 06:09

    This is almost certainly a bad idea, according to a recent-ish post by the infamous Raymond Chen. See here for details. Bottom line, I think it can be done, but it's a lot of hard work and there's almost certainly an easier way.

    Microsoft built the WOW emulation layer to make your life easier. Don't waste all their time and effort by fighting it :-).

    Perhaps if you told us why you need the non-WOW Program Files directory, we could assist further.

    0 讨论(0)
  • 2021-02-19 06:11

    I needed it to get the x64 Program Folder from a Logonscript and used:

    Dim oWshShell : Set oWshShell = CreateObject("WScript.Shell")
    Dim sProgramDirPath : sProgramDirPath = 
        oWshShell.ExpandEnvironmentStrings("%ProgramW6432%")
    
    WScript.Echo sProgramDirPath
    
    0 讨论(0)
  • 2021-02-19 06:12

    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);
    
    0 讨论(0)
提交回复
热议问题