1

I am trying to use environment variables that I set inside the [registry] section of my Inno Setup installer, and then use those environment variables inside the [Run] section by running windows cmds such as postgres psql and node commands to setup my node service / configure my postgres database and user.

How can I refresh the environment variables for the current Inno setup installer during the [Run] Section?

The problem is that when Inno opens a cmd process to run my commands, the environment variables haven't taken effect because the terminal uses the parent's session env var(which don't update) even though I use ChangesEnvironment=yes and calling RefreshEnvironment procedure. I need these environement variables to properly configure my database and my node service using pm2.

The RefreshEnvironment runs this code:

procedure RefreshEnvironment;
  var
    S: AnsiString;
    MsgResult: DWORD;
  begin
    S := 'Environment';
    SendTextMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
      PAnsiChar(S), SMTO_ABORTIFHUNG, 5000, MsgResult);
  end;

EDIT UPDATE

This is an example of my current code:

#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

The Path variable does not get updated and psql cannot be found unless I use a absolute path using the POSTGRES_PATH_ENV_VAR global variable.

I also can't get this to work with installing node js inside the installer then running npm command. Here is a full script of attempting to get it to work:

EDIT 2

I got node to work with using setEnvironmentVariable. But when I try to add a second path for psql then neither of them work? How can I get more than one env var added using 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;
JoelB
  • 401
  • 5
  • 14
  • What flags do you use for your `[Run]` entries? Show us [mcve]. – Martin Prikryl Jun 13 '19 at 20:19
  • @MartinPrikryl I edited my question to include some code – JoelB Jun 13 '19 at 20:26
  • I think you need to execute `SetEnvironmentVariable` as shown in [Environment variable not recognized \[not available\] for \[Run\] programs in Inno Setup](https://stackoverflow.com/q/21708140/850848). – Martin Prikryl Jun 13 '19 at 20:40
  • @MartinPrikryl I tried following the post you linked, and I cannot for the life of me get this to work. I edited my question to include a full script which installs node js but fails to run the node command. Do you have any other ideas? – JoelB Jun 14 '19 at 18:15
  • I do not see any `SetEnvironmentVariable` call in your new code. – Martin Prikryl Jun 14 '19 at 18:28
  • @MartinPrikryl I got node path to work with setEnvironmentVariable, but I can't get more than one path added using that method. I need node and psql for postgres added for the one cmd terminal. I edited the example to show what I mean – JoelB Jun 14 '19 at 18:54
  • I figured it out, turns out I was overriding path each time, and I needed to GetEnv('path') each time I wanted to set a new path and append to it. – JoelB Jun 14 '19 at 19:41
  • So is everything working now as you wanted? – Martin Prikryl Jun 14 '19 at 19:52
  • Yeah i finally got it working. Just have to set all the env vars that I need before install for each cmd steps. Thank you for your help – JoelB Jun 14 '19 at 19:54

0 Answers0