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

Вниз

Завершение работы консольного приложения   Найти похожие ветки 

 
Basil ©   (2002-04-02 13:21) [0]

День добрый! Помогите разобраться с проблемой:
Запускаю досовскую программку (к примеру arj) с помощью WinExec, ShellExecute или CreateProcess -- везде одинаковая ситуация. Если я ставлю параметр Sw_Show, программа выполняется и остается консольное окошко (сеанс завершен). А вот если я ставлю Sw_Hide -- программа выполняется, но работу не завершает. В системе она висит как winoldap. Что я не так делаю (или не делаю)?


 
Song ©   (2002-04-02 13:41) [1]

Winoldap - это вообще-то так называется процесс от программы Евгения Рошаля "Far Manager".
А закрыть консольное окошко можно также как и все остальные:
SendMessage(FindWindow("","название"),WM_CLOSE,0,0);


 
Basil ©   (2002-04-02 13:48) [2]

Да! Если знать, что программа уже закончила работать. А как это узнать (WaitForSingleObject не помогает).


 
Song ©   (2002-04-02 15:06) [3]

Вот так будет всё работать. Не забдутьте nShow подкорректировать, если нужно.

Procedure TForm5.CrProcess;
Var SeInfo:TShellExecuteInfo;
ExitCode:DWord;
Begin
FillChar(SEInfo,SizeOf(SEInfo),0);
With SEInfo Do
Begin
cbSize:=SizeOf(TShellExecuteInfo);
fmask:=SEE_MASK_NOCLOSEPROCESS;
Wnd:=Application.Handle;
lpFile:=PChar("имя_файла_архиватора");
lpParameters:=PChar("строка_с_ключами");
lpDirectory:=PChar("Временная_директория"); // Можно nil
nShow:=SW_HIDE;
End;
IF ShellExecuteEx(@SEInfo) then
Repeat
Application.ProcessMessages;
GetExitCodeProcess(SEInfo.hProcess,ExitCode);
Until(ExitCode<>STILL_ACTIVE) or (Application.Terminated) else MessageDlg("Ошибка создания внешнего процесса.",mtError,[mbAbort],0);
End;

P.S. Недавно адаптировал эту процедурку под arj, потому что именно arj по какой-то причине не срабатывает на ExitCode<>STILL_ACTIVE. Если у Вас будет такая же шняга, напишите, я запостю алтернативный вариант. Показания такие: процесс исполняется, заканчивает исполнение, пишет "Сеанс завершён" в заголовке, но управление программе не передаётся т.е. управление за цикл Repeat ... Until не выходит.


 
Basil ©   (2002-04-03 09:49) [4]

2 Song. Попробовал Вашу процедурку -- ничего не изменилось. Побовал и arj и pkzip -- "умирает" в цикле, т.е. ExitCode постоянно Still_Active.


 
Song ©   (2002-04-03 10:06) [5]

Я делал c rar.exe. У меня всё вышло.
В Вашем случае тогда постю алтернативный вариант. Нужно проверять на наличие окна "Сеанс завершён" через FindWindow:

Procedure CrProcess(S:String);
Var SeInfo:TShellExecuteInfo;
Begin
FillChar(SEInfo,SizeOf(SEInfo),0);
With SEInfo Do
Begin
cbSize:=SizeOf(TShellExecuteInfo);
fmask:=SEE_MASK_NOCLOSEPROCESS;
Wnd:=Application.Handle;
lpFile:=PChar("...");
lpParameters:=PChar("...");
lpDirectory:=PChar("...");
nShow:=SW_HIDE;
End;
IF ShellExecuteEx(@SEInfo) then
Repeat
Application.ProcessMessages;
IF FindWindow(nil,"(Сеанс завершен) - Arj")<>0 then
Begin
SendMessage(FindWindow(nil,"(Сеанс завершен) - Arj"),WM_CLOSE,0,0);
Application.ProcessMessages;
Break;
End;
Until False else MessageDlg("Ошибка создания внешнего процесса.",mtError,[mbAbort],0);
End;


P.S. Не забудьте подкорректировать строку в FindWindow


 
Basil ©   (2002-04-03 10:32) [6]

Это, конечно, вариант, спасибо за подсказку. Но неужели никак по-другому нельзя определить, что приложение уже закончило свою работу, ведь Caption (Сеанс завершен) какой-то командой выводится, и я не думаю, что это Dos-овская команда.
Но, тем не менее -- благодарю за помощь.


 
Song ©   (2002-04-03 10:59) [7]

2Basil © (03.04.02 10:32)
Это довольно рабочий вариант, особенно, если автоматизировать поиск окна "Сеанс завершён" по SEInfo.lpFile:

...
IF ShellExecuteEx(@SEInfo) then
Repeat
Application.ProcessMessages;
IF FindWindow(nil,PChar("(Сеанс завершен) - "+Copy(ExtractFileName(String(SEInfo.lpFile)),1,Length(ExtractFileName(String(SEInfo.lpFile)))-4)))<>0 then
Begin
SendMessage(FindWindow(nil,PChar("(Сеанс завершен) - "+Copy(ExtractFileName(String(SEInfo.lpFile)),1,Length(ExtractFileName(String(SEInfo.lpFile)))-4))),WM_CLOSE,0,0);
Application.ProcessMessages;
Break;
End;
Until False else MessageDlg("Ошибка создания внешнего процесса.",mtError,[mbAbort],0);

В этом случае Вы можете использовать любой архиватор, окно удалиться автоматически.



Страницы: 1 вся ветка

Текущий архив: 2002.06.06;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.016 c
3-17796
E-Master
2002-05-11 18:45
2002.06.06
DBGridProи подобные ...


4-18185
Юрий Федоров
2002-04-04 13:43
2002.06.06
Найти процесс...


1-18018
Константин
2002-05-24 10:51
2002.06.06
Раскрытие окна на весь экран


3-17822
XXL
2002-05-16 16:20
2002.06.06
Как сделать сортировку в базе данных


3-17803
Cranium
2002-05-14 12:20
2002.06.06
Поля со списком в IB