【发布时间】:2011-04-06 19:18:39
【问题描述】:
我正在使用 Inno Setup 准备安装程序。但我想添加一个额外的自定义(没有可用参数)命令行参数,并想获取参数的值,例如:
setup.exe /do something
检查是否给出了/do,然后获取某物的值。可能吗?我该怎么做?
【问题讨论】:
标签: command-line inno-setup command-line-arguments
我正在使用 Inno Setup 准备安装程序。但我想添加一个额外的自定义(没有可用参数)命令行参数,并想获取参数的值,例如:
setup.exe /do something
检查是否给出了/do,然后获取某物的值。可能吗?我该怎么做?
【问题讨论】:
标签: command-line inno-setup command-line-arguments
Inno Setup 直接支持使用{param} constant 语法/Name=Value 的开关。
您可以直接在部分中使用该常量,尽管这种用途非常有限。
一个例子:
[Registry]
Root: HKCU; Subkey: "Software\My Company\My Program\Settings"; ValueType: string; \
ValueName: "Mode"; ValueData: "{param:Mode|DefaultMode}"
您更有可能希望在Pascal Script 中使用开关。
如果您的开关具有/Name=Value 语法,则读取其值的最简单方法是使用ExpandConstant function。
例如:
if ExpandConstant('{param:Mode|DefaultMode}') = 'DefaultMode' then
begin
Log('Installing for default mode');
end
else
begin
Log('Installing for different mode');
end;
如果要使用开关值来切换部分中的条目,可以使用Check parameter 和辅助功能,例如:
[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;
具有讽刺意味的是,仅检查是否存在 switch(没有值)更加困难。
使用可以使用@TLama 对Passing conditional parameter in Inno Setup 的回答中的函数CmdLineParamExists。
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;
你显然可以使用 Pascal Script 中的函数:
if CmdLineParamExists('/DefaultMode') then
begin
Log('Installing for default mode');
end
else
begin
Log('Installing for different mode');
end;
但您甚至可以分段使用它,最常见的是使用Check parameter:
[Files]
Source: "MyProg.hlp"; DestDir: "{app}"; Check: CmdLineParamExists('/InstallHelp')
一个相关问题:
Add user defined command line parameters to /? window
【讨论】:
我修改了一点knguyen的答案。现在它不区分大小写(您可以在控制台中编写 /myParam 或 /MYPARAM)并且它可以接受默认值。我还修复了当您收到比预期更大的参数时的情况(例如:/myParamOther="parameterValue" 代替 /myParam="parameterValue"。现在 myParamOther 不匹配)。
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;
【讨论】:
ExpandConstant('{param:name|defaultvalue}') 来实现完全相同的功能。
这是我写的函数,是对 Steven Dunn 的回答的改进。您可以将其用作:
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;
【讨论】:
ParamCount 是另一个考虑因素。这就是ExpandConstant 如此简单的原因。
ExpandConstant 通过一行代码实现相同的目的。看我的回答:stackoverflow.com/a/48349992/850848
如果你想从 inno 中的代码解析命令行参数,那么使用类似的方法。只需从命令行调用 inno 脚本,如下所示:
c:\MyInstallDirectory>MyInnoSetup.exe -myParam parameterValue
然后,您可以在任何需要的地方调用 GetCommandLineParam:
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;
【讨论】:
ExpandConstant 用一行代码实现相同的目的。看我的回答:stackoverflow.com/a/48349992/850848
除了@DanLocks 的回答,{param:ParamName|DefaultValue} 常量记录在常量页面底部附近:
http://www.jrsoftware.org/ishelp/index.php?topic=consts
我发现选择性地隐藏许可证页面非常方便。这是我需要添加的所有内容(使用 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;
【讨论】:
回应:
“使用 InnoSetup 5.5.5(可能还有其他版本),只需将任何你想要的作为参数传递,以 / 为前缀” "@NickG,是的,您可以通过 ExpandConstant 函数扩展的每个常量"
PS:我会直接添加评论,但显然我没有足够的“声誉”
【讨论】:
使用 InnoSetup 5.5.5(可能还有其他版本),只需将您想要的任何参数作为参数传递,前缀为 /
c:\> myAppInstaller.exe /foo=wiggle
在你的 myApp.iss 中:
[Setup]
AppName = {param:foo|waggle}
如果没有参数匹配,|waggle 会提供默认值。 Inno 设置不区分大小写。这是处理命令行选项的一种特别好的方法:它们刚刚出现。我希望有一种巧妙的方法让用户知道安装程序关心的命令行参数。
顺便说一句,这使得@knguyen 和@steve-dunn 的答案有些多余。实用程序函数的功能与内置 {param: } 语法完全相同。
【讨论】:
ExpandConstant 函数扩展每个常量。
ExpandConstant 和{param} 常量,请参阅我的答案stackoverflow.com/a/48349992/850848
您可以将参数传递给安装程序脚本。安装Inno Setup Preprocessor 并阅读有关传递自定义命令行参数的文档。
【讨论】:
是的,您可以使用 PascalScript 中的 ParamStr 函数来访问所有命令行参数。 ParamCount 函数将为您提供命令行参数的数量。
另一种可能是使用GetCmdTail
【讨论】:
我找到了答案:GetCmdTail。
【讨论】: