#delphi #winapi
Запускаю программу Delphi, открывается форма, нажимаю на кнопку, происходит выполнение команды через cmd.exe. Мне нужно дождаться завершения ее выполнения. И пока команда не выполниться - у меня сама форма (программа) Delphi находится в замороженном состоянии. Мне нужно, чтобы сама форма (программа) Delphi - не была в замороженном состоянии. То есть её можно было передвигать. Как сделать, чтобы окно программы Delphi в процессе выполнения CMD.exe не застывало? То есть обработка в отдельном потоке. var LCmd: string; LInfo: TStartupInfo; LPI: TProcessInformation; begin // Заполняем структуры LCmd := 'cmd.exe ' + SPar; FillChar(LInfo, SizeOf(LInfo), 0); LInfo.cb := SizeOf(LInfo); LInfo.dwFlags := STARTF_USESHOWWINDOW; LInfo.wShowWindow := SW_HIDE; // Запускаем программу Win32Check(CreateProcess( 'cmd.exe', // lpApplicationName, PChar(LCmd), // lpCommandLine, nil, // lpProcessAttributes, nil, // lpThreadAttributes, False, // bInheritHandles, CREATE_NO_WINDOW, // dwCreationFlags, nil, // lpEnvironment, nil, // lpCurrentDirectory, LInfo, // lpStartupInfo, LPI // lpProcessInformation )); try // Закрываем хендл главного потока (он нам не нужен) CloseHandle(LPI.hThread); // Ждем завершения процесса Win32Check(WaitForSingleObject(LPI.hProcess, INFINITE) <> WAIT_FAILED); finally // Закрываем хендл процесса CloseHandle(LPI.hProcess); end; ShowMessage('Программа завершена'); end;
Ответы
Ответ 1
Чтобы дождаться завершения программы не замораживая интерфейс, нужно делать ожидание в отдельном потоке. А потом уведомить основной поток о завершении операции type TWaitThread = class(TThread) private FWaitHandle: THandle; protected procedure Execute; override; public constructor Create(ACreateSuspended: Boolean; AWaitHandle: THandle); destructor Destroy; override; end; constructor TWaitThread.Create(ACreateSuspended: Boolean; AWaitHandle: THandle); begin inherited Create(ACreateSuspended); FWaitHandle := AWaitHandle; end; destructor TWaitThread.Destroy; begin CloseHandle(FWaitHandle); inherited Destroy; end; procedure TWaitThread.Execute; begin // Ждем завершения процессса Win32Check(WaitForSingleObject(FWaitHandle, INFINITE) <> WAIT_FAILED); end; // И использование var .......... LPI: TProcessInformation; LThread: TThread; begin .......... Win32Check(CreateProcess(......, LPI)); CloseHandle(LPI.hThread); // Создаем ждущий поток LThread := TWaitThread.Create(True, LPI.hProcess); // Поток удалится при завершении LThread.FreeOnTerminate := True; // После завершения вызвать процедуру EndWait LThread.OnTerminate := EndWait; // Запускаем поток LThread.Start; end; procedure TForm1.EndWait(Sender: TObject); begin ShowMessage('Программа завершена'); end;
Комментариев нет:
Отправить комментарий