从EXE从EXE执行EXE

时间:2013-08-23 14:16:43

标签: delphi windows-7 windows-vista delphi-2007 shellexecuteex

我有3个程序,App1.exe,App2.exe和App3.exe。每个可以彼此独立运行,但App2.exe可以使用ShellExecuteEx运行App3.exe,App1.exe可以使用ShellExecuteEx运行App2.exe(后者可以运行App3)。 App3具有可选的命令行参数,如果使用GUI将不会显示但会自动生成输出文件并关闭。当App2运行App3传递命令行参数时,它工作得很好,但是当App1运行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 );

1 个答案:

答案 0 :(得分:4)

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

CAN 会影响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;