我有下面的Delphi代码来为CreateProcess 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);
奇怪的是,当窗口被隐藏时,我仍然得到一个进程ID,就好像它开始了。但是它退出的速度太快,我无法在任务管理器中看到它。
如果我将批处理文件更改为在其结尾处有一个“暂停”(因此它永远不会真的完成),我仍然会得到相同的结果。所以看起来,当我在代码的“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;
请注意,此函数会泄漏线程句柄和进程句柄。如果你真的想阻止这个函数的返回,直到这个进程停止运行,那么跳过这个循环就调用'WaitForSingleObject(ProcInfo.hProcess,Infinite)'。 – 2010-11-04 20:18:11