function WinExecAndWait32(sExe:String; onShowInfo:_stdShowInfo=nil):DWord;等待执行并回显运行过程中的信息
Posted haihong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了function WinExecAndWait32(sExe:String; onShowInfo:_stdShowInfo=nil):DWord;等待执行并回显运行过程中的信息相关的知识,希望对你有一定的参考价值。
常见的ExeAndWait函数,改了一下,带返回状态回调。
//执行程序,并等待其返回值System.exitCode //http://delphi.ktop.com.tw/board.php?cid=168&fid=914&tid=36163 function WinExecAndWait32(sExe:String; onShowInfo:_stdShowInfo=nil):DWord; var rt, n: DWORD; si : STARTUPINFO; pi : PROCESS_INFORMATION; p : pAnsiChar; s, sPath:string; // sa : TSecurityAttributes; pSec: pointer; hReadPipe,hWritePipe:THandle; lngBytesread:dword; L : BOOL; buf : array[0..255] of char; begin result:=0; zeroMemory(@si, sizeOf(si)); si.cb:=sizeOf(si); zeroMemory(@pi, sizeOf(pi)); // pSec:=nil; if assigned(onShowInfo) then begin FillChar(sa,Sizeof(sa),#0); sa.nLength := Sizeof(sa); sa.bInheritHandle := True; sa.lpSecurityDescriptor := nil; L:=CreatePipe(hReadPipe, hWritePipe, @sa, 0); pSec:[email protected]; // si.dwFlags:=STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; //si.wShowWindow:=Visibility; si.hStdOutput:=hWritePipe; si.hStdError:=hWritePipe; end; //路径 sPath:=extractFilePathNoParam(sExe); if sPath=‘‘ then sPath:=extractFilePath(application.exeName); //sExe:=‘"‘+sExe+‘"‘; L:=assigned(onShowInfo); if not CreateProcess( nil, pChar(sExe), { pointer to command line string } pSec, { pointer to process security attributes } pSec, { pointer to thread security attributes } L, { 20180622之前是FALSE。handle inheritance flag } CREATE_NO_WINDOW, nil, { pointer to new environment block } pChar(sPath), { pointer to current directory name, PChar} si, { pointer to STARTUPINFO } pi { pointer to PROCESS_INF } ) then begin raise exception.create(‘创建线程出错!CreateProcess failed! ‘#13‘起始路径:‘+sPath); exit; end; //开始执行、等待 if assigned(onShowInfo) then CloseHandle(hWritePipe); //关闭输入 repeat if assigned(onShowInfo) then begin fillChar(buf, Sizeof(buf), #0); L := ReadFile(hReadPipe, buf, 256, lngBytesread, nil); //从输出中读 if L then onShowInfo(trim(buf)); end; //继续,等待 rt:=WaitForSingleObject(pi.hProcess, 0); Application.ProcessMessages(); Sleep(500); //sleep(100) until (rt<>wait_TimeOut) or (lGlobalTerminateWorking); if (GetExitCodeProcess(pi.hProcess, rt)) then result:=rt; // CloseHandle(pi.hProcess); CloseHandle(pi.hThread); if assigned(onShowInfo) then CloseHandle(hReadPipe); end; //执行程序并等待其返回值,包括一系列输出 //http://delphi.ktop.com.tw/board.php?cid=30&fid=72&tid=27232 function WinExecAndWait32(sExe:String; Visibility:Integer; var mOutputs:string):Cardinal; var sa:TSecurityAttributes; hReadPipe,hWritePipe:THandle; ret:BOOL; strBuff:array[0..255] of char; lngBytesread:DWORD; WorkDir:String; StartupInfo:TStartupInfo; ProcessInfo:TProcessInformation; begin FillChar(sa,Sizeof(sa),#0); sa.nLength := Sizeof(sa); sa.bInheritHandle := True; sa.lpSecurityDescriptor := nil; //lpSecurityDeforbiddenor ret := CreatePipe(hReadPipe, hWritePipe, @sa, 0); WorkDir:=extractFilePathNoParam(sExe); //extractFileDir(Application.ExeName) FillChar(StartupInfo,Sizeof(StartupInfo),#0); StartupInfo.cb:=Sizeof(StartupInfo); StartupInfo.dwFlags:=STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; StartupInfo.wShowWindow:=Visibility; StartupInfo.hStdOutput:=hWritePipe; StartupInfo.hStdError:=hWritePipe; if not CreateProcess(nil, PChar(sExe), { pointer to command line string } @sa, { pointer to process security attributes } @sa, { pointer to thread security attributes } True, { handle inheritance flag } // CREATE_NEW_CONSOLE or { creation flags } NORMAL_PRIORITY_CLASS, nil, { pointer to new environment block } PChar(WorkDir), { pointer to current directory name, PChar} StartupInfo, { pointer to STARTUPINFO } ProcessInfo) { pointer to PROCESS_INF } then Result := INFINITE {-1} else begin // Form1.Hide; // FileOpen(FileName,fmShareExclusive); // SetWindowLong(Application.Handle,GWL_EXSTYLE,WS_EX_TOOLWINDOW); ret:=CloseHandle(hWritePipe); mOutputs:=‘‘; while ret do begin FillChar(strBuff,Sizeof(strBuff),#0); ret := ReadFile(hReadPipe, strBuff, 256, lngBytesread, nil); mOutputs := mOutputs + strBuff; end; // Application.ProcessMessages; WaitforSingleObject(ProcessInfo.hProcess, INFINITE); GetExitCodeProcess(ProcessInfo.hProcess, Result); CloseHandle(ProcessInfo.hProcess); { to prevent memory leaks } CloseHandle(ProcessInfo.hThread); // Form1.Close; { exit application } ret := CloseHandle(hReadPipe); end; end;
然后是定义:
type //显示信息的函数类型 _stdShowInfo=procedure (sInfo:string=‘‘; lTime:Boolean=true); stdcall; _objShowInfo=procedure (sInfo:string=‘‘; lTime:Boolean=true) of Object;
辅助的:
//参数的开始点:GetParamStr function iGetParamPosition(AFile:string):integer; var i, j, nDrv:integer; lHead:boolean; c, c2:char; s,s2:string; begin result:=0; //盘符,例如: d:a.exe -p1=f:a.bmp 或者:a.exe .a.exe ..a.exe s:=trim(AFile); s:=copy(s,1,2) + StringReplace(copy(s,3,length(s)),‘:‘,‘‘, [rfReplaceAll]); {lHead:=(pos(‘:‘,s)=2) or (pos(‘\‘,s)=1) or (pos(‘..‘,s)=1) or (pos(‘.‘,s)=1) or (pos(‘‘,s)=1); if lHead then begin //路径没有头 result:=length( extractFilePath(AFile) ); s:=extractFileName(AFile); end; } s2:=s; i:=-1; c2:=‘ ‘; //去掉文件名中的参数 while s<>‘‘ do begin c:=s[length(s)]; //最后一个字符 s:=copy(s, 1, length(s)-1); //去掉最后一个字符 if (c=‘ ‘) and (c2 in [‘-‘,‘/‘,‘#‘]) then i:=length(s); //空格后边跟着-/符号,表示参数 c2:=c; end; if i>0 then result:=result+i; end; //移除文件名中的参数。系统自带函数:GetParamStr function extractFilePathNoParam(AFile:string):string; var i:integer; s,s2:string; begin result:=extractFilePath(AFile); s:=AFile; //extractFileName(AFile); i:=iGetParamPosition(s); if i>0 then result:=extractFilePath( trim( copy(s,1,i) ) ); //result:=result+s; end; //执行的参数 function extractExecuteParam(AFile:string):string; var i, j:integer; s:string; begin result:=‘‘; s:=trim(AFile); i:=iGetParamPosition(s); if i>0 then result:=trim( copy(s,i+1,200) ); end;
这样外部调用的时候,可以传一个onShowInfo:_stdShowInfo给他。
以上是关于function WinExecAndWait32(sExe:String; onShowInfo:_stdShowInfo=nil):DWord;等待执行并回显运行过程中的信息的主要内容,如果未能解决你的问题,请参考以下文章
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
Runtime Error! R6025-pure virtual function call