我需要从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?
最佳答案
您的问题是重定向>
,仅当您具有命令解释器时才有意义。而且在您的代码中您没有。您有两种选择:
调用ShellExecuteEx
并传递命令解释器以完成工作。
使用CreateProcess
执行其他进程,但是将一个句柄作为新进程的stdout句柄传递给文件。
对于命令解释器选项,您将具有以下命令行:
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
的调用来创建文件,并将该句柄作为新进程的stdout传递。您需要确保文件句柄是可继承的。最后,您将需要等待该过程,以便关闭文件句柄。关于您当前的代码,您的等待不是很愉快。这是一个繁忙的等待,不必要地消耗了CPU。您应该在进程句柄上使用阻塞等待。
关于delphi - 如何从Delphi XE2 ShellExecute启动OpenFiles.exe?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20020450/