![](/img/trans.png)
[英]How to set registry key (environment variable) with value from [Code] section of Inno Setup?
[英]How to set a global environment variable from Inno Setup installer?
如何在 Inno Setup 中設置全局環境變量?
背景:我正在使用 Inno 安裝實用程序,需要在進行實際安裝之前設置全局環境變量。
嘗試這個:
[Registry]
Root: HKCU; Subkey: "Environment"; ValueType:string; ValueName: "VARIABLE_NAME"; \
ValueData: "new_value"; Flags: preservestringtype
您可能需要添加以下內容:
[Setup]
; Tell Windows Explorer to reload the environment
ChangesEnvironment=yes
或者嘗試:
[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;
如果未傳播變量更改(請參閱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;
更多細節:
在更現代的(換句話說,適當的)操作系統下,例如 Windows 2000、XP 和 Windows 2003 Server,環境變量存儲在注冊表中的以下項下:
HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\ Environment
通過在此鍵下創建新值或修改已存在的值來添加變量。 要刪除一個變量,您只需刪除它的注冊表值,除非您要刪除擴展值的一部分,例如 PATH,在這種情況下,您只需刪除您想要的部分。
此時,除非您注銷或重新啟動,否則 Windows 不會知道您的更改。 為了解決這個問題,SetEnv 將向系統中的所有窗口廣播WM_SETTINGCHANGE 。 這允許其他正在運行的應用程序(例如 Explorer.exe)收到您的更改通知。 如果從命令提示符運行 SetEnv,則不會更新當前 DOS 窗口的環境變量。 這主要是因為進程 (SetEnv) 不能改變其父進程的環境(命令提示符)。 但是,您打開的任何新的 DOS/命令提示符都將顯示新的變量/值。
運行兩個 setup.exe 有什么問題,第一個執行環境變量的設置,第二個執行真正設置所需的操作。 第一個將使用 setup.exe /VERYSILENT 運行
我正在添加一個系統范圍的環境變量:
[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
@Adrian 的回答中的解決方案(實際上是從@TLama 對類似問題的回答中復制的)在許多情況下都是正確的。
但它不適用於帶有runasoriginaluser
標志的[Run]
任務( postinstall
flag所暗示的內容)。 即該變量不會傳播到使用“已完成”頁面上常見的“運行我的程序”復選框運行的應用程序。
原因是runasoriginaluser
的任務由 Inno Setup 安裝程序的未提升的隱藏父進程執行。 SetEnvironmentVariable
將更改安裝程序的環境,但不會更改其父進程。 不幸的是,安裝程序的父進程無法控制(imo)。
作為一種解決方法,要為runasoriginaluser
任務設置變量,您必須在安裝程序父進程和任務之間注入一個中間進程,並讓中間進程設置變量。
這樣的中間過程可以很容易地成為cmd.exe
及其set
命令:
[Run]
Filename: "{cmd}"; Parameters: "/C set MYVAR=MyValue & ""{app}\MyProg.exe"""; \
Description: "Run My Program"; Flags: postinstall runhidden
runhidden
標志隱藏cmd.exe
控制台窗口,而不是應用程序(假設它是一個 GUI 應用程序)。 如果它是一個控制台應用程序,請使用start
在它自己的(可見的)控制台窗口中啟動它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.