我有3个程序,App1.exe,App2.exe和App3.exe。每种程序可以彼此独立运行,但是App2.exe可以使用ShellExecuteEx运行App3.exe,而App1.exe可以使用ShellExecuteEx(依次运行App3)运行App2.exe。如果使用App3,则App3具有可选的命令行参数,但GUI不会显示,但会自动生成输出文件并关闭。当App2运行通过命令行参数传递的App3时,它可以正常工作,但是当App1运行通过命令行参数传递参数的App2运行时,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 );
最佳答案
当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;