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" _

32.自己写的一个简单的加载插件

常用Function 收集

Runtime Error! R6025-pure virtual function call

Runtime Error! R6025-pure virtual function call 问题怎么解决

Cloud Functions 删除文件夹:TypeScript