【问题标题】:How can I wait for a command-line program to finish?如何等待命令行程序完成?
【发布时间】:2011-06-20 13:44:40
【问题描述】:

我已经使用命令行参数运行程序。我怎样才能等待它完成运行?

【问题讨论】:

  • 不能说什么问题对我来说非常清楚...对于 CLI input 来自 stdinoutput 转到 stdout (或 stderr 在某些情况下)。作为程序行为修饰符的参数
  • 请重新表述您的问题,因为目前的表格非常不清楚。你在等什么?执行程序的控制台输出?该程序发送的 Windows 消息?
  • 对不起我的英语不好!我找到了答案。你可以在页面底部看到!
  • 那是的答案,然后你没有很清楚地问你的问题。我已经为您编辑了它,使其与您显然打算询问的内容相匹配。

标签: delphi command-line


【解决方案1】:

这是我的回答:(谢谢大家)

uses ShellAPI;

function TForm1.ShellExecute_AndWait(FileName: string; Params: string): bool;
var
  exInfo: TShellExecuteInfo;
  Ph: DWORD;
begin

  FillChar(exInfo, SizeOf(exInfo), 0);
  with exInfo do
  begin
    cbSize := SizeOf(exInfo);
    fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT;
    Wnd := GetActiveWindow();
    exInfo.lpVerb := 'open';
    exInfo.lpParameters := PChar(Params);
    lpFile := PChar(FileName);
    nShow := SW_SHOWNORMAL;
  end;
  if ShellExecuteEx(@exInfo) then
    Ph := exInfo.hProcess
  else
  begin
    ShowMessage(SysErrorMessage(GetLastError));
    Result := true;
    exit;
  end;
  while WaitForSingleObject(exInfo.hProcess, 50) <> WAIT_OBJECT_0 do
    Application.ProcessMessages;
  CloseHandle(Ph);

  Result := true;

end;

【讨论】:

  • 您应该使用 MsgWaitForMultipleObjects() 而不是 WaitForSingleObject(),这样您就不会不必要地调用 Application.ProcessMessages()。过于频繁地这样做会在循环运行时降低应用的性能。
  • 我会在一个线程中使用它!所以 Application.ProcessMessages;将删除!
  • MsgWaitForMultipleObjects 确实可能是更好的解决方案 - 如果你这样做了,你只需要等待线程!
  • 在 XE3 中使用 Params = '' 工作正常。但只是好奇我可以将什么样的参数传递给该函数?
【解决方案2】:

如果我正确理解您的问题,您希望在命令行中执行程序并在您的应用程序中而不是在控制台窗口中捕获其输出。为此,您可以使用pipes 读取输出。这是一个示例源代码:

Capture the output from a DOS (command/console) Window

【讨论】:

    【解决方案3】:

    使用DSiWin32

    sl := TStringList.Create;
    if DSiExecuteAndCapture('cmd.exe /c dir', sl, 'c:\test', exitCode) = 0 then
      // exec error
    else
      // use sl
    sl.Free;
    

    【讨论】:

    • @gabr-嗨!我得到了 DSIWin32 v1.70b - 这是测试版吗?
    • @gabr-还有另一个问题。应用程序在捕获输出时冻结。有一种方法可以动态显示捕获的输出。
    【解决方案4】:

    好的,获取命令行参数,你用

    ParamCount:返回命令行传递给程序的参数个数。

    ParamStr :返回特定参数,由索引请求。 Running Dephi Applications With Parameters

    现在,如果您的意思是读写控制台,您可以使用

    WriteLn:向控制台写入一行文本。

    ReadLn :从控制台读取一行文本作为字符串。 Delphi Basics

    【讨论】:

      【解决方案5】:

      如果您想要执行命令行可执行文件,并获得此 exe 写入控制台的响应,最简单的方法可能是从批处理文件调用 exe 并使用 @ 将输出重定向到另一个文件987654322@,然后读取该文件。

      例如,如果您需要执行“dir”命令并获取其输出,您可以有一个名为 getdir.bat 的批处理文件,其中包含以下内容:

      @echo off
      dir c:\users\myuser\*.* > output.txt
      

      您可以使用 API 函数 ShellExecute 执行该批处理文件。你可以阅读它http://delphi.about.com/od/windowsshellapi/a/executeprogram.htm

      然后你可以读取输出文件,甚至使用 TStringList 之类的东西:

      var
        output: TStringList;
      begin
        output := TStringList.Create();
        output.LoadFromFile('output.txt');
        ...
      

      【讨论】:

        猜你喜欢
        • 2015-06-13
        • 2020-05-27
        • 2011-10-20
        • 1970-01-01
        • 2012-10-16
        • 2023-04-04
        • 1970-01-01
        • 2018-08-31
        • 2011-09-20
        相关资源
        最近更新 更多