以编程方式设置全局环境变量

时间:2018-02-22 12:56:01

标签: c++ c windows winapi environment-variables

我需要以编程方式设置环境变量。

Microsoft提供了here的文档。您只需要在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment下的注册表中创建一个新值。这部分工作正常。

问题是这些更改只有在注销并再次登录后才会生效。

为了传达这一点,他们建议执行这一小段代码:

if (!SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
    (LPARAM) "Environment", SMTO_ABORTIFHUNG,
    5000, &dwReturnValue))
{
  ... take action in case of failure
}

我做到了这一点,SendMessageTimeout返回TRUE,但至少在Windows 10下它没有效果。新打开的命令提示符窗口仍然不会显示新创建的变量。

我还尝试在升级过程中运行这段代码,但结果仍然相同。

但是当我使用系统applet更改环境变量时,我新创建的变量显示出来,当我在applet上单击OK时,当我打开另一个命令提示符时,变量就在那里。

有什么想法吗?

2 个答案:

答案 0 :(得分:6)

通过明确调用SendMessageTimeout wide 版本并将"Environment"作为 wide 字符串发送来解决问题:

SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 
                   (LPARAM)L"Environment", SMTO_ABORTIFHUNG, 5000, &dwReturnValue);

答案 1 :(得分:2)

Michael发现,字符串宽度需要与A / W功能类型相匹配。 WM_SETTINGCHANGE位于< WM_USER范围内,将由窗口管理器封送。

如果您不想对函数名称后缀进行硬编码,则可以使用TEXT macro创建适用于所有人的代码:

SendMessageTimeout(
  HWND_BROADCAST,
  WM_SETTINGCHANGE, 
  0, 
  (LPARAM) TEXT("Environment"),
  SMTO_ABORTIFHUNG,
  5000,
  &dwReturnValue
);