Можно ли принимать пользовательские параметры командной строки с помощью Inno Setup

Я готовлю установщик с Inno Setup. Но я хотел бы добавить дополнительные пользовательские (ни один из доступных параметров) параметры командной строки и хотел бы получить значение параметра, например:

setup.exe /do something

Проверьте, задано ли /do, затем получите значение чего-либо. Является ли это возможным? Как я могу это сделать?


person Similar    schedule 01.09.2010    source источник


Ответы (10)


В InnoSetup 5.5.5 (и, возможно, в других версиях) просто передайте все, что хотите, в качестве параметра с префиксом /.

c:\> myAppInstaller.exe /foo=wiggle

и в вашем myApp.iss:

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

|waggle предоставляет значение по умолчанию, если ни один параметр не соответствует. Inno setup не чувствителен к регистру. Это особенно хороший способ работы с параметрами командной строки: они просто появляются. Хотелось бы, чтобы был такой же удобный способ сообщить пользователям, какие параметры командной строки важны для установщика.

Кстати, это делает ответы @knguyen и @steve-dunn несколько излишними. Вспомогательные функции делают именно то, что делает встроенный синтаксис {param: }.

person Dan Locks    schedule 05.02.2015
comment
@TLama: Ты прав. В голове я смешал параметры препроцессора с параметрами настройки. - person Dan Locks; 10.02.2015
comment
Есть ли способ воспользоваться этим механизмом в коде? Я могу заставить его работать только в разделе [Setup], но вы можете как-то использовать его в разделе [Script]? - person NickG; 11.02.2015
comment
@NickG, да, каждую константу можно расширить с помощью функции ExpandConstant. - person TLama; 12.02.2015
comment
Об использовании ExpandConstant с константой {param} см. мой ответ stackoverflow.com/a/48349992/850848 - person Martin Prikryl; 20.01.2018

В дополнение к ответу @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;
person Mark Berry    schedule 30.01.2016

Inno Setup напрямую поддерживает переключатели с синтаксисом /Name=Value, используя {param} константу.


Вы можете использовать константу непосредственно в секциях, хотя это использование довольно ограничено.

Пример:

[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 параметр< /a> и вспомогательная функция, например:

[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;

Как ни странно, сложнее проверить простое наличие переключателя (без значения).

Использование может использовать функцию CmdLineParamExists из ответа @TLama на Передача условного параметра в 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;

Очевидно, вы можете использовать эту функцию в Pascal Script:

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

Но вы можете использовать его даже в разделах, чаще всего используя параметр Check:

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

Связанная проблема:
Добавить определяемые пользователем параметры командной строки в /? окно

person Martin Prikryl    schedule 19.01.2018
comment
Отличный ответ, как раз то, что мне было нужно. Спасибо, что нашли время написать все полезные фрагменты кода для различных сценариев! - person Violet Giraffe; 07.09.2020

Если вы хотите проанализировать аргументы командной строки из кода в 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;
person Steven Dunn    schedule 03.03.2011
comment
Я нашел это очень полезным, но я не думаю, что он поддерживает значения параметров в кавычках. - person Dragoljub Ćurčić; 02.12.2013
comment
Ответ @knguyen прост и работает со значениями в кавычках. - person Dragoljub Ćurčić; 02.12.2013
comment
Вы можете использовать ExpandConstant , чтобы добиться того же с помощью одной строки кода. См. мой ответ: stackoverflow.com/a/48349992/850848 - person Martin Prikryl; 20.01.2018

Это функция, которую я написал, которая является улучшением ответа Стивена Данна. Вы можете использовать его как:

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;
person knguyen    schedule 22.10.2013
comment
Это прекрасно работает. Я только добавил код для автоматического добавления '/' к значению inParamName, если оно еще не начинается с него. Таким образом, мне нужно только указать имя параметра, и мне не нужно беспокоиться о правильном префиксе имени параметра при получении значения параметра. - person Dragoljub Ćurčić; 02.12.2013
comment
Эти ответы хороши, но с несколькими параметрами определение ParamCount является еще одним соображением. Вот почему ExpandConstant намного проще. - person Laurie Stearn; 19.01.2018
comment
Как правильно прокомментировал @LaurieStearn, вы можете использовать ExpandConstant для достижения того же с помощью одной строки кода. См. мой ответ: stackoverflow.com/a/48349992/850848 - person Martin Prikryl; 20.01.2018

Да, это возможно, вы можете использовать функцию ParamStr в PascalScript для доступа все параметры командной строки. Функция ParamCount даст вам количество параметров командной строки.

Другой вариант — использовать GetCmdTail.

person Otherside    schedule 01.09.2010

В ответ на:

«В InnoSetup 5.5.5 (и, возможно, в других версиях) просто передайте все, что хотите, в качестве параметра с префиксом /» «@NickG, да, каждую константу вы можете расширить с помощью функции ExpandConstant»

  • Это не тот случай. Попытка использовать параметр командной строки в ExpandConstant в InnoSetup 5.5.6 приводит к ошибке времени выполнения.

PS: я бы добавил комментарий напрямую, но, видимо, мне не хватает "репутации"

person Sloth    schedule 26.11.2015
comment
У меня работает в 5.5.6(a). Однако константы имеют очень странный синтаксис; вы должны заключить их в одинарные кавычки внутри вызова функции ExpandConstant. Смотрите мой ответ для примера. - person Mark Berry; 30.01.2016

Я немного изменил ответ 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;
person Irina Leo    schedule 16.01.2018
comment
Мартин, большое спасибо. Это действительно работает, но с этим синтаксисом ExpandConstant('{param:name|defaultvalue}') - person Irina Leo; 16.01.2018
comment
Хорошо, правда, исправим мою команду: хотя это сработает, это совершенно не нужно, поскольку другие ответы показывают, что вы можете использовать ExpandConstant('{param:name|defaultvalue}') для достижения точно такой же функциональности. - person Martin Prikryl; 16.01.2018
comment
@MartinPrikryl: с помощью ExpandConstant('{param:name|defaultvalue}') я могу расширить defaultValue, только если оно константное, правильно? В моем случае defaultValue вычисляется динамически в моем скрипте на основе некоторых условий. Итак, как я могу использовать это значение в Expandconstant, если нет параметра командной строки? - person jamilia; 17.07.2020
comment
@jamilia Нет, значение можно вычислить. Это строковый аргумент функции. Ничто не мешает вам вычислить строковое значение. Хотя это не чат. Пожалуйста, разместите новый отдельный вопрос для вашей новой проблемы. - person Martin Prikryl; 19.07.2020

Я нашел ответ: GetCmdTail.

person Similar    schedule 01.09.2010

Вы можете передавать параметры сценариям установки. Установите препроцессор Inno Setup и прочитайте документацию по передаче пользовательских параметров командной строки.

person Bernard    schedule 01.09.2010
comment
Код препроцессора обрабатывается перед компиляцией установщика, поэтому его нельзя использовать для проверки параметров командной строки результирующего файла setup.exe. - person Otherside; 01.09.2010
comment
Я знаю, поэтому я указал сценарии установщика, а не скомпилированный исполняемый файл установщика. Мне часто приходилось это делать, поэтому я решил упомянуть об этой возможности. - person Bernard; 01.09.2010