刷新环境变量的值

时间:2023-01-15 07:48:59

In my Installscript project I need a reboot to register the values of Environment variables. But I want that application should setup without a reboot. So is their any way to refresh the values of Environment variable so that my application gets registered and no reboot is required? I am already using following code line :

在我的Installscript项目中,我需要重新启动才能注册环境变量的值。但我希望应用程序应该在没有重新启动的情况下进那么他们是否可以通过任何方式刷新Environment变量的值,以便我的应用程序得到注册并且不需要重新启动?我已经在使用以下代码行:

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

Is their is any other way to refresh the Environment variable values? I am running this on Windows xp.

他们是刷新环境变量值的其他方法吗?我在Windows XP上运行它。

2 个解决方案

#1


0  

A Windows process which sets an environment variable cannot access that variable for reading. This is a limitation in Windows. The idea is that if your process sets a variable, it already knows the variable value.

设置环境变量的Windows进程无法访问该变量以进行读取。这是Windows的限制。我们的想法是,如果您的流程设置了变量,它就已经知道了变量值。

So if your installer is setting an environment variable, your application must run in a separate and unrelated process to read that variable. This is why launching the application when the installation finishes doesn't work.

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

A solution is to pass the variable value through your application command line when launching it during install. Any future launches will still access the variable directly.

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

#2


0  

Sending the WININICHANGE message to the broadcast address is the correct thing to do. However there is no requirement that all running processes correctly subclass that message and update their environment variables for that process. They are supposed to, but it doesn't always happen. The most notorious example of this is the Service Control Manager. You have to reboot for the SCM to see the new variable/value.

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

Now if you are asking "how do I get my current running process to see this value?" ( Cosmin seems to think that's what you are asking but I'm not sure if you are or not ) then the answer lies in understanding that the environment space has four collections:

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

User Machine Process Volatile

用户机器过程易失性

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

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

What your code does is set the environment var for SYSTEM. This is like the old days when you would put a line in your autoexec.bat ( SET FOO=BAR ) and reboot. But you could also create a new dos prompt from windows and do SET SOMETHING=ELSE and it would only be seen for the life of that process and child processes but no other processes. This is the "Process" space vs the "System" space. Also if you updated AUTEXEC.BAT with a new variable and created a new process without rebooting it wouldn't see the new variable but you could always set it yourself and see it ( although not technically the same one ).

您的代码所做的是为SYSTEM设置环境变量。这就像过去你在autoexec.bat中设置一行(SET FOO = BAR)并重启一样。但是你也可以从windows创建一个新的dos提示符并执行SET SOMETHING = ELSE,它只能在该进程和子进程的生命周期中看到,但没有其他进程。这是“过程”空间与“系统”空间。此外,如果您使用新变量更新AUTEXEC.BAT并创建新进程而不重新启动它将无法看到新变量,但您可以自己设置它并查看它(虽然在技术上并不相同)。

I know, with SendMessage you shouldn't need the reboot but regardless not all processes will get the message.

我知道,使用SendMessage你不需要重启,但不管所有进程都不会收到消息。

So, if you need the current InstallScript process to also have this new variable, you'll want to call Kernel32's SetEnvironmentVariable function which according to MSDN "Sets the contents of the specified environment variable for the current process."

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

Interesting InstallScript has a GetEnvVar function but not a SetEnvVar function so you'll have to prototype this as an external function and then call it.

有趣的InstallScript有一个GetEnvVar函数,但不是一个SetEnvVar函数,所以你必须将它作为外部函数原型化,然后调用它。

A discussion with samples can be found here.

可以在此处找到与样品的讨论。

#1


0  

A Windows process which sets an environment variable cannot access that variable for reading. This is a limitation in Windows. The idea is that if your process sets a variable, it already knows the variable value.

设置环境变量的Windows进程无法访问该变量以进行读取。这是Windows的限制。我们的想法是,如果您的流程设置了变量,它就已经知道了变量值。

So if your installer is setting an environment variable, your application must run in a separate and unrelated process to read that variable. This is why launching the application when the installation finishes doesn't work.

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

A solution is to pass the variable value through your application command line when launching it during install. Any future launches will still access the variable directly.

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

#2


0  

Sending the WININICHANGE message to the broadcast address is the correct thing to do. However there is no requirement that all running processes correctly subclass that message and update their environment variables for that process. They are supposed to, but it doesn't always happen. The most notorious example of this is the Service Control Manager. You have to reboot for the SCM to see the new variable/value.

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

Now if you are asking "how do I get my current running process to see this value?" ( Cosmin seems to think that's what you are asking but I'm not sure if you are or not ) then the answer lies in understanding that the environment space has four collections:

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

User Machine Process Volatile

用户机器过程易失性

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

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

What your code does is set the environment var for SYSTEM. This is like the old days when you would put a line in your autoexec.bat ( SET FOO=BAR ) and reboot. But you could also create a new dos prompt from windows and do SET SOMETHING=ELSE and it would only be seen for the life of that process and child processes but no other processes. This is the "Process" space vs the "System" space. Also if you updated AUTEXEC.BAT with a new variable and created a new process without rebooting it wouldn't see the new variable but you could always set it yourself and see it ( although not technically the same one ).

您的代码所做的是为SYSTEM设置环境变量。这就像过去你在autoexec.bat中设置一行(SET FOO = BAR)并重启一样。但是你也可以从windows创建一个新的dos提示符并执行SET SOMETHING = ELSE,它只能在该进程和子进程的生命周期中看到,但没有其他进程。这是“过程”空间与“系统”空间。此外,如果您使用新变量更新AUTEXEC.BAT并创建新进程而不重新启动它将无法看到新变量,但您可以自己设置它并查看它(虽然在技术上并不相同)。

I know, with SendMessage you shouldn't need the reboot but regardless not all processes will get the message.

我知道,使用SendMessage你不需要重启,但不管所有进程都不会收到消息。

So, if you need the current InstallScript process to also have this new variable, you'll want to call Kernel32's SetEnvironmentVariable function which according to MSDN "Sets the contents of the specified environment variable for the current process."

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

Interesting InstallScript has a GetEnvVar function but not a SetEnvVar function so you'll have to prototype this as an external function and then call it.

有趣的InstallScript有一个GetEnvVar函数,但不是一个SetEnvVar函数,所以你必须将它作为外部函数原型化,然后调用它。

A discussion with samples can be found here.

可以在此处找到与样品的讨论。