![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
|||
|
|||
|
Запускаю из своего приложения стороннюю программу, с помощью ShellExecute как можно отловить закрытие приложения, чтобы продолжить выполнение кода.
Код:
procedure TForm1.ReadButClick(Sender: TObject);
var
s: TStringList;
begin
if ((AddrEdit1.Text = '') or (AddrEdit2.Text = '') or (AddrEdit3.Text = '')) then
begin
ShowMessage(' Вы не заполнили поля' + #13 + 'адресов концентраторов');
Exit;
end;
if PhoneEdit.Text = '+7' then
begin
ShowMessage('Вы не ввели номер телефона');
Exit;
end;
s := TStringList.Create;
s.LoadFromFile('Config.dat');
s.Text:=StringReplace(s.Text,'Phone',PhoneEdit.Text,[rfreplaceall]);
s.Text:=StringReplace(s.Text,'Addr1',AddrEdit1.Text,[rfreplaceall]);
s.Text:=StringReplace(s.Text,'Addr2',AddrEdit2.Text,[rfreplaceall]);
s.Text:=StringReplace(s.Text,'Addr3',AddrEdit3.Text,[rfreplaceall]);
s.SaveToFile('Root.dat');
FreeAndNil(s);
ShellExecute(Handle, 'open', 'BQuark.Rev.3.3.exe', 'Root.dat', nil, SW_SHOWNORMAL);
//Здесь должен идти код дальше после закрытия BQuark.
|
|
#2
|
|||
|
|||
|
Из ShellExecute - никак.
Тебе надо использовать CreateProcess. В этом случае ты получишь некоторый Handle, который можно проверять на валидность. Как только он освободится - значит приложение закрылось. |
|
#3
|
||||
|
||||
|
С одного старого проекта вырезка:
Код:
PThreadParams = ^TThreadParams;
TThreadParams = record // параметры, передаваемые в поток
Wnd: HWND; // окно, получающее сообщения из потока
Num: TChapterNumber; // номер запускаемой лекции
end;
function LectureThreadProc(p: Pointer): DWORD; stdcall; // функция потока
var
Buffer: array[0..1023] of Char;
tmp_filename, app_filename: string;
stream: TResourceStream;
lpHandles: array[0..1] of THandle;
fe_res: Integer;
SInfo: TStartupInfo;
PInfo: TProcessInformation;
begin
PostMessage(PThreadParams(p)^.Wnd, WM_LECTURE_THREAD, wLECTURE_RUN, 0); // отправляем окну сообщение о старте потока
tmp_filename := Format(LECTURE_FORMAT_FILE, [TMPpath, PThreadParams(p)^.Num]); // формируем имя временного файла
stream := TResourceStream.Create(HInstance, Format(LECTURE_FORMAT_RESOURCE, [PThreadParams(p)^.Num]), RT_RCDATA); // из ресурсов загружаем нужную лекцию
stream.SaveToFile(tmp_filename); // сохраняем в папу Temp
stream.Free;
fe_res := FindExecutable(PChar(tmp_filename), nil, Buffer); // ищем приложение отображения презентаций
if fe_res > 32 then // если нашли, то...
begin
app_filename := PChar(@Buffer);
FillChar(SInfo, SizeOf(SInfo), 0);
SInfo.wShowWindow := SW_SHOWNORMAL;
SInfo.cb := SizeOf(SInfo);
if CreateProcess(nil, PChar(Format('"%s" "%s"', [app_filename, tmp_filename])), nil, nil, False, NORMAL_PRIORITY_CLASS, nil, nil, SInfo, PInfo) then // создаем процесс с параметрами
begin
lpHandles[1] := PInfo.hProcess;
lpHandles[0] := LectureThreadCloseEvent;
// ожидаем завершение процесса или сигнала о принудительном завершении
if WaitForMultipleObjects(2, @lpHandles, False, INFINITE) = WAIT_OBJECT_0 then // принудительно завершаем процесс
TerminateProcess(PInfo.hProcess, 0);
// подчищаем за собой
CloseHandle(PInfo.hThread);
CloseHandle(PInfo.hProcess);
end
else // уведомляем окно об ошибке запуска процесса
PostMessage(PThreadParams(p)^.Wnd, WM_LECTURE_THREAD, wLECTURE_ERROR, lPROC_ERROR);
end
else
PostMessage(PThreadParams(p)^.Wnd, WM_LECTURE_THREAD, wLECTURE_ERROR, lAPP_ERROR); // окно об ошибке (не найдено приложение для отображения презентации)
Windows.DeleteFile(PChar(tmp_filename)); // удаляем временный файл
PostMessage(PThreadParams(p)^.Wnd, WM_LECTURE_THREAD, wLECTURE_CLOSE, 0); // уведомляем окно о завершении потока
Result := 0;
ExitThread(Result);
end;Запуск потока: Код:
procedure TMainForm._StartLecture(Number: TChapterNumber); var id: DWORD; begin LectureThreadParams.Wnd := Self.Handle; // задаем параметры потока LectureThreadParams.Num := Number; ResetEvent(LectureThreadCloseEvent); // сбрасываем событие принудительного завершения потока LectureThreadhandle := CreateThread(nil, 0, @LectureThreadProc, @LectureThreadParams, 0, id); // запускаем поток end; Программа запускала презентацию из ресурсов и ожидала завершения, отображая анимацию. Не забывайте подчищать за собой. |
|
#4
|
||||
|
||||
|
В принципе, если Вам не важно "подвиснет" Ваша программа или нет на время выполнения стороннего приложения, то можно обойтись и без потока. Просто адаптируйте код потока под вашу задачу и вставьте его "заместо" ShellExecute.
|
|
#5
|
|||
|
|||
|
Спасибо решил. Код нашел на одном из сайтов.
Код:
procedure ExecuteWait(const sProgramm: string; const sParams: string = ''; fHide: Boolean = false);
var
ShExecInfo: TShellExecuteInfo;
begin
FillChar(ShExecInfo, sizeof(ShExecInfo), 0);
with ShExecInfo do
begin
cbSize := sizeof(ShExecInfo);
fMask := SEE_MASK_NOCLOSEPROCESS;
lpFile := PChar(sProgramm);
lpParameters := PChar(sParams);
lpVerb := 'open';
if (not fHide) then
nShow := SW_SHOW
else
nShow := SW_HIDE
end;
if (ShellExecuteEx(@ShExecInfo) and (ShExecInfo.hProcess <> 0)) then
try
WaitForSingleObject(ShExecInfo.hProcess, INFINITE)
finally
CloseHandle(ShExecInfo.hProcess);
end;
end;
Вызываю так Код:
ExecuteWait('BQuark.Rev.3.3.exe', 'Root.dat', true); |