Это описание того, что я сегодня возился с 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
обрабатываются там конкретно в except
block.
Во всех других функциях событий Inno (например, NextButtonClick
и т. Д.) EAbort
exception достигнет основной программы / цикла пользовательского интерфейса и будет там проигнорирован.
Что приводит нас к следующему:
Поведение 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]
можно определить два типа обратных вызовов при нажатии кнопки: глобальный CancelButtonClick
procedure, и каждая страница мастера также имеет OnCancelButtonClick: TWizardPageCancelEvent
, который может быть установлен.
person
Martin Ba
schedule
07.05.2019