Вопрос, поднятый в запросе, заключается в необходимости синхронизации работы двух приложений, написанных на Delphi 5. Основная программа program.exe запускается без прав администратора и без манифеста, в то время как updater.exe требует прав администратора для записи в папку с программой. Задача состоит в том, чтобы запустить updater.exe и дождаться, пока program.exe закроется.
Проблема
Исходный код, предоставленный в запросе, демонстрирует две попытки решения проблемы: использование CreateProcess и ShellExecuteEx. Однако оба подхода не приводят к желаемому результату, особенно когда updater.exe требует прав администратора.
Решение
Для решения этой задачи можно использовать механизм событий Windows. Создается манипулируемое событие, которое program.exe инициализирует в несигнализированном состоянии. После этого program.exe запускает updater.exe и ожидает сигнала от этого события. updater.exe, в свою очередь, сигнализирует событие после того, как убедится, что program.exe закрыт (например, проверяя процесс с помощью его идентификатора).
Пример кода на Object Pascal (Delphi)
program.exe
procedure TForm1.Button1Click(Sender: TObject);
var
Event: THandle;
begin
// Создание манипулируемого события, несигнализированного
Event := CreateEvent(nil, True, False, 'MyUniqueEvent');
// Запуск updater.exe с правами администратора
// Здесь должен быть ваш код запуска updater.exe, возможно с использованием ShellExecuteEx
// ...
// Ожидание сигнала от события
WaitForSingleObject(Event, INFINITE);
// Закрытие обработчика события
CloseHandle(Event);
end;
updater.exe
procedure TForm1.FormCreate(Sender: TObject);
var
Event: THandle;
PID: Integer;
begin
// Получение идентификатора процесса основной программы
PID := StrToIntDef(ParamStr(1), 0);
if PID > 0 then
begin
// Проверка, что событие уже существует
Event := OpenEvent(SYNCHONIZE, FALSE, 'MyUniqueEvent');
if Event <> 0 then
// Удаление обработчика события, так как в коде запроса он не требуется
CloseHandle(Event);
// Создание нового события, так как это безопасный способ получить уже существующее
// событие через его имя в случая, если это имя не уникально по всему компьютеру
// Вместо этого, можно было бы использовать открытие события с указанием прав доступа
Event := CreateEvent(nil, TRUE, FALSE, 'MyUniqueEvent');
// Проверка на ошибки создания события
if Event = 0 then
RaiseLastOSError;
// Сигнализирование события после выполнения работы
SetEvent(Event);
// Закрытие обработчика события
CloseHandle(Event);
// Выполнение основных задач (обновление и т.д.)
// ...
end;
end;
Важные замечания
Важно не забыть закрыть обработчики событий после их использования, чтобы избежать утечек ресурсов.
Перед запуском updater.exe убедитесь, что у вас нет ошибок проверки прав доступа и создания процессов.
В примере кода не приведены ошибки проверки, которые должны быть добавлены в окончательную версию кода.
Также стоит учесть, что приведенный выше код - это упрощенный пример, и его нужно адаптировать для реального приложения, учитывая все необходимые проверки и условия.
Используя данный метод, вы сможете синхронизировать завершение работы основной программы с запуском процесса обновления.
Синхронизация процессов: использование механизма событий Windows для ожидания закрытия основной программы перед её обновлением.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.