zoukankan      html  css  js  c++  java
  • 如何实现调用DOS程序的时候的管道输入重定向!

    http://www.delphibbs.com/delphibbs/dispq.asp?lid=618422

    俺需要一个类似下面的方法!
    send.exe <pic.BMP >report.txt
    不过要求通过程序声称pic.bmp的数据且不通过程序中转直接输出给已经运行的DOS下程序
    send.exe并获得其运行结果的字符输出!因为同时可能有多个调用所以不能通过文件中转! 

    function GetDosOutput(const CommandLine:string): string;
      var
        SA: TSecurityAttributes;
        SI: TStartupInfo;
        PI: TProcessInformation;
        StdOutPipeRead, StdOutPipeWrite: THandle;
        WasOK: Boolean;
        Buffer: array[0..255] of Char;
        BytesRead: Cardinal;
        WorkDir, Line: String;
      begin
        Application.ProcessMessages;
        with SA do
        begin
          nLength := SizeOf(SA);
          bInheritHandle := True;
          lpSecurityDescriptor := nil;
        end;
        // create pipe for standard output redirection
        CreatePipe(StdOutPipeRead,  // read handle
                   StdOutPipeWrite, // write handle
                   @SA,             // security attributes
                   0                // number of bytes reserved for pipe - 0 default
                   );
        try
          // Make child process use StdOutPipeWrite as standard out,
          // and make sure it does not show on screen.
          with SI do
          begin
            FillChar(SI, SizeOf(SI), 0);
            cb := SizeOf(SI);
            dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
            wShowWindow := SW_HIDE;
            hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdinput
            hStdOutput := StdOutPipeWrite;
            hStdError := StdOutPipeWrite;
          end;
          // launch the command line compiler
          WorkDir := ExtractFilePath(CommandLine);
          WasOK := CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil,
                                 PChar(WorkDir), SI, PI);
          // Now that the handle has been inherited, close write to be safe.
          // We don't want to read or write to it accidentally.
          CloseHandle(StdOutPipeWrite);
          // if process could be created then handle its output
          if not WasOK then
            raise Exception.Create('Could not execute command line!')
          else
            try
              // get all output until dos app finishes
              Line := '';
              repeat
                // read block of characters (might contain carriage returns and line feeds)
                WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
                // has anything been read?
                if BytesRead > 0 then
                begin
                  // finish buffer to PChar
                  Buffer[BytesRead] := #0;
                  // combine the buffer with the rest of the last run
                  Line := Line + Buffer;
                end;
              until not WasOK or (BytesRead = 0);
              // wait for console app to finish (should be already at this point)
              WaitForSingleObject(PI.hProcess, INFINITE);
            finally
              // Close all remaining handles
              CloseHandle(PI.hThread);
              CloseHandle(PI.hProcess);
            end;
        finally
            result:=Line;
            CloseHandle(StdOutPipeRead);
        end;
      end;

    来自:战鹰, 时间:2001-9-11 18:09:00, ID:620558
    to tseug,
    我现在用的代码和你类似,但是我需要能够在
    CreateProcess和ReadFile
    之间向DOS程序发送一些数据,比如用WriteFile
    但不知道文件句柄用什么!你能高速我吗? 

    来自:tseug, 时间:2001-9-11 19:13:00, ID:620624
    那你还要建立一个管道, 重定向 STD_INPUT_HANDLE, CreateProcess之后, 写这个管道就可以了.

    来自:tseug, 时间:2001-9-13 23:23:00, ID:624891
    procedure Redirect(const aExecuteFile:string;
                       const aInputFile  :string;
                       const aOutputFile :string);

    var
      SI: TStartupInfo;
      PI: TProcessInformation;
      hInput, hOutput : THandle;
      WorkDir: string;
      bOk: Boolean;
    begin

      hInput := FileOpen(aInputFile, fmOpenRead);
      hOutput:= FileCreate(aOutputFile);

      try
        // Make child process use StdOutPipeWrite as standard out,
        // and make sure it does not show on screen.
        with SI do
          begin
          FillChar(SI, SizeOf(SI), 0);
          cb := SizeOf(SI);
          dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
          wShowWindow := SW_HIDE;
          hStdInput := hInput;
          hStdOutput:= hOutput;
          hStdError := hOutput;
          end;

        // launch the command line compiler
        WorkDir := ExtractFilePath(aExecuteFile);
        bOK := CreateProcess(nil, PChar(aExecuteFile), nil, nil, True, 0, nil,
                                 PChar(WorkDir), SI, PI);

        try
          // if process could be created then handle its output
          if not bOK then raise Exception.Create('Could not run ' + aExecuteFile);
          WaitForSingleObject(PI.hProcess, INFINITE);

        finally
          // Close all remaining handles
          CloseHandle(PI.hThread);
          CloseHandle(PI.hProcess);
        end;

      finally
        FileClose(hInput);
        FileClose(hOutput);
      end;
    end; 

    来自:tseug, 时间:2001-9-13 23:32:00, ID:624897
    看看上面的代码, 你应该明白重定向的含义了. 你只要得到合适的句柄, 可以把输入输
    出重定向到你想要的地方. 句柄可以是文件, 也可以是管道, 你只要指定好
    hStdInput(标准输入),hStdOutput(标准输出),hStdError(标准错误) 就可以了. 

  • 相关阅读:
    docker重启提示已存在一个容器的问题处理
    conda虚拟环境安装
    dell5460笔记本电脑ubuntu18.04系统音频驱动的安装和使用
    CentOS8的网络管理变化
    jupyter notebook 安装扩展nbextensions
    win10系统systeminfo命令的过滤用法
    《学习scrapy框架爬小说》的进一步完善
    记手机端 下拉加载新数据
    记 页面使用overflow-scroll在iOS上滑动卡顿的问题
    记 判断手机号运营商function
  • 原文地址:https://www.cnblogs.com/railgunman/p/1876775.html
Copyright © 2011-2022 走看看