Inno Setup - правильная остановка службы до копирования файла

Наш процесс установки включает службу Windows, которая устанавливается, если наше программное обеспечение настроено для установки в качестве сервера (по сравнению с установкой клиента). Я добавил библиотеку сервисов, чтобы иметь возможность управлять службами, а затем в файлах добавлял обработчики для событий BeforeInstall и AfterInstall...

[Files]
Source: "MyService.exe"; DestDir: "{app}"; Check: IsServer; BeforeInstall: BeforeServiceInstall('MyServiceName', 'MyService.exe'); AfterInstall: AfterServiceInstall('MyServiceName', 'MyService.exe')

procedure BeforeServiceInstall(SvcName, FileName: String);
var
  S: Longword;
begin
  //If service is installed, it needs to be stopped
  if ServiceExists(SvcName) then begin
    S:= SimpleQueryService(SvcName);
    if S <> SERVICE_STOPPED then begin
      SimpleStopService(SvcName, True, True);
    end;
  end;
end;

procedure AfterServiceInstall(SvcName, FileName: String);
begin
  //If service is not installed, it needs to be installed now
  if not ServiceExists(SvcName) then begin
    if SimpleCreateService(SvcName, 'My Service Name', ExpandConstant('{app}')+'\' + FileName, SERVICE_AUTO_START, '', '', False, True) then begin
      //Service successfully installed
      SimpleStartService(SvcName, True, True);
    end else begin
      //Service failed to install

    end;
  end;
end;

При первоначальной установке службы (она еще не существует и в настоящее время не запущена) установка/запуск этой службы работает нормально. Однако при запуске этого установщика при существующей установке (обновление) установщик останавливается, когда распознает, что эта служба запущена, и предлагает завершить процесс (прежде чем он вызывает обработчик BeforeServiceInstall())...

Prompt message

Как предотвратить появление этой подсказки для служб? Я не требую перезагрузки и все равно хочу, чтобы это приглашение отображалось для всех других файлов.

Ответ 1

В настоящее время нет прямого способа исключить файл из проверки, если он используется. Вы можете отключить этот контроль глобально (установив CloseApplications значение директивы no), которое я бы не рекомендовал. Или вы можете установить фильтр для файлов, который будет проверен (в директиве CloseApplicationsFilter), которая для вас может потребоваться, например. чтобы просмотреть все файлы, кроме исполняемого файла службы, который трудно поддерживать.

Вы также можете указать все файлы, которые нужно проверить, указав фильтр, который не будет соответствовать ни одному из ваших файлов, и добавив их из RegisterExtraCloseApplicationsResources то же самое, что и в случае с указанной директивой.

Я бы предложил остановить службу из PrepareToInstall метода событий. Его ссылка явно предлагает это (подчеркнуто мной):

Вы можете использовать эту функцию для обнаружения и установки отсутствующих предварительные условия и / или закрыть любое приложение, которое обновляться.

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

Для вашего script это просто означает переместить код из вашей процедуры BeforeServiceInstall в метод PrepareToInstall и удалить параметр BeforeInstall из записи.