Разница% ProgramFiles% на 64-битной Windows

8

Из командной строки я получаю следующее:

>echo %ProgramFiles%
C:\Program Files

Однако в некоторых приложениях (в данном случае PHP, хотя я видел такое же поведение в httpd.conf Apache), это:

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

Почему это?

Справочная информация: я разрабатываю сценарии, которые не зависят от операционной системы хоста 32-битной или 64-битной, и для файлов конфигурации это прекрасно работает. В 32-битной системе %ProgramFiles%это «C: \ Program Files», а в 64-битной системе это, по- %ProgramFiles%видимому, возвращается C:\Program Files (x86). Мне просто любопытно, почему то же самое не выполняется, когда я пытаюсь сделать это из командной строки Windows (или в панели обозревателя и т. Д.). Есть 64-битная командная строка или что-то?

кругозор
источник
В обеих средах %programfiles%возвращает C:\Program Files(в конфигурации Windows по умолчанию). В 64-разрядных версиях Windows %programfiles(x86)возвращается C:\Program Files (x86). Не уверен, почему php возвращает что-то, противоречащее этому, но вы можете легко проверить, какие переменные среды для данной системы установлены, запустив их setиз командной строки в Windows x64 и x86 Windows.
MDMarra

Ответы:

12

Когда 32-битное приложение, запущенное в 64-битной Windows, обращается к системным переменным среды% ProgramFiles% или% commonprogramfiles%, подсистема WoW64 заменяет значения этих переменных на значения переменных% ProgramFiles (x86)% и "% commonprogramfiles (x86)%. Таким образом, например,% ProgramFiles% будет открываться как «C: \ Program Files (x86)» при обращении из 32-разрядной программы.

Это поведение определяется системой перенаправления регистров, которая обеспечивает обратную совместимость 32-разрядного программного обеспечения с 64-разрядными операционными системами. 32-битная среда эмулируется для 32-битных программ, даже несмотря на то, что данные, к которым они обращаются, расположены в другом месте.

Чтобы избежать такого перенаправления в 32-битной программе, вы должны использовать переменные окружения% programfiles% или% COMMONPROGRAMFILES% (т.е. с обратным регистром) или флаг KEY_WOW64_64KEY при доступе к соответствующим узлам регистра.

justin0
источник
На самом деле, вместо того, чтобы избегать перенаправления, я пытаюсь включить его из командной строки Windows; например, я хотел бы иметь возможность создавать сценарии %ProgramFiles%и использовать их C:\Program Filesна 32-разрядных, но при этом использовать C:\Program Files (x86)на 64-разрядных. Именно так работают и Apache, и PHP, и хотя я не могу комментировать, является ли это «правильным», это изящное поведение. Например, я могу установить ServerRoot "${ProgramFiles}\Zend\Apache2"в httpd.conf, и он правильно найдет установку Zend / Apache (которая находится в папке x86 на 64-битной) независимо от версии Windows.
Кен
3
На моей машине в 32-битной командной оболочке echo %programfiles%все еще возвращается 32-битный путь. Однако есть переменная с именем ProgramW6432, которая указывает на 64-битный путь.
Гарри Джонстон
Это не работает для меня. Все эти переменные возвращают один и тот же путь: var environmentVariables = new string[] { "%programfiles%", "%programfiles(x86)%", "%ProgramFiles%", "%commonprogramfiles%", "%COMMONPROGRAMFILES%" };
Саид Неати