Is it possible to accept custom command line parameters with Inno Setup
I am preparing an installer with Inno Setup. But I'd like to add an additional custom (none of the available parameters) command line parameters and would like to get the value of the p开发者_JAVA百科arameter, like:
setup.exe /do something
Check if /do
is given, then get the value of something. Is it possible? How can I do this?
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.
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;
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
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;
This is the function I wrote, which is an improvement of Steven Dunn's answer. You can use it as:
c:\MyInstallDirectory>MyInnoSetup.exe /myParam="parameterValue"
myVariable := GetCommandLineParam('/myParam');
{ util method, equivalent to C# string.StartsWith }
function StartsWith(SubStr, S: String): Boolean;
begin
Result:= Pos(SubStr, S) = 1;
end;
{ util method, equivalent to C# string.Replace }
function StringReplace(S, oldSubString, newSubString: String): String;
var
stringCopy: String;
begin
stringCopy := S; { Prevent modification to the original string }
StringChange(stringCopy, oldSubString, newSubString);
Result := stringCopy;
end;
{ ================================================================== }
function GetCommandlineParam(inParamName: String): String;
var
paramNameAndValue: String;
i: Integer;
begin
Result := '';
for i := 0 to ParamCount do
begin
paramNameAndValue := ParamStr(i);
if (StartsWith(inParamName, paramNameAndValue)) then
begin
Result := StringReplace(paramNameAndValue, inParamName + '=', '');
break;
end;
end;
end;
Yes it is possible, you can use the ParamStr
function in PascalScript to access all the commandline parameters. The ParamCount
function will give you the number of commandline parameters.
Another possibility is to use GetCmdTail
In response to:
"With InnoSetup 5.5.5 (and perhaps other versions), just pass whatever you want as a parameter, prefixed by a /" "@NickG, yes, every constant you can expand by the ExpandConstant function"
- This is not the case. Trying to use a command line parameter in ExpandConstant in InnoSetup 5.5.6 results in a runtime error.
PS: I would have added a comment directly but apparently I dont have enough "reputation"
I've modified a little bit knguyen's answer. Now it's case insensitive (you can write en console /myParam or /MYPARAM) and it can accept default value. Also I fixed the case when you receive larger parameter then expected (for ex: /myParamOther="parameterValue" in place of /myParam="parameterValue". Now myParamOther doesn't match).
function GetCommandlineParam(inParamName: String; defaultParam: String): String;
var
paramNameAndValue: String;
i: Integer;
begin
Result := defaultParam;
for i := 0 to ParamCount do
begin
paramNameAndValue := ParamStr(i);
if (Pos(Lowercase(inParamName)+'=', AnsiLowercase(paramNameAndValue)) = 1) then
begin
Result := Copy(paramNameAndValue, Length(inParamName)+2, Length(paramNameAndValue)-Length(inParamName));
break;
end;
end;
end;
I found the answer: GetCmdTail.
You can pass parameters to your installer scripts. Install the Inno Setup Preprocessor and read the documentation on passing custom command-line parameters.
精彩评论