What is the source of the data for the ProgramFiles, ProgramW6432Dir, ProgramFilesDir (x86), CommonProgramFiles environment variables?

On a 64-bit Windows system, the reading of the various environment variables and some Windows Registry keys is redirected to different sources, depending whether the process doing the reading is 64-bit or 32-bit.

The table below lists these data sources:

X = HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion
Y = HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion
Z = HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
     
READING ENVIRONMENT VARIABLES:    Source for 64-bit process               Source for 32-bit process
-------------------------------|----------------------------------------|--------------------------------------------------------------
                %ProgramFiles% :  X\ProgramW6432Dir                       X\ProgramFilesDir (x86)
           %ProgramFiles(x86)% :  X\ProgramFilesDir (x86)                 X\ProgramFilesDir (x86)
                %ProgramW6432% :  X\ProgramW6432Dir                       X\ProgramW6432Dir
     
          %CommonProgramFiles% :  X\CommonW6432Dir                        X\CommonFilesDir (x86)
     %CommonProgramFiles(x86)% :  X\CommonFilesDir (x86)                  X\CommonFilesDir (x86)
          %CommonProgramW6432% :  X\CommonW6432Dir                        X\CommonW6432Dir
     
                 %ProgramData% :  Z\ProgramData                           Z\ProgramData


      READING REGISTRY VALUES:    Source for 64-bit process               Source for 32-bit process
-------------------------------|----------------------------------------|--------------------------------------------------------------
             X\ProgramFilesDir :  X\ProgramFilesDir                       Y\ProgramFilesDir
       X\ProgramFilesDir (x86) :  X\ProgramFilesDir (x86)                 Y\ProgramFilesDir (x86)
            X\ProgramFilesPath :  X\ProgramFilesPath = %ProgramFiles%     Y\ProgramFilesPath = %ProgramFiles(x86)%
             X\ProgramW6432Dir :  X\ProgramW6432Dir                       Y\ProgramW6432Dir
     
              X\CommonFilesDir :  X\CommonFilesDir                        Y\CommonFilesDir
        X\CommonFilesDir (x86) :  X\CommonFilesDir (x86)                  Y\CommonFilesDir (x86)
              X\CommonW6432Dir :  X\CommonW6432Dir                        Y\CommonW6432Dir
     

So for example, for a 32-bit process, the source of the data for the %ProgramFiles% and %ProgramFiles(x86)% environment variables is the Registry value HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir (x86).

However, for a 64-bit process, the source of the data for the %ProgramFiles% environment variable is the Registry value HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramW6432Dir …and the source of the data for the %ProgramFiles(x86)% environment variable is the Registry value HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir (x86)

Most default Windows installations put a string like C:\Program Files (x86) into the Registry value HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir (x86) but this can be changed (and the others, too).

Below is the typical data in these environment variables and Registry values:

 READING ENVIRONMENT VARIABLES:   Typical data for 64-bit process         Typical data for 32-bit process
-------------------------------|----------------------------------------|-----------------------------------------------                                                                        
                %ProgramFiles% = C:\Program Files                        C:\Program Files (x86)
           %ProgramFiles(x86)% = C:\Program Files (x86)                  C:\Program Files (x86) 
                %ProgramW6432% = C:\Program Files                        C:\Program Files

          %CommonProgramFiles% = C:\Program Files\Common Files           C:\Program Files (x86)\Common Files
     %CommonProgramFiles(x86)% = C:\Program Files (x86)\Common Files     C:\Program Files (x86)\Common Files
          %CommonProgramW6432% = C:\Program Files\Common Files           C:\Program Files\Common Files

                 %ProgramData% = C:\ProgramData                          C:\ProgramData
 
 
       READING REGISTRY VALUES:  Typical data for 64-bit process         Typical data for 32-bit process
 ------------------------------|----------------------------------------|-----------------------------------------------
             X\ProgramFilesDir = C:\Program Files                        C:\Program Files (x86)
       X\ProgramFilesDir (x86) = C:\Program Files (x86)                  C:\Program Files (x86)
            X\ProgramFilesPath = %ProgramFiles% => C:\Program Files      %ProgramFiles(x86)% => C:\Program Files (x86)
             X\ProgramW6432Dir = C:\Program Files                        C:\Program Files

              X\CommonFilesDir = C:\Program Files\Common Files           C:\Program Files (x86)\Common Files
        X\CommonFilesDir (x86) = C:\Program Files (x86)\Common Files     C:\Program Files (x86)\Common Files
              X\CommonW6432Dir = C:\Program Files\Common Files           C:\Program Files\Common Files
 
 X = HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion

Ultimately, whatever is entered into these Windows Registry values will be read by Windows Explorer into respective Environment Variables upon login and then copied to any child process that it subsequently spawns. The child process can change its own environment variables using _putenv()

The registry value HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesPath is especially noteworthy because most Windows installations put the string %ProgramFiles% into it, to be read by 64-bit processes. This string refers to the environment variable %ProgramFiles% which in turn, takes its data from the Registry value HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramW6432Dir …unless some program changes the value of this environment variable apriori.

I have written a small utility, which displays these environment variables for 64-bit and 32-bit processes. You can download it here.
The source code for VisualStudio 2017 is included and the compiled 64-bit and 32-bit binary executables are in the directories ..\x64\Release and ..\x86\Release, respectively.

Leave a Comment