Форум: "Основная";
Текущий архив: 2002.03.04;
Скачать: [xml.tar.bz2];
ВнизКак узнать код возврата Найти похожие ветки
← →
fag2000@ok.ru (2002-02-13 13:44) [0]Привет всем.
У меня следующая проблема:
Мне надо запустить чужую прогу из своей дождаться её завершения и получить её код возврата.
function MyFunction():integer;
var
result:Cardinal;
state:boolean;
ExecString,ParamString:string;
InstanceID: Cardinal;
Start_Info:STARTUPINFO;
Proc_Inform:PROCESS_INFORMATION;
begin
ExecString:="c:\1.exe";//Путь приложения
ParamString:="par1=1"//параметры;
GetStartupInfo(Start_Info);
CreateProcess(Nil, PChar (ExecString+ParamString) ,NIL,NIL,false,CREATE_NEW_PROCESS_GROUP,NIL,NIL,Start_Info,Proc_Inform);
//Запускается и работает внешнее приложение без проблем
repeat //В этом цикле ожидается завершение приложения но к сожалению после завершения выход из цикла не происходит
Как бы это победить?
state:=GetExitCodeProcess(Proc_Inform.hProcess,result);
until state=false;
memo1.Lines.Add(IntToStr(result));
end;
Заранее благодарен
← →
Виктор Щербаков (2002-02-13 13:48) [1]WaitForSingleObject.
А цикл убери.
← →
fag2000@ok.ru (2002-02-13 14:25) [2]Попробовал я с WaitForSingleObject
Ничего хорошего. Внешнее приложение запускается очень долго (около 1 мин а без WaitForSingleObject меньше секунды) а код возврата получить не удается. (Возвращаемое значение 0 а должно быть 1).
← →
Виктор Щербаков (2002-02-13 14:35) [3]to fag2000@ok.ru ©
> Ничего хорошего. Внешнее приложение запускается очень долго
> (около 1 мин а без WaitForSingleObject меньше секунды)
Просто фантастика какая-то! Приведи код.
← →
Набережных С. (2002-02-13 14:40) [4]GetExitCodeProcess вернет ноль в случае сбоя. А раз нет ошибки, то и цикл не завершается.
Нужноuntil result <> STILL_ACTIVE{$103};
← →
fag2000@ok.ru (2002-02-13 14:49) [5]
procedure TForm1.Button1Click(Sender: TObject);
var
result:Cardinal;
state:boolean;
ExecString,ParamString:string;
InstanceID: Cardinal;
Start_Info:STARTUPINFO;
Proc_Inform:PROCESS_INFORMATION;
begin
ExecString:="c:\1.exe ";
ParamString:="par1=1";
GetStartupInfo(Start_Info);
CreateProcess(Nil,PChar(ExecString+ParamString),NIL,NIL,false,CREATE_NEW_PROCESS_GROUP,NIL,NIL,Start_Info,Proc_Inform);
result:=WaitForSingleObject(Proc_Inform.hProcess,INFINITE);//
memo1.Lines.Add(IntToStr(result));
end;
← →
Юрий Зотов (M) (2002-02-13 15:05) [6]Тяжелый случай. Но даже при таком количестве ляп F1 обычно помогает. Например, с чего Вы взяли, что WaitForSingleObject
возвращает код завершения? Разве в SDK ЭТО написано?
procedure TForm1.Button1Click(Sender: TObject);
var
result: Cardinal;
// state: boolean; // для чего?
ExecString, ParamString: string;
// InstanceID: Cardinal; // для чего?
Start_Info: TSTARTUPINFO;
Proc_Inform: TPROCESSINFORMATION;
begin
ExecString := "c:\1.exe ";
ParamString := "par1=1";
ZeroMemory(Start_Info, SizeOf(Start_Info));
Start_Info.cb := SizeOf(Start_Info);
if CreateProcess(Nil, PChar(ExecString + ParamString), NIL, NIL, false, 0, NIL, NIL, Start_Info, Proc_Inform) then
begin
CloseHandle(Proc_Inform.hThread);
WaitForSingleObject(Proc_Inform.hProcess, INFINITE);
GetExitCodeProcess(Proc_Inform.hProcess, Result);
CloseHandle(Proc_Inform.hProcess);
memo1.Lines.Add(IntToStr(result));
end
else memo1.Lines.Add("Ошибка запуска");
end;
← →
fag2000@ok.ru (2002-02-13 15:22) [7]Спасибо, код теперь возвращается верно . Однако все равно внешнее приложение стартует и работает очень медленно. Как можно ускорить его запуск и работу работу?
← →
Юрий Зотов (M) (2002-02-13 15:37) [8]Оно не СТАРТУЕТ медленно и не РАБОТАЕТ медленно. Оно стартует, как обычно и работает столько, сколько ему нужно, чтобы выполнить свою задачу. КАК это можно ускорить, подумайте сами?
А Ваша программа стоит и ждет, пока запущенное им приложение не завершится (поэтому, наверное, Вы и решили что все замедлилось). Но Вы же хотите получить код завершения - а КАК можно его получить, не дождавшись этого самого завершения? Никак, конечно.
Все что здесь можно сделать - это поместить этот код в метод Execute дополнительного потока. Тогда ожидать будет этот поток, а основной поток Вашей программы будет продолжать свою работу. Но код завершения Вы в любом случае сможете получить ТОЛЬКО после самого завершения.
← →
fag2000@ok.ru (2002-02-13 16:09) [9]Вы не совсем верно меня поняли.
При использовании следующего кода (без ожидания завершения)
procedure TForm1.Button1Click(Sender: TObject);
var
result: Cardinal;
ExecString, ParamString: string;
Start_Info: TSTARTUPINFO;
Proc_Inform: TPROCESSINFORMATION;
begin
ExecString:="c:\1.exe ";
ParamString:="par1=1";
GetStartupInfo(Start_Info);
if CreateProcess(Nil, PChar(ExecString + ParamString), NIL, NIL, false, 0, NIL, NIL, Start_Info, Proc_Inform) then
begin
end
else memo1.Lines.Add("Error");
end;
время до появления окна внешнего приложения с результатами его работы около 1 секуды.
Если ждать завершения:
procedure TForm1.Button1Click(Sender: TObject);
var
result: Cardinal;
ExecString, ParamString: string;
Start_Info: TSTARTUPINFO;
Proc_Inform: TPROCESSINFORMATION;
begin
ExecString:="c:\1.exe ";
ParamString:="par1=1";
GetStartupInfo(Start_Info);
if CreateProcess(Nil, PChar(ExecString + ParamString), NIL, NIL, false, 0, NIL, NIL, Start_Info, Proc_Inform) then
begin
CloseHandle(Proc_Inform.hThread);
WaitForSingleObject(Proc_Inform.hProcess, INFINITE);
GetExitCodeProcess(Proc_Inform.hProcess, Result);
CloseHandle(Proc_Inform.hProcess);
memo1.Lines.Add(IntToStr(result));
end
else memo1.Lines.Add("Error");
end;
До появления результатовработы внешнегоприложения проходит 40 секунд. При этом процессор не занят 39 секунд. Потом видимо внешнее приложение запускается (процессор полностью загружен) и отображается результат.
← →
Юрий Зотов (M) (2002-02-13 16:14) [10]Фантастика. В чем дело, не знаю, но уж точно не в этом коде.
А что делает программа 1.exe?
← →
fag2000@ok.ru (2002-02-13 16:24) [11]Преобразует текстовый файл в формат rtf, запихивает rtf файл в архив и показывает его из архива в MSWORD с помощью ZipTv.
← →
Набережных С. (2002-02-13 16:33) [12]>Юрий Зотов (M) (13.02.02 15:37)
Все-же можно и без потока и WaitFor...
.....
result:=STILL_ACTIVE;
while result = STILL_ACTIVE do
begin
Application.ProcessMessages;
if Application.Terminated then break;
GetExitCodeProcess(Proc_Inform.hProcess,result);
end;
.....
← →
fag2000@ok.ru (2002-02-13 17:35) [13]Та же ситуация только теперь процессор занят все 40 секунд.
А код определяется верно.
← →
Юрий Зотов (M) (2002-02-13 18:00) [14]> Преобразует текстовый файл в формат rtf, запихивает rtf файл в архив...
Похоже, вот это 40 секунд и длится.
← →
fag2000@ok.ru (2002-02-14 16:03) [15]Нет программа в обоих случаях делает одно и тоже. Параметры ей на вход идут одинаковые. Результаты совпадают.
Только без контроля это происходит быстро а с контролем очень долго.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.03.04;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.006 c