我正在尝试使用在Inno Setup安装程序的[registry]部分中设置的环境变量,然后通过运行Windows cmds(例如postgres psql和node命令)来在[Run]部分中使用这些环境变量进行设置我的节点服务/配置我的postgres数据库和用户。
如何在[运行]部分刷新当前Inno安装程序安装程序的环境变量?
问题是,当Inno打开cmd进程来运行我的命令时,环境变量没有生效,因为即使我使用ChangesEnvironment = yes,终端也使用父级的会话环境var(不会更新),并且调用RefreshEnvironment过程。我需要这些环境变量来使用pm2正确配置数据库和节点服务。
RefreshEnvironment运行以下代码:
procedure RefreshEnvironment;
var
S: AnsiString;
MsgResult: DWORD;
begin
S := 'Environment';
SendTextMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
PAnsiChar(S), SMTO_ABORTIFHUNG, 5000, MsgResult);
end;
编辑更新
这是我当前代码的示例:
#define POSTGRES_PATH_ENV_VAR "C:\Program Files\PostgreSQL\11\bin"
[Registry]
; Path Env Vars
; Postgres commands
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \
ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};{#POSTGRES_PATH_ENV_VAR}"; \
Check: NeedsAddPath('{#POSTGRES_PATH_ENV_VAR}')
[Run]
; Install Postgres
Filename: "{tmp}\{#POSTGRES}"; StatusMsg: "Installing Postgres..."; BeforeInstall: RefreshEnvironment();
; Configure Postgres after installation
Filename: "{cmd}"; Parameters: "/k """"{#POSTGRES_PATH_ENV_VAR}\psql"" -c ""CREATE USER {code:GetPostgresEnvVar|2} WITH PASSWORD 'testingPassword';"" -U postgres & \
""{#POSTGRES_PATH_ENV_VAR}\psql"" -c ""CREATE DATABASE testUser OWNER postgres"" -U postgres"""; StatusMsg: "Configuring PostgreSQL..."; Flags: shellexec runascurrentuser waituntilterminated
除非使用POSTGRES_PATH_ENV_VAR全局变量使用绝对路径,否则Path变量不会更新,也无法找到psql。
我也无法通过在安装程序中安装node js然后运行npm命令来解决这个问题。这是尝试使其正常工作的完整脚本:
编辑2
我有了使用setEnvironmentVariable的节点。但是,当我尝试为psql添加第二条路径时,它们都不起作用吗?如何使用setEnvironmentVariable添加多个环境变量?
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "Test"
#define MyAppVersion "0.2.0"
#define MyAppPublisher "Blarg"
; Programs
#define NODE "node-v10.16.0-x64.msi"
#define POSTGRES_PATH_ENV_VAR "C:\Program Files\PostgreSQL\11\bin"
[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{33B47B4D-F4A9-43F5-BF97-8A485232253C}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
; AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
DefaultDirName=C:\Program Files\TestingApp\{#MyAppName}
DisableDirPage=yes
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
; Uncomment the following line to run in non administrative install mode (install for current user only.)
; PrivilegesRequired=lowest
OutputDir=C:\Users\Joel\Desktop
OutputBaseFilename=Test-Installer-{#MyAppVersion}
Compression=lzma
SolidCompression=yes
WizardStyle=modern
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Files]
Source: "installation_files\{#NODE}"; DestDir: "{tmp}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Icons]
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
[Run]
; Install Node
Filename: "{sys}\msiexec.exe"; Parameters: "/i ""{tmp}\{#NODE}"""; StatusMsg: "Installing Node.Js...";
; Install Postgres
; Postgres Configuring and run first time setup if database creates successfully
Filename: "{cmd}"; Parameters: "/k node -v && npm -v && psql"; StatusMsg: "Testing Node and Psql..."; BeforeInstall: SetEnvPath; Flags: shellexec runascurrentuser waituntilterminated;
[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);
MsgBox('Refreshed Environment Variables.', mbInformation, MB_OK);
end;
#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('PATH', 'C:\Program Files\nodejs\') then
MsgBox(SysErrorMessage(DLLGetLastError), mbError, MB_OK);
if not SetEnvironmentVariable('PATH', '{#POSTGRES_PATH_ENV_VAR}') then
MsgBox(SysErrorMessage(DLLGetLastError), mbError, MB_OK);
end;