boka
boka

Reputation: 79

Why does FOLDERID_ProgramFiles return "C:\Program Files (x86)"?

#include <Shlobj.h>
#include <iostream>
#include <string>

std::string fun(REFKNOWNFOLDERID  val) {
    ITEMIDLIST* pIDList;
    if (S_OK == SHGetKnownFolderIDList (val, 0, NULL, & pIDList))
    {
        char cpath[MAX_PATH] = {0};
        if (TRUE == SHGetPathFromIDList(pIDList, cpath))
            return cpath;
    }
    return "failed";
}

int main() {
    std::cout << "--> " << fun(FOLDERID_ProgramFiles) << std::endl;
    std::cout << "--> " << fun(FOLDERID_ProgramFilesX86) << std::endl;
    std::cout << "--> " << fun(FOLDERID_ProgramFilesX64) << std::endl;
}

The output is:

--> C:\Program Files (x86)
--> C:\Program Files (x86)
--> failed

I compile it using cl.exe test.cpp shell32.lib.

I was expecting "C:\Program Files" for FOLDERID_ProgramFiles. My system is x64 based. Why am I getting "Program Files (x86)"?

Upvotes: 1

Views: 764

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 598309

This happens because you are compiling your application as a 32bit executable, even though you are running it on a 64bit system. So FOLDERID_ProgramFiles is mapping to the 32bit Program Files (x86) folder.

This is especially evident by the fact that FOLDERID_ProgramFilesX64 is failing, per the KNOWNFOLDERID documentation:

FOLDERID_ProgramFilesX64

This value is not supported on 32-bit operating systems. It also is not supported for 32-bit applications running on 64-bit operating systems. Attempting to use FOLDERID_ProgramFilesX64 in either situation results in an error. See Remarks for more information.

This is covered in more detail in the documentation's Remarks section:

The interpretation of certain KNOWNFOLDERID values depends on whether the folder is part of a 32-bit or 64-bit application and whether that application is running on a 32-bit or 64-bit operating system. If your application needs to distinguish between, for example, Program Files and Program Files (x86), you must use the right KNOWNFOLDERID for the situation.

The following tables summarize the KNOWNFOLDERID use in those cases.

FOLDERID_ProgramFiles

Operating System Application KNOWNFOLDERID Default Path CSIDL Equivalent
32 bit 32 bit FOLDERID_ProgramFiles %SystemDrive%\Program Files CSIDL_PROGRAM_FILES
32 bit 32 bit FOLDERID_ProgramFilesX86 %SystemDrive%\Program Files CSIDL_PROGRAM_FILESX86
32 bit 32 bit FOLDERID_ProgramFilesX64 (not supported under 32-bit operating systems) Not applicable Not applicable
64 bit 64 bit FOLDERID_ProgramFiles %SystemDrive%\Program Files CSIDL_PROGRAM_FILES
64 bit 64 bit FOLDERID_ProgramFilesX86 %SystemDrive%\Program Files (x86) CSIDL_PROGRAM_FILESX86
64 bit 64 bit FOLDERID_ProgramFilesX64 %SystemDrive%\Program Files None
64 bit 32 bit FOLDERID_ProgramFiles %SystemDrive%\Program Files (x86) CSIDL_PROGRAM_FILES
64 bit 32 bit FOLDERID_ProgramFilesX86 %SystemDrive%\Program Files (x86) CSIDL_PROGRAM_FILESX86
64 bit 32 bit FOLDERID_ProgramFilesX64 (not supported for 32-bit applications) Not applicable Not applicable

This 32bit/64bit issue also affects FOLDERID_ProgramFilesCommon and FOLDERID_System, too.

Upvotes: 3

Related Questions