【问题标题】:Access custom environment variable without rebooting (using C++)无需重启即可访问自定义环境变量(使用 C++)
【发布时间】:2012-02-07 12:22:28
【问题描述】:

我正在使用 C++ 编写一个利用自定义系统范围环境变量的程序。该变量由 msi 安装程序设置。后来我的程序使用 GetEnvironmentVariable() API 读取它。

问题在于,似乎需要重新启动系统才能让我的自定义环境变量在我的程序中可见,而我不想为此重新启动系统。

似乎奇怪的是,如果(不重新启动)我右键单击我的电脑,然后进入属性 -> 高级并单击“环境变量”,我的自定义环境变量在该列表中,但由于某种原因 GetEnvironmentVariable () 仍然没有看到它。

那么有没有其他我可以使用的 API 可以在不重新启动系统的情况下工作? (因为系统属性可以清楚地看到它。)

【问题讨论】:

  • 您通常不需要重新启动,但是在进程启动时会复制环境,因此您肯定需要重新启动程序才能看到新的环境变量。请注意,在某些情况下,您需要重新启动启动您的程序(例如,通过持久命令提示符启动进程时)。您的计划是如何开始的?
  • @Jesse:环境变量由外部程序(在这种情况下为安装程序)设置。
  • @AndréCaron:谢谢,我会删除我的评论。

标签: c++ winapi environment-variables


【解决方案1】:

如果您想在不重新启动系统的情况下执行此操作,您需要broadcast it。类似于

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

Explorer 正确处理此消息,因此在此广播之后启动的程序将看到更改。

  1. 从技术上讲,您也不需要重新启动、简单的注销和 登录就足够了
  2. 另一种选择是简单地restart explorer

【讨论】:

  • 我在这里有点困惑。我以为 GetEnvironmentVariable() 是 kernel32.dll 的一部分,与 Windows Explorer 无关?
  • @ahmd0:我认为当资源管理器收到该消息时,它将从注册表中重新加载其环境变量,然后所有新的子进程都将拥有这些环境变量。
  • 当进程启动时,它会从其父进程继承环境变量。当您双击一个 exe 时,资源管理器进程正在启动您的 exe,因此如果资源管理器知道环境变量,那么您的进程也会这样做
  • @icktoofay 谢谢。我仍然不确定我应该从哪里广播该消息?安装程序是一个 msi 进程,我认为我不能从那里完成它。在我自己的过程中,它是一个服务应用程序,无法访问用户桌面来广播任何消息......
  • 您可以将答案中的代码包装成一个简单的 exe,并在安装结束时启动该 exe。或者您可以完全跳过环境变量,并将一些适当的写入磁盘,以便您的 exe 可以在启动时读取
【解决方案2】:

我最近遇到了这样的事情,并且广播消息是正确的方式,正如这个 kb(和 parapura)中所解释的那样:

http://support.microsoft.com/kb/104011

但是,我建议将 _T() 放在“环境”(或者可能是“L”)周围,以确保您传入正确的字符串(ansi 或宽)。像这样:

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

我在命令行应用程序中使用了上述内容。没有 _T() 消息发送成功,但我的系统似乎从未收到环境变量的更新。

顺便说一句,'setx' 命令行可能使用相同的机制来更新环境变量。 另外,我在 atl dll 中使用它。

【讨论】:

    猜你喜欢
    • 2017-12-04
    • 2014-01-24
    • 2015-09-08
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-29
    • 2018-06-17
    相关资源
    最近更新 更多