1

在我的 Installscript 项目中,我需要重新启动以注册环境变量的值。但我希望该应用程序无需重新启动即可设置。那么他们有什么方法可以刷新环境变量的值,以便我的应用程序被注册并且不需要重新启动?我已经在使用以下代码行:

define WM_WININICHANGE 0x001A'
define HWND_BROADCAST 0xffff'
szEnv = "Environment";
pEnv = &szEnv;
SendMessage( HWND_BROADCAST, WM_WININICHANGE, 0, pEnv );`

他们是刷新环境变量值的任何其他方式吗?我在 Windows xp 上运行它。

4

2 回答 2

0

设置环境变量的 Windows 进程无法访问该变量以进行读取。这是 Windows 中的限制。这个想法是,如果你的进程设置了一个变量,它已经知道变量值。

因此,如果您的安装程序正在设置环境变量,您的应用程序必须在单独且不相关的进程中运行才能读取该变量。这就是为什么在安装完成时启动应用程序不起作用的原因。

一种解决方案是在安装期间启动应用程序时通过应用程序命令行传递变量值。任何未来的启动仍将直接访问该变量。

于 2011-10-20T12:42:16.057 回答
0

将 WININICHANGE 消息发送到广播地址是正确的做法。但是,并不要求所有正在运行的进程都正确地继承该消息并为该进程更新它们的环境变量。他们应该这样做,但并不总是发生。最臭名昭著的例子是服务控制管理器。您必须重新启动 SCM 才能看到新的变量/值。

现在,如果您问“如何让我当前正在运行的进程看到这个值?” (Cosmin 似乎认为这就是您要问的,但我不确定您是否是)那么答案在于了解环境空间有四个集合:

用户机器进程不稳定

http://msdn.microsoft.com/en-us/library/6s7w15a0(v=vs.85).aspx

您的代码所做的是为 SYSTEM 设置环境变量。这就像您在 autoexec.bat ( SET FOO=BAR ) 中放入一行并重新启动的过去一样。但是您也可以从 Windows 中创建一个新的 dos 提示符并执行 SET SOMETHING=ELSE 并且它只会在该进程和子进程的生命周期内看到,而不会在其他进程中看到。这是“进程”空间与“系统”空间。此外,如果您使用新变量更新了 AUTEXEC.BAT 并在不重新启动的情况下创建了一个新进程,它将看不到新变量,但您始终可以自己设置并查看它(尽管从技术上讲不是同一个)。

我知道,使用 SendMessage 您不需要重新启动,但并非所有进程都会收到消息。

因此,如果您需要当前的 InstallScript 进程也有这个新变量,您将需要调用 Kernel32 的SetEnvironmentVariable函数,该函数根据 MSDN“为当前进程设置指定环境变量的内容”。

有趣的 InstallScript 有一个 GetEnvVar 函数,但没有一个 SetEnvVar 函数,因此您必须将其原型化为外部函数,然后调用它。

可以在此处找到与示例的讨论。

于 2011-10-20T13:16:04.673 回答