Вопрос разработчика связан с использованием контекстного меню в Delphi и ожиданием завершения процессов, запущенных через это меню. Поскольку не все действия, предлагаемые контекстным меню, запускают новый процесс, стандартный подход с ожиданием завершения процесса через ShellExecuteEx не подходит. В качестве альтернативы предлагается использовать мониторинг изменений файлов.
Вопрос, с которым столкнулся разработчик, связан с необходимостью ожидания завершения процессов, запущенных через контекстное меню в Delphi. Это может быть необходимо, например, для обновления списка файлов после их изменения или удаления. Однако, стандартный подход, использующий потоки и ожидание завершения процесса с помощью ShellExecuteEx, не всегда применим, так как некоторые действия не запускают отдельные процессы.
Использование потоков для ожидания процесса
Разработчик уже реализовал использование потоков для ожидания завершения процесса, запущенного на открытие файла с помощью ShellExecuteEx. Пример кода, который он использовал, выглядит следующим образом:
TNotifyThread = class(TThread)
private
FFileName: string;
FFileAge: TDateTime;
public
constructor Create(const FileName: string; OnClosed: TNotifyEvent); overload;
procedure Execute; override;
property FileName: String read FFileName;
property FileAge: TDateTime read FFileAge;
end;
constructor TNotifyThread.Create(const FileName: string; OnClosed: TNotifyEvent);
begin
inherited Create(True);
// ...
Resume;
end;
procedure TNotifyThread.Execute;
var
se: SHELLEXECUTEINFO;
begin
with se do
begin
cbSize := SizeOf(SHELLEXECUTEINFO);
fMask := SEE_MASK_INVOKEIDLIST or SEE_MASK_NOCLOSEPROCESS or SEE_MASK_NOASYNC;
lpVerb := PChar('open');
// ...
end;
if ShellExecuteEx(@se) then
begin
WaitForSingleObject(se.hProcess, INFINITE);
if se.hProcess <> 0 then
CloseHandle(se.hProcess);
end;
end;
Этот код запускает процесс открытия файла и ожидает его завершения, что позволяет использовать событие TThread.OnTerminate для обновления изменений в файле после его закрытия пользователем.
Проблема с ожиданием команд контекстного меню
Разработчик хочет расширить функционал, чтобы ожидать завершения действий, выбранных пользователем через контекстное меню, например, 'Свойства', 'Удалить' и т.д. Однако, CMINVOKECOMMANDINFO не возвращает обработчик процесса, как SHELLEXECUTEINFO, и поэтому использование аналогичного подхода не представляется возможным.
Альтернативное решение: мониторинг изменений файлов
В качестве альтернативы, разработчик решил использовать мониторинг изменений файлов. Для этого он использовал компонент TJvChangeNotify из JVCL, чтобы отслеживать изменения в папке временных файлов Windows. Список отслеживаемых файлов хранится в TDictionary<FileName, LastWrite>.
Пример обработчика события изменения файлов:
procedure TFileChangeMonitor.ChangeNotifyEvent(Sender: TObject; Dir: string;
Actions: TJvChangeActions);
var
LFile: TPair<String, TDateTime>;
LSearchRec: TSearchRec;
LFoundErrorCode: Integer;
begin
for LFile in FMonitoredFiles do
begin
LFoundErrorCode := FindFirst(LFile.Key, faAnyFile, LSearchRec);
try
if LFoundErrorCode = NOERROR then
begin
if LSearchRec.TimeStamp > LFile.Value then
begin
// Обработка изменений файла
// ...
// Обновление времени последнего изменения файла
FMonitoredFiles.AddOrSetValue(LFile.Key, LSearchRec.TimeStamp);
end;
end
else if (LFoundErrorCode = ERROR_FILE_NOT_FOUND) then
begin
// Обработка удаления файла
// ...
// Удаление файла из списка отслеживаемых
FMonitoredFiles.Remove(LFile.Key);
end;
finally
System.SysUtils.FindClose(LSearchRec);
end;
end;
end;
Этот подход позволяет отслеживать изменения и удаления файлов, не требуя ожидания завершения процессов, что делает его более надежным и универсальным решением.
Заключение
Использование потоков для ожидания процесса открытия файла является эффективным, но не может быть применено для команд контекстного меню. В качестве альтернативы, мониторинг изменений файлов с помощью TJvChangeNotify предоставляет более гибкое и надежное решение для обновления списка файлов в приложении.
Разработчик в Delphi столкнулся с задачей ожидания завершения процессов, запущенных через контекстное меню, и рассматривает возможность использования мониторинга изменений файлов вместо ожидания завершения процесса через `ShellExecute
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS