How to set a global environment variable from Inno Setup installer?

inno setup environment variable
inno setup documentation
inno setup commonappdata
inno setup variables
how to use inno setup
inno setup code
inno setup files
inno setup function example

How do I set a global environment variable in Inno Setup?

Background: I am using the Inno install utility and need to set a global environment variable before I do the actual install.

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

If the variable change is not propagated (see Environment variable not recognized [not available] for [Run] programs in Inno Setup)

[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

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:

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.

At this point, Windows will not be aware of your changes unless you log off or reboot. To get around this, SetEnv will broadcast a WM_SETTINGCHANGE to all of the windows in the system. This allows other running applications—for example, Explorer.exe—to be notified of your change. If you run SetEnv from a command prompt, this will not update the environment variable for the current DOS window. This is mainly due to the fact that a process (SetEnv) cannot change the environment of its parent (The Command Prompt). However, any new DOS/Command Prompts that you open will show the new variable/value.

ChangesEnvironment, How do I set a global environment variable in Inno Setup? Background: I am using the Inno install utility and need to set a global environment variable before I​  Here is the entire sordid story: Some of the inno panels get information from the user. Based on that info I may need to set an environment variable. Then I try to start a process that will not run unless the environment variable is set. All of this before the install. Everything appears to be working except setting the var.

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. The first one would be run with 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

Inno Setup FAQ, If your installation creates or changes an environment variable but doesn't have ChangesEnvironment set to yes, the new/changed environment variable will not​  Inno Setup lets you set environment variables via the [Registry] sections (by setting registry key which correspond to environment variable) However, sometimes you don't just wanna set an environment variable. Often, you wanna modify it. For example: upon installation, one may want to add/remove a directory to/from the PATH environment variable.

The solutions in @Adrian's answer (actually copied from @TLama's answer to similar question) are correct for many situations.

But it won't work for [Run] tasks with runasoriginaluser flag (what is implied by postinstall flag). I.e. 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. The SetEnvironmentVariable will change environment for the installer, but not for its parent process. Unfortunately, the parent process of the installer cannot be controlled (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.

Such an intermediate process can easily be the cmd.exe with its set command:

[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). If it's a console application, use start to start it in its own (visible) console window.

Constants, Is it possible to do a silent install without using the /SILENT or /VERYSILENT Creating File Associations; Setting Environment Variables; Setting the "Close on Exit" OCX Files; Visual Basic System Files; Visual C++ System Files (e.g. MFC)​  According to this page in the Inno Setup documentation, the value of environment variables can be retrieved using the following syntax: {%name|default} I ran into the same problem when trying to specify the source location of files in the [Files] section.

How do I modify the PATH environment variable when running an , EXE". {win}. The system's Windows directory. For example: If you used {win}\​MYPROG.INI on an entry (This can be overridden by enabling 64-bit install mode.) This directory constant is equivalent to the SystemDrive environment variable. Make sure you're using the latest version of InnoSetup (v5.1.12). Once you've got ISPP installed with InnoSetup, you can create variables that can be used similar to the way you describe. For example: ; Script generated by the Inno Setup Script Wizard.

Setting a System Environment Variable, Inno Setup lets you set environment variables via the [Registry] sections (by setting upon installation, one may want to add/remove a directory to/from the PATH Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\​Environment";  Installation and Usage (Inno Setup) To use ModPath in your Inno Setup package, follow these steps: Copy modpath.iss to the same directory as your setup script; Add this statement to your [Setup] section; ChangesEnvironment=true; Add this statement to your [Tasks] section; You can change the Description or Flags.

Inno Setup ChangeEnvironment not working, How do I set a global environment variable in Inno Setup? Background: I am using the Inno install utility and need to set a global environment  Returns the current include path (or paths delimited with semicolons) set via #pragma include. __LINE__: int. Returns the number of the line in the current file (not a translation) on which the variable is used (or user defined function that uses this variable is called). __OPT_X__ void. Defined if specified option set via #pragma option -x+ is

Comments
  • See also stackoverflow.com/questions/21708140/… and stackoverflow.com/questions/10687188/…
  • Then do this change from code in the PrepareToInstall event. For what you need to make this change ? I'm asking because processes inherit environment variable blocks, so if you'd e.g. set some environment variable by the SetEnvironmentVariable function, process executed from Inno Setup would see that change. However, such change would not be persistent. On the other hand you can change the variables persistently in registry (and optionally call my RefreshEnvironment procedure which will notify running apps about the environment change).
  • Here is the entire sordid story: Some of the inno panels get information from the user. Based on that info I may need to set an environment variable. Then I try to start a process that will not run unless the environment variable is set. All of this before the install. Everything appears to be working except setting the var. (If I set the var by hand before running the install, everything works fine.)
  • More background: We are doing our own licensing scheme, and what I am trying to do is make sure they have set up their license correctly so that the installation can help them out if they are having problems.
  • I have also tried RegWriteDWordValue(HKEY_CURRENT_USER,'name','value',1); followed by the RefreshEnvironment call.
  • Oh, good point. Then I guess my question has been answered above.
  • What would be wrong on having two installer binaries from which one will only set an environment variable ? Ask yourself ;-) P.S. ChangesEnvironment does not tell anything to Windows Explorer. It broadcasts the WM_SETTINGCHANGE message to all top-level windows (with lParam == "Environment").