Как программно запустить Досовское приложение?

  • Автор темы semantics
  • Дата начала
Статус
Закрыто для дальнейших ответов.
S

semantics

#1
Кто ориентируется в программном запуске ехе-шников?
Есть досовский ехе-файл. Как запустить его программно из другой программы, скомпилированной в среде DELFI?
Как обнаружить его завершение?
 
P

ProgeRock

#2
Что касается запуска:
ShellExecute(HWND_DESKTOP, 'open', 'путь', nil, nil, SW_SHOWNORMAL);
находится в ShellApi

А вот чтоб обнаружить завершение: если приложение имеет идентификатор окна, то пойдет
Код:
Wnd: HWd;

Wnd:=FindWindow(nil, 'Заголовок');
if Wnd<>0 then {ехе-файл работает}
если не имеет идентификатора, то скажите.
 
Y

Yason

#3
Вызывает некоторые сомнения, что дос-приложение будет создавать окошки отличные от "c:\windows\system32\cmd.exe"...

Я бы для запуска использовал CreateProcess (да, там куча параметров, но большинство можно тупо ставить NULL) - эта функция не только запускает процесс, но и возвращает его идентификатор (через lpProcessInformation.hProcess).
А потом состояние процесса можно проверять с помощью GetExitCodeProcess: пока процесс живой, будет возвращаться STILL_ACTIVE, в противном случае - код завершения.
 
S

semantics

#4
Что касается запуска:
ShellExecute(HWND_DESKTOP, 'open', 'путь', nil, nil, SW_SHOWNORMAL);
находится в ShellApi

А вот чтоб обнаружить завершение: если приложение имеет идентификатор окна, то пойдет
Код:
Wnd: HWd;

Wnd:=FindWindow(nil, 'Заголовок');
if Wnd<>0 then {ехе-файл работает}
если не имеет идентификатора, то скажите.
Окна у программы нет.
Есть еще одно уточнение - нужен синхронный запуск, т.е. приостановить выполнение основной программы до завершения подчиненной.
 
Z

zubr

#5
semantics
Можно используя
1. ShellExecutEx и WaitForInputIdle или WaitForSingleObject
2. CreateProcess и WaitForInputIdle или WaitForSingleObject
 
P

ProgeRock

#6
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
ShellInfo: TShellExecuteInfo;
Code: DWord;
Hnd: THandle;
begin
FillChar(ShellInfo, SizeOf(TShellExecuteInfo), 0);
ShellInfo.cbSize:=SizeOf(TShellExecuteInfo);
ShellInfo.fMask:=SEE_MASK_NOCLOSEPROCESS;
ShellInfo.Wnd:=HWND_DESKTOP;
ShellInfo.lpFile:='путь к файлу';
ShellInfo.lpParameters:=nil;
ShellInfo.lpDirectory:=nil;
ShellInfo.nShow:=SW_SHOWNORMAL;

ShellExecuteEx(@ShellInfo); //Можно использовать вместо ShellExecute

Hnd:=ShellInfo.hProcess ;
GetExitCodeProcess(Hnd, Code);

if Code=Still_Active then {приложение работает};
end;
 
Z

zubr

#7
ProgeRock
GetExitCodeProcess(Hnd, Code); - не самое лучшее решение, тогда надо в цикле вызывать этот код. Лучше сделать:
WaitForInputIdle(ShellInfo.hProcess, 200); //приложение ждет 200 мс (если надо бесконечно, пока не завершится, то вместо 200, infinite) пока не завершится вызванный процесс
 
Статус
Закрыто для дальнейших ответов.