在Windows XP上从Delphi应用程序中的命令行程序获取输出

在Windows XP上从Delphi应用程序中的命令行程序获取输出,delphi,command-line,windows-xp,Delphi,Command Line,Windows Xp,我有一个用Delphi XE2编写的VCL应用程序,它需要执行一个命令行程序(也用Delphi XE2编写)并通过它获得文本输出。我目前正在使用以下代码,该代码基于此处找到的代码: 这在大多数Windows版本上都可以正常工作。不幸的是,我们最近注意到它在Windows XP上不起作用。对WaitForSingleObject的调用永远不会返回。我尝试用较小的值(例如15000)替换第二个参数INFINITE,但这似乎没有任何区别。在TaskManager中,我可以看到,在调用GetDosOut

我有一个用Delphi XE2编写的VCL应用程序,它需要执行一个命令行程序(也用Delphi XE2编写)并通过它获得文本输出。我目前正在使用以下代码,该代码基于此处找到的代码:

这在大多数Windows版本上都可以正常工作。不幸的是,我们最近注意到它在Windows XP上不起作用。对WaitForSingleObject的调用永远不会返回。我尝试用较小的值(例如15000)替换第二个参数INFINITE,但这似乎没有任何区别。在TaskManager中,我可以看到,在调用GetDosOutput之后,命令行程序实际上正在运行。如果我结束VCL应用程序,那么命令行程序似乎会成功完成它的工作(这可以从它输出我期望它输出的文件这一事实得到证明)。我还注意到,如果我从StartupInfo.dwFlags中删除STARTF_USESTDHANDLES,命令行程序将正常运行,WaitForSingleObject将立即返回;然而,我显然无法获得程序返回的文本


有没有人对我如何在Windows XP上实现这一点有什么建议?

在freepascal中有一个非常有用的单元,叫做“进程”,它可以做到这一点,已经完成了将端口连接到Delphi的工作,因此您可以使用简单的一行程序在Delphi中捕获命令的输出:

RunCommand()

或者,您也可以通过自己创建一个TProcess对象(RunCommand只是包装这个对象)来捕获具有更高级功能的命令输出

项目在这里:

  • 一个简单的演示:
如何将命令的输出,即“dir”(列出目录内容,著名的MS DOS命令)捕获到字符串中,然后将其添加到备忘录中:

uses 
  dprocess; 
// ...
var 
  output: ansistring;
begin
  RunCommand('cmd', ['/c', 'dir'], output, [poNoConsole]);
  memo1.Lines.Add(output);
end;

您可以在以下任务的答案中找到正确的代码:我喜欢阅读此位:句柄:Boolean@DavidHeffernan对于具有强类型背景的人来说,winAPI的BOOL类型可能会令人困惑。如果在读取管道之前等待程序完成,则可能会出现死锁。最好在输出可用时读取输出。在这方面,Delphi Dabbler的代码更好。进一步调查该程序出现挂起的原因。使用调试器。@RobKennedy,你是对的,这一个似乎是众多衍生工具中的一个(与DelphiDabler的代码片段也不是100%相同)。不管怎样,我建议不要再胡思乱想了,转而使用JCL帮助程序(或相应的JVCL组件)。您是否打算对每个问题都给出相同的答案?
uses 
  dprocess; 
// ...
var 
  output: ansistring;
begin
  RunCommand('cmd', ['/c', 'dir'], output, [poNoConsole]);
  memo1.Lines.Add(output);
end;