Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.03.04;
Скачать: CL | DM;

Вниз

Как узнать код возврата   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.009 c
3-9069
kserg@ukr.net
2002-02-06 12:50
2002.03.04
Как узнать дату последнего обновления файла-таблицы?


6-9263
Leviathan
2001-12-10 22:29
2002.03.04
Ошибка на сокете


3-9079
СергейКнязев
2002-02-06 11:48
2002.03.04
Помогите найти ошибку в запросе СРОЧНО


7-9320
AlexKniga
2001-11-27 18:10
2002.03.04
Не в тему. Про аудио системы.


1-9171
VID
2002-02-14 09:15
2002.03.04
Необязательные параметры функции