[英]How to set a global environment variable from Inno Setup installer?
How do I set a global environment variable in Inno Setup?如何在 Inno Setup 中设置全局环境变量?
Background: I am using the Inno install utility and need to set a global environment variable before I do the actual install.背景:我正在使用 Inno 安装实用程序,需要在进行实际安装之前设置全局环境变量。
Try this:尝试这个:
[Registry]
Root: HKCU; Subkey: "Environment"; ValueType:string; ValueName: "VARIABLE_NAME"; \
ValueData: "new_value"; Flags: preservestringtype
You might need to add this:您可能需要添加以下内容:
[Setup]
; Tell Windows Explorer to reload the environment
ChangesEnvironment=yes
Alternatively try:或者尝试:
[Run]
Filename: "{app}\MyProg.exe"; BeforeInstall: SetEnvPath
[Code]
#ifdef UNICODE
#define AW "W"
#else
#define AW "A"
#endif
function SetEnvironmentVariable(lpName: string; lpValue: string): BOOL;
external 'SetEnvironmentVariable{#AW}@kernel32.dll stdcall';
procedure SetEnvPath;
begin
if not SetEnvironmentVariable('VARIABLE_NAME', 'new_value') then
MsgBox(SysErrorMessage(DLLGetLastError), mbError, MB_OK);
end;
Reference: Inno Setup Frequently Asked Questions - Setting Environment Variables参考: Inno Setup 常见问题-设置环境变量
If the variable change is not propagated (see Environment variable not recognized [not available] for [Run] programs in Inno Setup )如果未传播变量更改(请参阅Inno Setup 中 [Run] 程序的环境变量未识别 [不可用] )
[Run]
...; AfterInstall: RefreshEnvironment
[Code]
const
SMTO_ABORTIFHUNG = 2;
WM_WININICHANGE = $001A;
WM_SETTINGCHANGE = WM_WININICHANGE;
type
WPARAM = UINT_PTR;
LPARAM = INT_PTR;
LRESULT = INT_PTR;
function SendTextMessageTimeout(hWnd: HWND; Msg: UINT;
wParam: WPARAM; lParam: PAnsiChar; fuFlags: UINT;
uTimeout: UINT; out lpdwResult: DWORD): LRESULT;
external 'SendMessageTimeoutA@user32.dll stdcall';
procedure RefreshEnvironment;
var
S: AnsiString;
MsgResult: DWORD;
begin
S := 'Environment';
SendTextMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
PAnsiChar(S), SMTO_ABORTIFHUNG, 5000, MsgResult);
end;
More details:更多细节:
Inno Setup: Setting a System Environment Variable Inno Setup:设置系统环境变量
Under more modern (in other words, proper) operating systems, such as Windows 2000, XP, and Windows 2003 Server, environment variables are stored in the Registry under the following key:
在更现代的(换句话说,适当的)操作系统下,例如 Windows 2000、XP 和 Windows 2003 Server,环境变量存储在注册表中的以下项下:
HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\ Environment
HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\ Environment
Variables are added by creating a new value under this key or by modifying a value if it already exists.
通过在此键下创建新值或修改已存在的值来添加变量。 To delete a variable, you simply delete its Registry value, unless you are removing part of an expanded value, such as PATH, in which case you only remove the part you want.
要删除一个变量,您只需删除它的注册表值,除非您要删除扩展值的一部分,例如 PATH,在这种情况下,您只需删除您想要的部分。
At this point, Windows will not be aware of your changes unless you log off or reboot.
此时,除非您注销或重新启动,否则 Windows 不会知道您的更改。 To get around this, SetEnv will broadcast a WM_SETTINGCHANGE to all of the windows in the system.
为了解决这个问题,SetEnv 将向系统中的所有窗口广播WM_SETTINGCHANGE 。 This allows other running applications—for example, Explorer.exe—to be notified of your change.
这允许其他正在运行的应用程序(例如 Explorer.exe)收到您的更改通知。 If you run SetEnv from a command prompt, this will not update the environment variable for the current DOS window.
如果从命令提示符运行 SetEnv,则不会更新当前 DOS 窗口的环境变量。 This is mainly due to the fact that a process (SetEnv) cannot change the environment of its parent (The Command Prompt).
这主要是因为进程 (SetEnv) 不能改变其父进程的环境(命令提示符)。 However, any new DOS/Command Prompts that you open will show the new variable/value.
但是,您打开的任何新的 DOS/命令提示符都将显示新的变量/值。
What would be wrong with running two setup.exe with the first one doing the setting of the environment variables, and the second doing the things needed for the true setup.运行两个 setup.exe 有什么问题,第一个执行环境变量的设置,第二个执行真正设置所需的操作。 The first one would be run with setup.exe /VERYSILENT
第一个将使用 setup.exe /VERYSILENT 运行
I am doing to add an system wide environment variable:我正在添加一个系统范围的环境变量:
[Setup]
; Tell Windows Explorer to reload the environment
ChangesEnvironment=True
[Registry]
Root: "HKLM"; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; ValueName: "EGPL_GeoLibrarian_Drive"; ValueData: "L"; Flags: createvalueifdoesntexist preservestringtype
The solutions in @Adrian's answer (actually copied from @TLama's answer to similar question ) are correct for many situations. @Adrian 的回答中的解决方案(实际上是从@TLama 对类似问题的回答中复制的)在许多情况下都是正确的。
But it won't work for [Run]
tasks with runasoriginaluser
flag (what is implied by postinstall
flag ).但它不适用于带有
runasoriginaluser
标志的[Run]
任务( postinstall
flag所暗示的内容)。 Ie the variable won't be propagated to an application run with common "Run My Program" check box on the "Finished" page.即该变量不会传播到使用“已完成”页面上常见的“运行我的程序”复选框运行的应用程序。
The reason is that the tasks with runasoriginaluser
are executed by a un-elevated hidden parent process of the Inno Setup installer.原因是
runasoriginaluser
的任务由 Inno Setup 安装程序的未提升的隐藏父进程执行。 The SetEnvironmentVariable
will change environment for the installer, but not for its parent process. SetEnvironmentVariable
将更改安装程序的环境,但不会更改其父进程。 Unfortunately, the parent process of the installer cannot be controlled (imo).不幸的是,安装程序的父进程无法控制(imo)。
As a workaround, to set the variable for the runasoriginaluser
tasks, you have to inject an intermediate process between the installer parent process and the task, and have the intermediate process set the variable.作为一种解决方法,要为
runasoriginaluser
任务设置变量,您必须在安装程序父进程和任务之间注入一个中间进程,并让中间进程设置变量。
Such an intermediate process can easily be the cmd.exe
with its set
command :这样的中间过程可以很容易地成为
cmd.exe
及其set
命令:
[Run]
Filename: "{cmd}"; Parameters: "/C set MYVAR=MyValue & ""{app}\MyProg.exe"""; \
Description: "Run My Program"; Flags: postinstall runhidden
The runhidden
flag hides the cmd.exe
console window, not the application (assuming it's a GUI application). runhidden
标志隐藏cmd.exe
控制台窗口,而不是应用程序(假设它是一个 GUI 应用程序)。 If it's a console application, use start
to start it in its own (visible) console window.如果它是一个控制台应用程序,请使用
start
在它自己的(可见的)控制台窗口中启动它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.