zoukankan      html  css  js  c++  java
  • 运行Dos命令并得到dos的输出文本(使用管道函数CreatePipe和PeekNamedPipe)

    function RunDOS(const CommandLine: string): string;
    var
      HRead, HWrite: THandle;
      StartInfo: TStartupInfo;
      ProceInfo: TProcessInformation;
      b: Boolean;
      sa: TSecurityAttributes;
      inS: THandleStream;
      sRet: TStrings;
    begin
      Result := '';
      FillChar(sa, sizeof(sa), 0);
    //设置允许继承,否则在NT和2000下无法取得输出结果
      sa.nLength := sizeof(sa);
      sa.bInheritHandle := True;
      sa.lpSecurityDescriptor := nil;
      b := CreatePipe(HRead, HWrite, @sa, 0);
      Assert(b);

      FillChar(StartInfo, SizeOf(StartInfo), 0);
      StartInfo.cb := SizeOf(StartInfo);
      StartInfo.wShowWindow := SW_HIDE;
    //使用指定的句柄作为标准输入输出的文件句柄,使用指定的显示方式
      StartInfo.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
      StartInfo.hStdError := HWrite;
      StartInfo.hStdInput := GetStdHandle(STD_INPUT_HANDLE); //HRead;
      StartInfo.hStdOutput := HWrite;
     
      b := CreateProcess(nil, //lpApplicationName: PChar
        PChar(CommandLine), //lpCommandLine: PChar
        nil, //lpProcessAttributes: PSecurityAttributes
        nil, //lpThreadAttributes: PSecurityAttributes
        True, //bInheritHandles: BOOL
        CREATE_NEW_CONSOLE,
        nil,
        nil,
        StartInfo,
        ProceInfo);
     
      Assert(b);
      WaitForSingleObject(ProceInfo.hProcess, INFINITE);

      inS := THandleStream.Create(HRead);
      if inS.Size > 0 then
      begin
        sRet := TStringList.Create;
        sRet.LoadFromStream(inS);
        Result := sRet.Text;
        sRet.Free;
      end;
      inS.Free;

      CloseHandle(HRead);
      CloseHandle(HWrite);
    end;

    这个函数在长时间运行dos命令时,会发生无法退出的问题,因此需要另一个实现版本:

    function GetDosOutput(Command: string): string;
    var
    hReadPipe : THandle;
    hWritePipe : THandle;
    SI : TStartUpInfo;
    PI : TProcessInformation;
    SA : TSecurityAttributes;
    BytesRead : DWORD;
    Dest : array[0..32767] of char;
    CmdLine : array[0..512] of char;
    Avail, ExitCode, wrResult : DWORD;
    osVer : TOSVERSIONINFO;
    tmpstr :AnsiString;
    Line: String;
    begin
    osVer.dwOSVersionInfoSize := Sizeof(TOSVERSIONINFO);
    GetVersionEX(osVer);
    if osVer.dwPlatformId = VER_PLATFORM_WIN32_NT then
    begin
        SA.nLength := SizeOf(SA);
        SA.lpSecurityDescriptor := nil;
        SA.bInheritHandle := True;
        CreatePipe(hReadPipe, hWritePipe, @SA, 0);
    end
    else
        CreatePipe(hReadPipe, hWritePipe, nil, 1024);
    try
        FillChar(SI, SizeOf(SI), 0);
        SI.cb := SizeOf(TStartUpInfo);
        SI.wShowWindow := SW_HIDE;
        SI.dwFlags := STARTF_USESHOWWINDOW;
        SI.dwFlags := SI.dwFlags or STARTF_USESTDHANDLES;
        SI.hStdOutput := hWritePipe;
        SI.hStdError := hWritePipe;
        StrPCopy(CmdLine, Command);
        if CreateProcess(nil, CmdLine, nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil, SI, PI) then
        begin
           ExitCode := 0;
           while ExitCode = 0 do
           begin
              wrResult := WaitForSingleObject(PI.hProcess, 1000);
              if PeekNamedPipe(hReadPipe, @Dest[0], 32768, @Avail, nil, nil) then
              begin
                 if Avail > 0 then
                 begin
                   try
                     FillChar(Dest, SizeOf(Dest), 0);
                     ReadFile(hReadPipe, Dest[0], Avail, BytesRead, nil);
                     TmpStr := Copy(Dest,0 , BytesRead-1);
                     Line:=Line+TmpStr; 
                   Except
                   end;
                 end;
              end;
                if wrResult <> WAIT_TIMEOUT then ExitCode := 1;
           end;
           GetExitCodeProcess(PI.hProcess, ExitCode);
           CloseHandle(PI.hProcess);
           CloseHandle(PI.hThread);
         end;
         finally
           if line='' then line:='NULL';    //命令没有输出回应!
           result:=Line;
           CloseHandle(hReadPipe);
           CloseHandle(hWritePipe);
       end;
    end;

    http://blog.csdn.net/henreash/article/details/7095744

  • 相关阅读:
    Redis21:客户端与服务器端的通信与redis管道
    Redis20:keys、scan、bigkeys、查看key的存储方式
    Redis19:限流
    Redis18:分布式锁
    Redis17:cluster集群
    Redis16:两种redis集群解决方案:codis和cluster
    Android : 获取声卡信息的测试代码
    Android : 基于alsa库的音乐播放
    Android system :灯光系统_HAL_lights
    Android system :led_class驱动
  • 原文地址:https://www.cnblogs.com/findumars/p/5289370.html
Copyright © 2011-2022 走看看