Выйти из установки Inno Setup из [Код]

Можно ли выйти из установки из функции в разделе [Code] установщика, созданного с помощью Inno Setup?

Меня не интересует установка кода выхода, я хочу выполнить настраиваемую проверку на наличие требования и выйти из установки, если это требование ранее не было установлено.


person Matheus    schedule 14.12.2010    source источник
comment
Здесь был дан ответ на вопрос: stackoverflow.com/questions/6345920/   -  person 010110110101    schedule 07.05.2013


Ответы (6)


Вы можете использовать Abort () в следующих случаях:

InitializeSetup
InitializeWizard
CurStepChanged(ssInstall)
InitializeUninstall
CurUninstallStepChanged(usAppMutexCheck)
CurUninstallStepChanged(usUninstall)
person lepe    schedule 11.08.2011

Чтобы программа установки не запускалась, когда проверка предварительных требований не проходит, просто верните False из InitializeSetup . Это приведет к выходу из установщика даже до того, как отобразится мастер.

function InitializeSetup(): Boolean;
begin
  Result := True;

  if not PrerequisitesTest then
  begin                     
    SuppressibleMsgBox('Prerequisites test failed', mbError, MB_OK, MB_OK);
    Result := False;
  end;
end;

введите описание изображения здесь


Если вам нужно проверить предварительные условия только непосредственно перед началом установки (т.е. InitializeSetup слишком рано), вы можете вызвать _ 5_ функция из CurStepChanged(ssInstall) :

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssInstall then
  begin
    if not PrerequisitesTest then
    begin                     
      SuppressibleMsgBox('Prerequisites test failed', mbError, MB_OK, MB_OK);
      Abort;
    end;
  end;
end;

введите описание изображения здесь


Хотя для этого сценария рассмотрите возможность использования вместо этого механизма PrepareToInstall event function выхода из настройки.

function PrepareToInstall(var NeedsRestart: Boolean): String;
begin
  Result := '';

  if not PrerequisitesTest then
  begin                     
    Result := 'Prerequisites test failed';
  end;
end;

введите описание изображения здесь


Если вам нужно принудительно завершить программу установки в любое другое время, используйте вызов ExitProcess WinAPI:

procedure ExitProcess(uExitCode: Integer);
  external '[email protected] stdcall';

function NextButtonClick(CurPageID: Integer): Boolean;
begin
  if CurPageID = wpReady then
  begin
    if not PrerequisitesTest then
    begin                     
      SuppressibleMsgBox('Prerequisites test failed', mbError, MB_OK, MB_OK);
      ExitProcess(1);
    end;
  end;
  Result := True;
end;

Хотя это довольно опасный выход, поэтому используйте его только в крайнем случае. Если у вас загружена какая-либо внешняя DLL, вам может потребоваться сначала выгрузить ее, чтобы избежать сбоев. Это также не очищает временный каталог.

введите описание изображения здесь


person Martin Prikryl    schedule 30.09.2016

Я делаю это так:

procedure ExitProcess(exitCode:integer);
  external '[email protected] stdcall';

И способ его использования:

[Code]
  if .... then begin
     ExitProcess(0);
  end;
person lepe    schedule 11.08.2011
comment
Хотя с точки зрения пользователя это работает, временные файлы остаются. - person Gogowitsch; 09.07.2012
comment
В этом ответе используется Wizard.Close, который, кажется, позволяет избежать этой проблемы. stackoverflow .com / questions / 6345920 /. - person 010110110101; 07.05.2013
comment
@JerryDodge Вы можете отключить подсказку. См. stackoverflow.com/a/12849863/382885 - person PolyTekPatrick; 14.05.2015
comment
@ 010110110101 Использование WizardForm.Close не работает в тихом режиме (/silent), поэтому пользователь может легко обойти проверку. - person Martin Prikryl; 30.09.2016
comment
WizardForm.Close также не работает на пользовательских страницах после ssInstall. - person MSalters; 26.07.2018

Взгляните на InitializeSetup и Abort в справке InnoSetup. Как сказал Коди, это возможно. Если у вас возникли проблемы, опубликуйте, что вы сделали и какая у вас проблема.

person mirtheil    schedule 14.12.2010

Это описание того, что я сегодня возился с Inno 5.6.1, и источников, которые вы можете найти по адресу https://github.com/jrsoftware/issrc [ref1]

Возможно, полезное комплексное решение «Выход из [Код]»

TL; Пример DR:

[Code]
var _ImmediateInnoExit_was_invoked_flag: Boolean; // Inno/Pascal Script initializes all Boolean to False.

procedure ImmediateInnoExit();
  var MainFormRef: TForm;
begin
  _ImmediateInnoExit_was_invoked_flag := True;
  try
    MainFormRef := MainForm(); // calls GetMainForm() in Inno pascal code, which will raise an internal exception if the form is not yet initialized.
    Log('INFO: ImmediateInnoExit: Calling MainForm.Close()!');
    Log('NOTE: If the Event Fn CancelButtonClick is not coded to auto-Confirm, this will display the cancel dialog in the GUI case!');
    Log('NOTE: Code will stall inside the Close() function while the Cancel confirmation dialog is displayed.');
    MainFormRef.Close(); // this is only effective if the Wizard is visible, but we cann call it even when running siently (as long as the Wizard is initialized)
    Log('NOTE: MainForm.Close() invoked. (If confirmed, setup will exit.)');
  except
    Log('INFO: ImmediateInnoExit did not resolve MainForm -> assuming we were call in an InitializeSetup() context before the Main form has been created!');
  end;

  Log('INFO: ImmediateInnoExit: Calling Abort() -> EAbort!');
  Log('NOTE: Will exit the current scope.');
  Log('NOTE:   In GUI mode, it will just jump up to the Delphi event loop (and be ignored there). (But the WizardForm.Close() call should lead to exit!)');
  Log('NOTE:   In Silent Mode, it will be caught and exit the setup.');
  Abort(); // Raise EAbort
