1

我有 3 个程序,App1.exe、App2.exe 和 App3.exe。每个都可以彼此独立运行,但 App2.exe 可以使用 ShellExecuteEx 运行 App3.exe,而 App1.exe 可以使用 ShellExecuteEx 运行 App2.exe(后者又可以运行 App3)。App3 有可选的命令行参数,如果使用 GUI 将不会显示,但会自动生成输出文件并关闭。当 App2 运行 App3 传递命令行参数时,它工作得很好,但是当 App1 运行 App2 时,App2 运行 App3 传递命令行参数,App3 的 ShellExecuteEx 返回 true,但 GUI 显示并且不创建输出文件。
你知道为什么会发生这种情况吗?它确实适用于 Windows XP,但不适用于 Vista 或 7。我也尝试使用 CreateProcess(),它给出了相同的结果。所有 3 个应用程序都在同一个文件夹中。

FillChar( exInfo, Sizeof(exInfo), 0 );
with exInfo do
begin
  cbSize:= Sizeof( exInfo );
  fMask := SEE_MASK_NOCLOSEPROCESS;
  lpVerb:= 'open';
  lpFile:= PChar('App3.exe');
  lpParameters := PChar('/Param1 Param2 "' + folderpath + 'outputfile.txt"');
  nShow := SW_HIDE;
end;
if ShellExecuteEx( @exInfo ) then
begin
  repeat
    Sleep( 500 );
    GetExitCodeProcess( exinfo.hProcess, exitcode )
  until (exitcode <> STILL_ACTIVE);
end;
CloseHandle( exinfo.hProcess );
4

1 回答 1

4

当 App2 运行 App3 时,无论 App2 是直接运行还是由 App1 运行,App3 都会以完全相同的方式运行。因此,运行 App2 的 App1 不会影响 App2 运行 App3 的方式。

受影响的是App2的初始工作目录,因此也影响了 App3 的初始工作目录。因此,您应该始终使用绝对路径,不仅用于参数值,还用于 .exe 路径。您还应该考虑使用该SHELLEXECUTEINFO.lpDirectory字段来指定初始工作目录。因此,您的应用程序在工作时不可能在错误的目录中查找。

话虽如此,如果您仍然有同样的问题,那么我建议您让 App3 输出它收到的实际命令行参数(MessageBox()、OutputDebugString()、文件等)。它可能会收到与您预期不同的东西,或者它可能会错误地解析参数。

最后,附带说明一下,您可以Sleep()+GetExitCodeProcess()用一次调用替换循环WaitForSingleObject()(或者MsgWaitForMultipleObjects()如果您需要在等待时运行消息循环),然后在需要时调用GetExitCodeProcess()一次以获得最终结果:

if ShellExecuteEx( @exInfo ) then
begin
  if WaitForSingleObject(exinfo.hProcess, INFINITE) = WAIT_OBJECT_0 then
    GetExitCodeProcess( exinfo.hProcess, exitcode );
  CloseHandle( exinfo.hProcess );
end;
于 2013-08-23T21:02:03.807 回答