如何为当前的Inno设置安装程序进程刷新环境变量?

时间:2019-06-13 20:03:08

标签: windows inno-setup

我正在尝试使用在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;

0 个答案:

没有答案