Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 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]

Нет программа в обоих случаях делает одно и тоже. Параметры ей на вход идут одинаковые. Результаты совпадают.
Только без контроля это происходит быстро а с контролем очень долго.




Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.04;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.75 MB
Время: 0.018 c
1-9137            LLL                   2002-02-16 20:04  2002.03.04  
Рамка для компонента


6-9253            Alligator             2001-12-18 08:18  2002.03.04  
Как создать-убрать сетевой диск вWin2000


6-9259            Yuri Btr              2001-12-18 10:36  2002.03.04  
Тест порта


3-9072            SGrigory              2002-02-06 12:00  2002.03.04  
Про глюки в индексах Paradox


1-9108            Igl                   2002-02-15 21:50  2002.03.04  
Как можно сделать эквалайзер?