问题描述
环境变量 ProgramFiles
、ProgramW6432Dir
、ProgramFilesDir (x86)
、CommonProgramFiles
和 ProgramData
从哪里获取数据?
为什么无法使用 _putenv()
更改这些环境变量的值?
例如:
_putenv( "ProgramFiles=D:\\MyProgs" );
解决方法
在 64 位 Windows 系统上,读取各种环境变量和一些 Windows 注册表项 redirected 到不同的来源,取决于进行读取的进程是否为 64-位或 32 位。
下表列出了这些数据来源:
__init__
例如,对于 32 位进程,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
和 %ProgramFiles%
环境变量的数据源是注册表值 %ProgramFiles(x86)%
。
但是,对于 64 位进程,HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir (x86)
环境变量的数据源是注册表值 %ProgramFiles%
...以及 {{1} } 环境变量是注册表值 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramW6432Dir
大多数默认的 Windows 安装都会在注册表值 %ProgramFiles(x86)%
中添加一个类似 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir (x86)
的字符串,但这可以更改(其他也可以)。
以下是这些环境变量和注册表值中的典型数据:
C:\Program Files (x86)
最终,Windows 资源管理器将在登录时将输入到这些 Windows 注册表值的任何内容读入相应的环境变量,然后复制到它随后产生的任何子进程。子进程可以使用 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir (x86)
注册表值 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
尤其值得注意,因为大多数 Windows 安装都将字符串 _putenv()
放入其中,以便 64 位进程读取。此字符串指的是环境变量 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesPath
,而后者又从注册表值 %ProgramFiles%
中获取其数据……除非某些程序先验地更改了此环境变量的值。
我编写了一个小实用程序,用于显示 64 位和 32 位进程的这些环境变量。你可以下载它here。
包含 VisualStudio 2017 的源代码,编译后的 64 位和 32 位二进制可执行文件分别位于 %ProgramFiles%
和 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramW6432Dir
目录中。