end;

// This is called when the user clicks the cancel button or the [x] Close button
// the close/cancel can be invoked from code via WizardForm.Close!
procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin

  Log(Format('IN: CancelButtonClick(%d <- Cancel=[%d], Confirm=[%d])', [CurPageID, Cancel, Confirm]));
  Confirm := not _ImmediateInnoExit_was_invoked_flag; // if Confirm==False we don't get the dialog prompt.
  Log(Format('IN: CancelButtonClick(%d -> [%d], [%d])', [CurPageID, Cancel, Confirm]));
end;

А теперь в чем суть приведенного выше кода:

Анатомия Inno Setup Exit / Cancel и Abort

Abort

Документы Inno для Abort состояния:

Описание: Выход из текущего пути выполнения без сообщения об ошибке.

Прерывание вызывает специальное «тихое исключение», которое работает как любое другое исключение, но не отображает сообщение об ошибке для конечного пользователя.

Примечания.
Abort не вызывает завершение установки или удаления , если он не вызван одной из этих функций события (или другой функцией, вызываемой их):

InitializeSetup InitializeWizard CurStepChanged(ssInstall) InitializeUninstall CurUninstallStepChanged(usAppMutexCheck) CurUninstallStepChanged(usUninstall)

Объяснение поведения Abort ()

Причина, по которой функция Abort работает таким образом, заключается в том, что внутри Inno вызывает исключение EAbort, и это исключение специально обрабатывается циклом пользовательского интерфейса Delphi. Только в перечисленных функциях разработчики Inno либо добавили специальную обработку для EAbort (как в случае CurStepChanged(ssInstall) [ref2]), -

- или функция os не вызывается через цикл пользовательского интерфейса, как в случае InitializeSetup, который вызывается из основной программы в _ 9_, и любые прямые EAbort обрабатываются там конкретно в exceptblock.

Во всех других функциях событий Inno (например, NextButtonClick и т. Д.) EAbortexception достигнет основной программы / цикла пользовательского интерфейса и будет там проигнорирован.

Что приводит нас к следующему:

Поведение Abort () при запуске /SILENT (или /VERSILENT)

Когда Inno работает в автоматическом режиме, он не отображает пользовательский интерфейс формы мастера. Таким образом, прогресс "Wizard" / Inno не управляется циклом пользовательского интерфейса, а WizardForm.ClickThroughPages, который вызывается в том же блоке верхнего уровня try/except, что и, например, InitializeSetup. [ref3]

Из-за этого, если Inno вызывается незаметно, Abort() выйдет из настройки из каждой большинства [Code] функций, и список, указанный в документации для Abort, станет спорным, если настройка выполняется бежать молча.

Отмена

Чтобы отменить настройку, пользователь может нажать кнопку [Cancel] или [X] кнопку закрытия мастера настройки.

В этом случае Inno вызовет функцию обратного вызова CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean) (если определено ) и завершает настройку, возможно с помощью диалогового окна аварийного вывода:

Вызывается, когда пользователь нажимает кнопку «Отмена» или кнопку «Закрыть» окна. Параметр Cancel указывает, должна ли выполняться обычная обработка отмены; по умолчанию True. Параметр Confirm указывает, требуется ли «Выйти из настройки?» должно отображаться окно сообщения;

Пользователь [Code] может активировать механизм кнопки отмены, вызвав WizardForm.Close(), но это работает только в том случае, если программа установки отображает форму мастера, а не работает в автоматическом режиме.

Отменить Детали

WizardForm.Close [ref4], или щелчок по самой кнопке, в конечном итоге вызовет TMainForm.FormCloseQuery (в Main.pas), который вызовет CancelButtonClick обратные вызовы [ref5] и зависит от Confirm значение, либо вызовите TerminateApp(); напрямую, либо сначала вызовите вспомогательную функцию ExitSetupMsgBox(), которая отобразит окно сообщения для пользователя.



Сноски:

  • [ref1]: Для пользователей, не относящихся к delphi: если вы выполняете поиск по источникам в текстовом редакторе, убедитесь, что включены как минимум .iss .pas и .dpr
  • [ref2]: обработка исключений ssInstall находится по адресу issrc\Projects\Main.pas: TMainForm.Install через SetStep(ssInstall, False); и блок except в конце TMainForm.Install, где вызывается TerminateApp.
  • [ref3]: См. Setup.dpr вызов MainForm.InitializeWizard из Main.pas, который вызывает WizardForm.ClickThroughPages iff not InstallMode = imNormal, то есть в беззвучном случае.
  • [ref4]: WizardForm.Close() внутренние вызовы MainForm.Close() (см .: TWizardForm.FormClose)
  • [ref5]: На самом деле в Inno [Code] можно определить два типа обратных вызовов при нажатии кнопки: глобальный CancelButtonClickprocedure, и каждая страница мастера также имеет OnCancelButtonClick: TWizardPageCancelEvent, который может быть установлен.
person Martin Ba    schedule 07.05.2019

Где-то в разделе кода вы выполняете проверку. Верно? В результате этой проверки вы хотите выйти из установки. Для выполнения выхода поставьте строку:

PostMessage (WizardForm.Handle, $0010, 0, 0);  { quit setup, $0010=WM_CLOSE }

Надеюсь, это поможет

person Armand Colleye    schedule 21.01.2011
comment
Это можно легко обойти, используя беззвучный режим (/silent). - person Martin Prikryl; 30.09.2016