![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как узнать код возврата [D6, Win2k]
fag2000@ok.ru © (2002-02-13 13:44:00)Привет всем.
У меня следующая проблема:
Мне надо запустить чужую прогу из своей дождаться её завершения и получить её код возврата.
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;
Заранее благодарен
fag2000@ok.ru (2002-02-14 16:03:00) [1]Нет программа в обоих случаях делает одно и тоже. Параметры ей на вход идут одинаковые. Результаты совпадают.
Только без контроля это происходит быстро а с контролем очень долго.
Юрий Зотов (M) (2002-02-13 18:00:00) [2]> Преобразует текстовый файл в формат rtf, запихивает rtf файл в архив...
Похоже, вот это 40 секунд и длится.
fag2000@ok.ru (2002-02-13 17:35:00) [3]Та же ситуация только теперь процессор занят все 40 секунд.
А код определяется верно.
Набережных С. (2002-02-13 16:33:00) [4]>Юрий Зотов (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 16:24:00) [5]Преобразует текстовый файл в формат rtf, запихивает rtf файл в архив и показывает его из архива в MSWORD с помощью ZipTv.
Юрий Зотов (M) (2002-02-13 16:14:00) [6]Фантастика. В чем дело, не знаю, но уж точно не в этом коде.
А что делает программа 1.exe?
fag2000@ok.ru (2002-02-13 16:09:00) [7]Вы не совсем верно меня поняли.
При использовании следующего кода (без ожидания завершения)
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 15:37:00) [8]Оно не СТАРТУЕТ медленно и не РАБОТАЕТ медленно. Оно стартует, как обычно и работает столько, сколько ему нужно, чтобы выполнить свою задачу. КАКэто можно ускорить, подумайте сами?
А Ваша программа стоит и ждет, пока запущенное им приложение не завершится (поэтому, наверное, Вы и решили что все замедлилось). Но Вы же хотите получить код завершения - а КАКможно его получить, не дождавшись этого самого завершения? Никак, конечно.
Все что здесь можно сделать - это поместить этот код в метод Execute дополнительного потока. Тогда ожидать будет этот поток, а основной поток Вашей программы будет продолжать свою работу. Но код завершения Вы в любом случае сможете получить ТОЛЬКО после самого завершения.
fag2000@ok.ru (2002-02-13 15:22:00) [9]Спасибо, код теперь возвращается верно . Однако все равно внешнее приложение стартует и работает очень медленно. Как можно ускорить его запуск и работу работу?
Юрий Зотов (M) (2002-02-13 15:05:00) [10]Тяжелый случай. Но даже при таком количестве ляп 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 14:49:00) [11]
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;
Набережных С. (2002-02-13 14:40:00) [12]GetExitCodeProcess вернет ноль в случае сбоя. А раз нет ошибки, то и цикл не завершается.
Нужноuntil result <> STILL_ACTIVE{$103};
Виктор Щербаков (2002-02-13 14:35:00) [13]to fag2000@ok.ru ©
> Ничего хорошего. Внешнее приложение запускается очень долго
> (около 1 мин а без WaitForSingleObject меньше секунды)
Просто фантастика какая-то! Приведи код.
fag2000@ok.ru (2002-02-13 14:25:00) [14]Попробовал я с WaitForSingleObject
Ничего хорошего. Внешнее приложение запускается очень долго (около 1 мин а без WaitForSingleObject меньше секунды) а код возврата получить не удается. (Возвращаемое значение 0 а должно быть 1).
Виктор Щербаков (2002-02-13 13:48:00) [15]WaitForSingleObject.
А цикл убери.