2013-08-23 48 views
1

我有3個程序,App1.exe,App2.exe和App3.exe。每個都可以彼此獨立運行,但App2.exe可以使用ShellExecuteEx運行App3.exe,並且App1.exe可以使用ShellExecuteEx運行App2.exe(進而可以運行App3)。當使用GUI時,App3具有可選的命令行參數,但不會顯示,但會自動生成輸出文件並關閉。當App2運行App3傳遞命令行參數時,它工作得很好,但是當App1運行運行App3的App2傳遞命令行參數時,App3的ShellExecuteEx返回true,但GUI顯示並且不會創建輸出文件。
你知道爲什麼會發生這種情況嗎?它可以在Windows XP上工作,但它不在Vista或7上。我也嘗試使用CreateProcess(),它給出了相同的結果。所有3個應用程序都在同一個文件夾中。從EXE EXE執行EXE

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

當App2運行App3時,無論App2是直接運行還是通過App1運行,App3都以完全相同的方式運行。所以運行App2的App1無法影響App3如何運行App2。

什麼CAN受到影響是App2的初始工作目錄,因此也是App3的初始工作目錄。所以你應該總是使用絕對路徑,不僅僅用於參數值,而且也用於.exe路徑。您還應該考慮使用SHELLEXECUTEINFO.lpDirectory字段來指定初始工作目錄。就這樣,你的應用程序不可能在工作時看到錯誤的目錄。這就是說,如果你仍然有同樣的問題,那麼我建議你讓App3輸出它接收到的實際命令行參數(MessageBox(),OutputDebugString(),一個文件等)。它可能正在接收與您所期望的不同的東西,或者它可能會錯誤地解析參數。

最後,在一個側面說明,你可以到WaitForSingleObject()(或MsgWaitForMultipleObjects()如果你需要同時等待運行的消息循環)的單次調用替換您Sleep()+GetExitCodeProcess()循環,然後調用GetExitCodeProcess()一次事後得到最終結果,如果需要:

if ShellExecuteEx(@exInfo) then 
begin 
    if WaitForSingleObject(exinfo.hProcess, INFINITE) = WAIT_OBJECT_0 then 
    GetExitCodeProcess(exinfo.hProcess, exitcode); 
    CloseHandle(exinfo.hProcess); 
end; 
+0

問題肯定是工作目錄。更改代碼以傳遞完整文件路徑後,它可以很好地工作。 –