Is it possible to accept custom command line parameters with Inno Setup

Solution 1:

With InnoSetup 5.5.5 (and perhaps other versions), just pass whatever you want as a parameter, prefixed by a /

c:\> myAppInstaller.exe /foo=wiggle

and in your myApp.iss:

[Setup]
AppName = {param:foo|waggle}

The |waggle provides a default value if no parameter matches. Inno setup is not case sensitive. This is a particularly nice way to handle command line options: They just spring into existence. I wish there was as slick a way to let users know what command line parameters the installer cares about.

BTW, this makes both @knguyen's and @steve-dunn's answers somewhat redundant. The utility functions do exactly what the built-in {param: } syntax does.

Solution 2:

Further to @DanLocks' answer, the {param:ParamName|DefaultValue} constant is documented near the bottom of the Constants page:

http://www.jrsoftware.org/ishelp/index.php?topic=consts

I found it quite handy for optionally suppressing the license page. Here is all I needed to add (using Inno Setup 5.5.6(a)):

[code]
{ If there is a command-line parameter "skiplicense=true", don't display license page }
function ShouldSkipPage(PageID: Integer): Boolean;
begin
  Result := False
  if PageId = wpLicense then
    if ExpandConstant('{param:skiplicense|false}') = 'true' then
      Result := True;
end;

Solution 3:

Inno Setup directly supports switches with syntax /Name=Value using {param} constant.


You can use the constant directly in sections, though this use is quite limited.

An example:

[Registry]
Root: HKCU; Subkey: "Software\My Company\My Program\Settings"; ValueType: string; \
    ValueName: "Mode"; ValueData: "{param:Mode|DefaultMode}"

You will more likely want to use switches in Pascal Script.

If your switch has the syntax /Name=Value, the easiest way to read its value is using ExpandConstant function.

For example:

if ExpandConstant('{param:Mode|DefaultMode}') = 'DefaultMode' then
begin
  Log('Installing for default mode');
end
  else
begin
  Log('Installing for different mode');
end;

If you want to use a switch value to toggle entries in sections, you can use Check parameter and a auxiliary function, like:

[Files]
Source: "Client.exe"; DestDir: "{app}"; Check: SwitchHasValue('Mode', 'Client')
Source: "Server.exe"; DestDir: "{app}"; Check: SwitchHasValue('Mode', 'Server')
[Code]

function SwitchHasValue(Name: string; Value: string): Boolean;
begin
  Result := CompareText(ExpandConstant('{param:' + Name + '}'), Value) = 0;
end;

Ironically it is more difficult to check for a mere presence of switch (without a value).

Use can use a function CmdLineParamExists from @TLama's answer to Passing conditional parameter in Inno Setup.

function CmdLineParamExists(const Value: string): Boolean;
var
  I: Integer;  
begin
  Result := False;
  for I := 1 to ParamCount do
    if CompareText(ParamStr(I), Value) = 0 then
    begin
      Result := True;
      Exit;
    end;
end;

You can obviously use the function in Pascal Script:

if CmdLineParamExists('/DefaultMode') then
begin
  Log('Installing for default mode');
end
  else
begin
  Log('Installing for different mode');
end;

But you can even use it in sections, most typically using Check parameter:

[Files]
Source: "MyProg.hlp"; DestDir: "{app}"; Check: CmdLineParamExists('/InstallHelp')

A related problem:
Add user defined command line parameters to /? window

Solution 4:

If you want to parse command line arguments from code in inno, then use a method similar to this. Just call the inno script from the command line as follows:

c:\MyInstallDirectory>MyInnoSetup.exe -myParam parameterValue

Then you can call the GetCommandLineParam like this wherever you need it:

myVariable := GetCommandLineParam('-myParam');
{ ================================================================== }
{ Allows for standard command line parsing assuming a key/value organization }
function GetCommandlineParam (inParam: String):String;
var
  LoopVar : Integer;
  BreakLoop : Boolean;
begin
  { Init the variable to known values }
  LoopVar :=0;
  Result := '';
  BreakLoop := False;

  { Loop through the passed in arry to find the parameter }
  while ( (LoopVar < ParamCount) and
          (not BreakLoop) ) do
  begin
    { Determine if the looked for parameter is the next value }
    if ( (ParamStr(LoopVar) = inParam) and
         ( (LoopVar+1) <= ParamCount )) then
    begin
      { Set the return result equal to the next command line parameter }
      Result := ParamStr(LoopVar+1);

      { Break the loop }
      BreakLoop := True;
    end;

    { Increment the loop variable }
    LoopVar := LoopVar + 1;
  end;
end;