Форум: "Начинающим";
Текущий архив: 2008.12.07;
Скачать: [xml.tar.bz2];
ВнизЗапуск приложения и ождание завершения, при этом форма активна Найти похожие ветки
← →
cruiser © (2008-10-22 22:46) [0]Уважаемые Мастера! Столкнулся с проблемкой. Вот код от которого я отталкиваюсь:
function RunAny(CommandLine: string; Memo1: TMemo): boolean;
var
I: byte;
S: string;
Flag: boolean;
tRead, cWrite, dwRead, dwAvail: cardinal;
SA: TSecurityAttributes;
PI: TProcessInformation;
SI: TStartupInfo;
begin
Result:=False;
SA.nLength:=SizeOf(SECURITY_ATTRIBUTES);
SA.bInheritHandle:=True;
SA.lpSecurityDescriptor:=nil;
if not CreatePipe(tRead, cWrite, @SA, 0) then Exit;
ZeroMemory(@SI, SizeOf(TStartupInfo));
SI.cb:=SizeOf(TStartupInfo);
SI.dwFlags:=STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
SI.wShowWindow:=SW_HIDE;
SI.hStdOutput:=cWrite;
if CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil, nil, SI, PI) then begin
CloseHandle(PI.hProcess);
CloseHandle(PI.hThread);
Memo1.Clear;
Flag:=True;
while Flag do begin
for I:=0 to 9 do begin
PeekNamedPipe(tRead, nil, 0, nil, @dwAvail, nil);
if (dwAvail>0) then begin
Flag:=True;
Break;
end
else Flag:=False;
if CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil, nil, SI, PI) then
begin
WaitForSingleObject(PI.hProcess, 100);
CloseHandle(PI.hProcess);
end;
end;
if dwAvail>0 then begin
SetLength(S, dwAvail);
ReadFile(tRead, PChar(S)^, Length(S), dwRead, Nil);
OemToChar(PChar(S), PChar(S));
Memo1.Lines.Add(S);
Application.ProcessMessages;
Result:=True;
end; // if dwAvail
end; // while Flag
end; // if CreateProcess
CloseHandle(cWrite);
CloseHandle(tRead);
end;
Мне не нужно считывание вывода приложения в консоль, а только нужно что бы запустив из моей программы некое приложение, дождаться его завершения и вывести мессагу что приложение завершило действие. При этом необходимо дальше работать с главной формой и с её элементами. Какой код можно на основе этого сделать без всего лишнего?
← →
Правильный$Вася (2008-10-22 23:08) [1]
> При этом необходимо дальше работать с главной формой и
> с её элементами.
в запущенном или запускающем приложении?
> WaitForSingleObject(PI.hProcess, 100);
if( WaitForSingleObject( hProcInfo.hProcess, INFINITE ) = WAIT_FAILED ) then
?
← →
cruiser © (2008-10-24 12:01) [2]Извините за адрежку с ответом - в запускаемом, т.е. запустили приложение, а сами (наша программа) должна спокойно продолжать отвечать на клики, выбор элементов и т.п., т.е. на любые действия со стороны пользователя. Сейчас получается какой-то "висяк" - наше приложение зависает, пока не отработает запущенное.
← →
Правильный$Вася (2008-10-24 12:12) [3]
> в запускаемом, т.е. запустили приложение, а сами (наша программа)
> должна спокойно продолжать отвечать на клики
это запускающее, а не запускаемое
решается организацией запуска другого приложения в отдельной нити
← →
cruiser © (2008-10-24 13:01) [4]Да, я ошибся. Торопился с написанием ответа. Т.е. тот код что приведен выше не подходит как исходная точка от которой отталкиваться?
← →
{RASkov} © (2008-10-24 13:05) [5]> [4] cruiser © (24.10.08 13:01)
> Т.е. тот код что приведен выше не подходит как исходная
> точка от которой отталкиваться?
К чему этот вопрос? В [3] вник или как?
В доп потоке делаешь запуск стороннего приложения и в нем ждешь окончания его работы, а основной поток работает....
← →
cruiser © (2008-10-26 17:51) [6]Спасибо. Разобрался. Сделал так:
procedure TForm1.Button1Click(Sender: TObject);
begin
NewThread:=TNewThread.Create(true);
NewThread.FreeOnTerminate:=true;
NewThread.Priority:=tpLower;
NewThread.Resume;
end;
procedure TNewThread.Execute;
begin
CriticalSection.Enter;
ExecAndWait (fp+"rar.exe", s, windows.SW_SHOWNORMAL );
CriticalSection.Leave;
end;
Но при закртыии программы (запускающей) выдается ошибка: Access violation....
Я так понимаю, что это из-за того, что не завершен созданный поток? Подскажите как мне программно завершать правильно поток при закрытии запускающего приложения? Т.е. мне надо при закрытии моего приложения или по нажатию кнопки на форме завершить запущенное приложение.
← →
Leonid Troyanovsky © (2008-10-27 14:40) [7]
> cruiser © (26.10.08 17:51) [6]
> Но при закртыии программы (запускающей) выдается ошибка:
> Access violation....
> Я так понимаю, что это из-за того, что не завершен созданный
> поток?
Мы думаем, что из-за того, что не создана CriticalSection.
Кста, а зачем она здесь?
> Подскажите как мне программно завершать правильно поток
> при закрытии запускающего приложения?
Правильно - никак. Поток завершится при выходе из функции потока.
> Т.е. мне надо при закрытии моего приложения или по нажатию
> кнопки на форме завершить запущенное приложение.
TerminateProcess(PI.hProcess, 0)
--
Regards, LVT.
← →
cruiser © (2008-10-27 15:39) [8]
> Мы думаем, что из-за того, что не создана CriticalSection.
>
> Кста, а зачем она здесь?
она создается в Tform.create. Попробую убрать из кода.
> TerminateProcess(PI.hProcess, 0)
Дело в том, что PI.hProcess определяется только в функии ExecAndWait. А как мне этот параметр сделать доступным для всей формы?
← →
clickmaker © (2008-10-27 15:44) [9]> А как мне этот параметр сделать доступным для всей формы?
а сам-то как думаешь?
FProcessHandle := pi.hProcess
← →
Правильный$Вася (2008-10-27 16:03) [10]
> PI.hProcess определяется только в функии ExecAndWait
сделай его методом класса формы, например
← →
Leonid Troyanovsky © (2008-10-27 16:04) [11]
> cruiser © (27.10.08 15:39) [8]
> Дело в том, что PI.hProcess определяется только в функии
> ExecAndWait. А как мне этот параметр сделать доступным для
> всей формы?
Например, сделай его полем формы, а ExecAndWait - ее методом.
--
Regards, LVT.
← →
cruiser © (2008-10-27 17:16) [12]
> Например, сделай его полем формы, а ExecAndWait - ее методом.
> > PI.hProcess определяется только в функии ExecAndWait
>
> сделай его методом класса формы, например
А можно подробнее? Хотя бы кусочек кода как это сделать? :)
← →
Правильный$Вася (2008-10-27 17:22) [13]
> Хотя бы кусочек кода как это сделать?
TForm1.ExecAndWait
← →
cruiser © (2008-10-27 17:36) [14]Т.е. сделать процедурой TForm1? Правильно я понял?
← →
cruiser © (2008-10-27 17:37) [15]имел в виду процедурой класса TForm1
← →
Правильный$Вася (2008-10-27 17:45) [16]
> процедурой класса TForm1
методом, причем у тебя вроде ж как функция, а не процедура
← →
cruiser © (2008-10-27 18:00) [17]Да - сейчас это функция. Т.е. при описании в разделе type её нужно указать? Извините, просто немного не могу понять как должен выглядить код.
← →
clickmaker © (2008-10-27 18:02) [18]> Извините, просто немного не могу понять как должен выглядить
> код.
а букварь почитать, прежде чем бездумно чужой код копипастить?
← →
cruiser © (2008-10-27 22:10) [19]Всем большое спасибо. Ваши советы помогли. Сделал так, как и рекомендовали:
1. Сделал функцию Execandwait методом класса TForm1
2. Параметр ProcInfo: TProcessInformation объявил в разделе private класса и запускаемое приложение теперь закрывается по
TerminateProcess(ProcInfo.hProcess, 0)
← →
Leonid Troyanovsky © (2008-10-27 22:16) [20]
> cruiser © (27.10.08 22:10) [19]
> private класса и запускаемое приложение теперь закрывается
> по
> TerminateProcess(ProcInfo.hProcess, 0)
Надеемся, что про UINT uExitCode читано, как, впрочем,
и все описалово TerminateProcess.
--
Regards, LVT.
← →
cruiser © (2008-10-27 22:23) [21]Да. Почитал на просторах интернета http://vsokovikov.narod.ru/New_MSDN_API/Process_thread/fn_terminateprocess.htm
Думаю, что для моей задачи вполне можно испольовать данную функцию как TerminateProcess
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2008.12.07;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.005 c