У меня есть приведенный ниже код Delphi, чтобы обеспечить дружественную оболочку для вызова API CreateProcess.
function StartProcess(ExeName: string; CmdLineArgs: string = '';
ShowWindow: boolean = True; WaitForFinish: boolean = False): integer;
const
c_Wait = 100;
var
StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
begin
//Simple wrapper for the CreateProcess command
//returns the process id of the started process.
FillChar(StartInfo,SizeOf(TStartupInfo),#0);
FillChar(ProcInfo,SizeOf(TProcessInformation),#0);
StartInfo.cb := SizeOf(TStartupInfo);
//this block is the only part of execution that is different
//between my two calls. What am I doing wrong with these flags?
if not(ShowWindow) then begin
StartInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
StartInfo.wShowWindow := SW_HIDE;
end;
CreateProcess(nil,PChar(ExeName + ' ' + CmdLineArgs),nil,nil,False,
CREATE_NEW_PROCESS_GROUP + NORMAL_PRIORITY_CLASS,nil,nil,StartInfo,
ProcInfo);
Result := ProcInfo.dwProcessId;
if WaitForFinish then begin
while IsProcessRunning(Result) do begin
Sleep(c_Wait);
end;
end;
end;
Я использую его для запуска пакетного файла и жду, пока пакетный файл вернется.Это работает хорошо, пока я оставляю значение "ShowWindow" как True.Если я попытаюсь скрыть окно командной строки, оно сразу же возвращается без ошибок.Может ли кто-нибудь помочь мне понять мою ошибку здесь?Пример использования приведен ниже с комментариями.
//this will not show the cmd line window, and it will return immediately
StartProcess('C:\run_me.bat','',False,True);
//this will show the cmd line, and (correctly) wait for the job to finish
StartProcess('C:\run_me.bat','',True,True);
Странно, когда окно скрыто, я все равно получаю идентификатор процесса обратно, как если бы он начался.Но он выходит так быстро, что я не вижу его в диспетчере задач.
Если я изменю командный файл, чтобы в конце его была «пауза» (чтобы он никогда не закончился), явсе равно получаю тот же результат.Таким образом, кажется, что процесс действительно не запускается, когда я устанавливаю флаги в блоке «if not (ShowWindow)» моего кода.
После предложений Роба Кеннеди мой код выглядит так:
function StartProcess(ExeName: string; CmdLineArgs: string = '';
ShowWindow: boolean = True; WaitForFinish: boolean = False): integer;
var
StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
begin
//Simple wrapper for the CreateProcess command
//returns the process id of the started process.
FillChar(StartInfo,SizeOf(TStartupInfo),#0);
FillChar(ProcInfo,SizeOf(TProcessInformation),#0);
StartInfo.cb := SizeOf(TStartupInfo);
if not(ShowWindow) then begin
StartInfo.dwFlags := STARTF_USESHOWWINDOW;
StartInfo.wShowWindow := SW_HIDE;
end;
CreateProcess(nil,PChar(ExeName + ' ' + CmdLineArgs),nil,nil,False,
CREATE_NEW_PROCESS_GROUP + NORMAL_PRIORITY_CLASS,nil,nil,StartInfo,
ProcInfo);
Result := ProcInfo.dwProcessId;
if WaitForFinish then begin
WaitForSingleObject(ProcInfo.hProcess,Infinite);
end;
//close process & thread handles
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
end;