Delphi 2009 及更高版本中的捕获控制台

2024-04-11

下面的代码适用于 Delphi XE,但 2400 的缓冲区大小相当难看。

有人对清理这个例程有一些建议吗?并使 2400 限制消失(不定义 64000 缓冲区)。

Thanks


procedure TForm1.Button1Click(Sender: TObject);
begin
     CaptureConsoleOutput('c:\windows\system32\ipconfig','',Memo1);
end;

过程 TForm1.CaptureConsoleOutput(const ACommand, AParameters: String; AMemo: TMemo); 常量 CReadBuffer = 2400; 变量 saSecurity:TSecurityAttributes; hRead:THandle; hWrite:THandle; suiStartup:TStartupInfo; piProcess: TProcessInformation; pBuffer:AnsiChar 的数组[0..CReadBuffer]; dRead:双字; d运行:双字; 开始 saSecurity.nLength := SizeOf(TSecurityAttributes); saSecurity.bInheritHandle := True; saSecurity.lpSecurityDescriptor := nil;

如果 CreatePipe(hRead, hWrite, @saSecurity, 0) 那么 开始 FillChar(suiStartup, SizeOf(TStartupInfo), #0); suiStartup.cb := SizeOf(TStartupInfo); suiStartup.hStdInput := hRead; suiStartup.hStdOutput := hWrite; suiStartup.hStdError := hWrite; suiStartup.dwFlags := STARTF_USESTDHANDLES 或 STARTF_USESHOWWINDOW; suiStartup.wShowWindow := SW_HIDE;

 if CreateProcess(nil, PChar(ACommand + ' ' + AParameters), @saSecurity,
   @saSecurity, True, NORMAL_PRIORITY_CLASS, nil, nil, suiStartup, piProcess)
   then
 begin
   repeat
     dRunning  := WaitForSingleObject(piProcess.hProcess, 100);
     Application.ProcessMessages();
     repeat
       dRead := 0;
       ReadFile(hRead, pBuffer[0], CReadBuffer, dRead, nil);
       pBuffer[dRead] := #0;

       OemToAnsi(pBuffer, pBuffer);
       AMemo.Lines.Add(String(pBuffer));
     until (dRead < CReadBuffer);
   until (dRunning <> WAIT_TIMEOUT);
   CloseHandle(piProcess.hProcess);
   CloseHandle(piProcess.hThread);
 end;

 CloseHandle(hRead);
 CloseHandle(hWrite);

结尾; 结尾;


我有一些代码可以做到这一点。我已经删除了各种不相关的部分,所以这可能无法按原样编译。但你应该明白:

  procedure ReadStdout(hstdout: THandle; out stdout: string);
  var
    Buffer: AnsiString;
    FileSize: DWORD;
    NumberOfBytesRead: DWORD;
  begin
    FileSize := SetFilePointer(hstdout, 0, nil, FILE_END);
    if FileSize>0 then begin
      SetLength(Buffer, FileSize);
      SetFilePointer(hstdout, 0, nil, FILE_BEGIN);
      ReadFile(hstdout, Buffer[1], FileSize, NumberOfBytesRead, nil);
      //should really check that NumberOfBytesRead=FileSize
      stdout := Buffer;
    end else begin
      stdout := '';
    end;
  end;

  function CreateFileHandle(const FileName: string): THandle;
  var
    SecurityAttributes: TSecurityAttributes;
  begin
    ZeroMemory(@SecurityAttributes, SizeOf(SecurityAttributes));
    SecurityAttributes.nLength := SizeOf(SecurityAttributes);
    SecurityAttributes.lpSecurityDescriptor := nil;
    SecurityAttributes.bInheritHandle := True;
    Result := CreateFile(
      PChar(FileName),
      GENERIC_READ or GENERIC_WRITE,
      FILE_SHARE_READ or FILE_SHARE_WRITE,
      @SecurityAttributes,
      CREATE_ALWAYS,
      FILE_ATTRIBUTE_NORMAL or FILE_FLAG_WRITE_THROUGH,
      0
    );
  end;

  procedure Execute(const ExecutableFileName, DataFileName, TempFolder: string);
  var        
    hstdin, hstdout: THandle;
    StartupInfo: TStartupInfo;
    ProcessInfo: TProcessInformation;
    ExitCode: DWORD;
    stdout: string;
  begin
    hstdin := CreateFileHandle(TempFolder+'stdin');
    hstdout := CreateFileHandle(TempFolder+'stdout');
    Try
      ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
      StartupInfo.cb := SizeOf(StartupInfo);
      StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      StartupInfo.wShowWindow := SW_HIDE;
      StartupInfo.hStdInput := hstdin;
      StartupInfo.hStdError := hstdout;
      if CreateProcess(
        PChar(ExecutableFileName),
        '',
        nil,
        nil,
        True,
        CREATE_NO_WINDOW or NORMAL_PRIORITY_CLASS,
        nil,
        PChar(TempFolder),
        StartupInfo,
        ProcessInfo
      ) then begin            
        Try
          WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
          GetExitCodeProcess(ProcessInfo.hProcess, ExitCode);
          ReadStdout(hstdout, stdout);
        Finally
          CloseHandle(ProcessInfo.hProcess);
          CloseHandle(ProcessInfo.hThread);
        End;
      end else begin
        //error;
      end;
    Finally
      CloseHandle(hstdout);
      CloseHandle(hstdin);
    End;
  end;

您有时会想要清理临时文件。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Delphi 2009 及更高版本中的捕获控制台 的相关文章

随机推荐

  • 使用 Spring Data JDBC 的嵌套数据结构

    我想创建一个嵌套的数据结构 Entity1包含类型的对象Entity2存储在地图中 Entity2应该包含一个对象的映射Entity3 第一部分 Entity1 and Entity工作正常 当我添加Entity3 发生异常 当我执行一个简
  • 如何在 php/mysql Web 应用程序中实现悲观锁定?

    如何在 php mysql Web 应用程序中实现悲观锁定 网络用户打开一个页面来编辑一个数据集 行 网络用户单击 锁定 按钮 因此其他用户可以读取但不能写入此数据集 网络用户进行一些修改 可能需要 1 到 30 分钟 网络用户单击 保存
  • 如何在 watir 的 webdriver-user-agent gem 中传递 Chrome 选项

    我正在尝试使用 Watir gem 传递 Chrome Drive 的 cookies 选项 从 Watir 文档我可以做Watir Browser new chrome opts 所以对于cookie我可以这样做 browser Wati
  • Android FAB setBackgroundTintList 与 ColorStateList 不起作用

    我想在未启用 NFC 时更改 NFC 扫描 FAB 的颜色 我已成功在应用程序启动时更改颜色 但如果用户点击 FAB 并启用 NFC 颜色不会更改为原色 日志显示确实如此 但更改并未发生 My minSdkVersion 15 XML
  • Node.js 请求库的相对 uri

    我有以下代码 node js 无法解析 url const request require request const teamURL users user id teams const req request url teamURL js
  • 类“QueryParameterComparer”必须实现函数比较。

    我在下面从 C 转换为 VB NET 的代码中遇到以下错误 原始代码可以在此处找到 https developer linkedin com sites default files LinkedInAuth rar zip https de
  • 带有 android:priority 设置的意图过滤器

    我测试了意图过滤器android priority 0 和意图过滤器android priority 20 by android intent category HOME 我列出以下信息
  • 变量中的 JavaScript 反斜杠 (\) 导致错误

    在 Javascript 中 当我在某些变量中添加反斜杠时 例如 var ttt aa var ttt aa JavaScript 显示错误 如果我尝试限制用户输入此字符 我也会收到错误 aaa indexOf 1 限制用户输入中的反斜杠并
  • 如何更改 Xamarin 中的章节标题字体样式?

    我有这个列表视图 但我不知道如何设置部分标题的样式 在 Xamarin 中如何实现 还没有找到任何东西
  • OpenCV 中是否可以将局部曲率绘制为代表对象“指向性”的热图?

    给定一个可以检测并绘制轮廓的斑点阈值图像 在绘制轮廓时是否可以将局部曲率表示为热图 即是否 1 可以确定开放 cv 轮廓上的局部曲率 2 将此曲率映射到热图颜色空间 3 将轮廓绘制为热图 我的目标是测量对象的 尖度 以便我可以绘制从尖头侧到
  • 带回滚的Mysql嵌套事务

    有人可以告诉我是否可以从一个过程中调用另一个过程 并且如果任一过程的任何部分失败 则回滚所有内容 如果这是可能的 有人可以向我展示一个如何实施的小例子吗 EDIT 过程 b 失败 但过程 a 仍然向表 a 中插入一行 据我了解 如果插入的任
  • C 检测 popen 子进程中的错误

    我在用着popen读取第三方程序的输出 如果子程序失败 我想检测并重新启动 我该怎么做呢 如果子进程死亡 进程不会正常退出 因此无法使用WEXITSTATUS去检查 还有别的办法吗 这是一个简单的例子 PINGER C include
  • 在经典 ASP 中设置 HTTP_X_FORWARDED_FOR 服务器变量

    我需要在 Request ServerVariables 集合中设置 HTTP X FORWARDED FOR 值 我正在尝试使用 Fiddler 请参阅本文 https stackoverflow com questions 321185
  • 给定精度的快速双精度数到字符串转换

    我需要以给定的精度将双精度数转换为字符串 String format 3f value or DecimalFormat 可以完成这项工作 但基准测试表明它很慢 甚至Double toString在我的机器上转换 100 万个数字大约需要
  • 如何判断一个视频是否是首映? ...通过 YouTube API

    在 YouTube 上 我们可以上传录制的视频 直播 现在还可以进行首映 使用视频 列出 YouTube 数据 API 的端点 https developers google com youtube v3 docs videos list我
  • mysql 全文搜索无法搜索 3 个字符

    在我的网站中 我使用全文搜索实现了搜索功能 它通常工作正常 但有时不像当我使用关键字 ship 而不是 shi 搜索时给出结果 但它应该回来 请帮助我为什么会发生这种情况 要索引的单词的最小和最大长度由ft min word len and
  • 使用 JavaScript 或 jQuery 如何检查窗口上是否存在事件?

    Setup 我已将一个事件附加到 窗口 对象 我想通过代码检查它是否存在 window addEventListener beforeunload function e false Attempts 我尝试过简单的和 jQuery 但没有成
  • 栅栏柱问题的优雅解决方案(带字符串)

    我指的是连接Strings 具有一定的String中间 例如用句点分隔的句子连接 或用逗号连接参数列表 我知道您可以使用库 但有时这些库不能满足您的要求 例如当您想要生成要连接的短语时 到目前为止我已经想出了两种解决方案 StringBuf
  • 当用户按下按键时看不到消息

    下列java程序调用本机方法C应该打印一条消息you pressed a key 如果用户按下某个键 但当我按下按键时我看不到该消息 我还检查该功能是否SetWindowsHookEx返回 null 但不 它不返回 null Java代码
  • Delphi 2009 及更高版本中的捕获控制台

    下面的代码适用于 Delphi XE 但 2400 的缓冲区大小相当难看 有人对清理这个例程有一些建议吗 并使 2400 限制消失 不定义 64000 缓冲区 Thanks procedure TForm1 Button1Click Sen