【问题标题】:How do I Launch OpenFiles.exe from Delphi XE2 ShellExecute?如何从 Delphi XE2 ShellExecute 启动 OpenFiles.exe?
【发布时间】:2013-11-16 15:53:56
【问题描述】:

我需要从 Delphi XE2 应用程序启动 MS Window 的 OpenFiles.exe 以将当前打开的文件导出到文本文件。正常的 cmd.exe 语法类似于:

Openfiles.exe /query /s 127.0.0.1 /nh >c:\OpenFilesExport.txt

使用以下代码返回成功退出代码但未生成导出文件:

var
  exInfo: TShellExecuteInfo;
  exitcode: DWORD;
begin
  FillChar(exInfo, Sizeof(exInfo), 0);
  with exInfo do
  begin
    cbSize := Sizeof(exInfo);
    fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT;
    lpVerb := 'open';
    lpFile := Pchar('Openfiles.exe');
    lpParameters := PChar('/query /s 127.0.0.1 /nh >c:\OpenFilesOutput.txt');
    nShow := SW_SHOWNORMAL
  end;
  if ShellExecuteEx(@exInfo) then
  begin
    while GetExitCodeProcess(exInfo.hProcess, exitcode)
      and (exitcode = STILL_ACTIVE) do
      Application.ProcessMessages();

    CloseHandle(exInfo.hProcess);
  end
  else
    ShowMessage(SysErrorMessage(GetLastError));

我还尝试将 cmd.exe 语法放在一个 bat 文件中并从 shellexecute 启动它,它确实会生成文件但没有内容。从资源管理器运行相同的 bat 文件会按预期生成文件。

如何从 ShellExecute 成功启动 Openfiles.exe?

【问题讨论】:

    标签: delphi winapi delphi-xe2


    【解决方案1】:

    你的问题是重定向,>,只有在你有命令解释器的情况下才有意义。而在你的代码中你没有。你有两个选择:

    1. 调用ShellExecuteEx 传递命令解释器来完成这项工作。
    2. 使用CreateProcess 执行其他进程,但将句柄作为新进程的标准输出句柄传递给文件。

    对于命令解释器选项,您将拥有如下命令行:

    cmd /c Openfiles.exe /query /s 127.0.0.1 /nh >c:\OpenFilesExport.txt
    

    代码可能是这样的:

    FillChar(exInfo, Sizeof(exInfo), 0);
    with exInfo do
    begin
      cbSize := Sizeof(exInfo);
      fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT;
      lpFile := 'cmd.exe';
      lpParameters := '/c Openfiles.exe /query /s 127.0.0.1 /nh >c:\OpenFilesExport.txt';
      nShow := SW_SHOWNORMAL;
    end;
    

    对于CreateProcess 选项,您需要通过调用CreateFile 创建文件,并将该句柄作为新进程的标准输出传递。您需要确保文件句柄是可继承的。最后,您需要等待该过程才能关闭文件句柄。

    关于您当前的代码,您的等待不是很愉快。这是一个不必要地消耗 CPU 的繁忙等待。您应该在进程句柄上使用阻塞等待。

    【讨论】:

    • 感谢您的回复。我尝试了调用 ShellExecuteEX 的解决方案 #1 并使用提供的代码,但在应该有数据时总是以零长度文件结束。
    • 还尝试了使用相同逻辑的不同命令('cmd.exe'、'/C find "Test" c:\SearchIn.txt > c:\SearchOut.txt')和导出文件生成正确的结果。
    • cmd /c 和 stdout 的重定向在我的测试中工作正常。我用ls.exe 进行了测试。我猜你只需要调试代码。我不知道 openfiles.exe 是什么。它是 GUI 子系统还是控制台子系统应用程序?无论如何,老实说,我认为我不能提供比这个答案更多的东西。很抱歉您没有发现它有帮助。
    • openfiles.exe 应用程序是 Windows\System32 区域中的控制台应用程序,用于查询工作站上打开的文件。我尝试使用您的示例代码启动的所有其他控制台应用程序都可以正常工作。 OpenFiles.exe 似乎是个例外。还尝试将 OpenFiles 命令添加到 bat 文件中。从资源管理器启动时,它会生成文件,但使用 shellexecute 启动 bat 文件时,它总是会创建一个零长度的导出文件。
    • 可能的 32/64 位问题。如果父进程是 32 位,它可能需要在 syswow64 中。但是,如果您将文件放在系统目录中,那么您就做错了。别那样做。将文件放在其他地方。
    猜你喜欢
    • 2012-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    • 2011-12-19
    相关资源
    最近更新 更多