Отказ от синхронизации: использование ShellExecute против CreateProcess в Delphi
Введение
В процессе разработки программ на Delphi часто возникает необходимость запускать внешние программы. Для этого существует несколько способов, одним из которых является использование функции ShellExecute. Однако, при работе с внешними программами, важно обеспечить их корректное завершение перед дальнейшими действиями, например, проверкой созданных файлов. В этом контексте возникает проблема синхронизации, которая решается с помощью функции CreateProcess.
Проблема
При использовании функции ShellExecute для запуска внешних программ, не всегда удается дождаться их завершения, что может привести к ошибкам в работе программы, особенно если проверка на создание файлов выполняется слишком рано.
Пример кода с ShellExecute
uses
Forms, ShellAPI, SysConst, SysUtils;
procedure Pdf2Text(const fFileName: string; const Lines: TStrings);
var
H: HWND;
PdfToTextPathName: string;
ReturnValue: Integer;
TxtFileName: string;
begin
H := 0;
PdfToTextPathName := ExtractFilePath(Application.ExeName) + 'pdftotext.exe'; // полный путь
if FileExists(PdfToTextPathName) then
begin
ReturnValue := ShellExecute(0, 'open', PWideChar(PdfToTextPathName), PWideChar(fFileName), nil, SW_SHOWNORMAL);
if ReturnValue <= 32 then
RaiseLastOsError();
// код ниже этой строки приведет к сбою, если pdftotext.exe не завершится достаточно быстро; вы должны дождаться завершения pdftotext.exe
TxtFileName := ChangeFileExt(fFileName, '.txt');
if FileExists(TxtFileName) then
Lines.LoadFromFile(TxtFileName)
else
raise EFileNotFoundException.CreateRes(@SFileNotFound);
end;
end;
Подтвержденный ответ
Использование ShellExecute не позволяет получать достаточную информацию для ожидания завершения запущенной программы. В качестве альтернативы следует использовать функцию CreateProcess, которая позволяет контролировать процесс и дожидаться его завершения.
Альтернативный ответ
В некоторых случаях проблема может быть решена простым добавлением полного пути к исполняемому файлу, что позволит ShellExecute корректно его найти и запустить.
Пример кода с добавлением полного пути
PdfToTextPathName := ExtractFilePath(Application.ExeName) + 'pdftotext.exe'; // полный путь
Важные замечания
Необходимо учитывать возвращаемое значение функций API, чтобы своевременно выявлять ошибки.
Важно использовать полный путь к исполняемому файлу, чтобы избежать проблем с поиском программы в текущем рабочем каталоге.
Решение проблемы
Для корректной синхронизации с внешними программами рекомендуется использовать функцию CreateProcess. В интернете есть множество примеров, как это можно сделать. Например, можно ознакомиться с обсуждением на Stack Overflow: Как дождаться завершения командной строки программы?
Заключение
При разработке в Delphi, для запуска внешних программ и ожидания их завершения, предпочтительнее использовать CreateProcess. Это позволит избежать проблем, связанных с синхронизацией и обеспечит более надежную работу вашего приложения.
Эта статья является кратким обзором проблемы, связанной с использованием функции ShellExecute в Delphi для запуска внешних программ и необходимости синхронизации с их завершением. Представлены примеры кода и рекомендации по решению проблемы.
Контекст: Проблема синхронизации при использовании `ShellExecute` для запуска внешних программ в Delphi и необходимость использования `CreateProcess` для контроля за их завершением.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.