10

From a command prompt, I get the following:

>echo %ProgramFiles%
C:\Program Files

However, some applications (PHP in this instance, though I've seen the same behavior from within Apache's httpd.conf), it is:

>php -r "echo $_ENV['ProgramFiles'];"
C:\Program Files (x86)

Why is this?

Background: I'm developing scripts that are agnostic of the host OS being 32bit or 64bit, and for configuration files this works great. On a 32bit system, %ProgramFiles% is "C:\Program Files", and on a 64bit system that same %ProgramFiles% seemingly returns C:\Program Files (x86). I'm just curious why the same doesn't hold true when I try it from the Windows command prompt (or in the explorer bar, etc.). Is there a 64bit command prompt or something?

ken
  • 201
  • 1
  • 2
  • 6
  • In both environments, `%programfiles%` returns `C:\Program Files` (on a default config of Windows). On x64 versions of Windows, `%programfiles(x86)` returns `C:\Program Files (x86)`. Not sure why php is returning something contrary to that, but you can easily verify what the environmental variables for a given system are set to by running `set` from a command prompt on x64 Windows and x86 Windows. – MDMarra Aug 01 '12 at 15:13

1 Answers1

14

When a 32-bit application launched in a 64-bit Windows addresses the system environment variables %ProgramFiles% or %commonprogramfiles%, the WoW64 subsystem replaces the values of these variables with the values of the variables %ProgramFiles(x86)% and "%commonprogramfiles(x86)%. Thus, for instance, %ProgramFiles% will be opened as "C:\Program Files (x86)" when addressing from a 32-bit program.

This behavior is determined by the register redirection system that provides backward compatibility of 32-bit software with 64-bit operating systems. The 32-bit environment is emulated for 32-bit programs even despite the fact that the data they are addressing is located in a different place.

To avoid such a redirection in a 32-bit program, you should use the %programfiles% or %COMMONPROGRAMFILES% (i.e. with reverse case) environment variables or the KEY_WOW64_64KEY flag when accessing the corresponding register nodes.

justin0
  • 561
  • 3
  • 7
  • Actually, instead of avoiding the redirection, I'm trying to enact it from a Windows prompt; for instance, I'd like to be able to script `%ProgramFiles%` and have it use `C:\Program Files` on 32bit and yet use `C:\Program Files (x86)` on 64bit. This is the way in which both Apache and PHP work, and while I can't comment on whether this is "correct", it is a nifty behavior. For example, I can set `ServerRoot "${ProgramFiles}\Zend\Apache2"` in httpd.conf, and it will correctly find the Zend/Apache install (which is in the x86 folder on 64bit) regardless of the Windows version. – ken Aug 01 '12 at 15:31
  • 4
    On my machine, in a 32-bit command shell, `echo %programfiles%` still returns the 32-bit path. There is, however, a variable named ProgramW6432 which points to the 64-bit path. – Harry Johnston Aug 02 '12 at 01:52
  • This does not work for me. All these variables return the same path: `var environmentVariables = new string[] { "%programfiles%", "%programfiles(x86)%", "%ProgramFiles%", "%commonprogramfiles%", "%COMMONPROGRAMFILES%" };` – Saeed Neamati Nov 29 '15 at 08:26
  • 2
    Documentation: https://msdn.microsoft.com/en-us/library/windows/desktop/aa384274(v=vs.85).aspx – C.O. Feb 25 '18 at 00:10