2012-11-16 96 views
5

我試圖從使用CreateProcessAsUser()API類似於this code的服務啓動用戶模式進程。我的代碼在99%的時間內工作正常,除了API成功時,我從PROCESS_INFORMATION結構中獲得流程句柄,但流程本身未出現在我打算運行的交互式用戶會話中。CreateProcess成功,但GetExitCodeProcess返回C0000142

有趣的是,如果我在進程句柄上調用GetExitCodeProcess(),它將返回代碼0xC0000142。任何想法爲什麼?

+0

發生故障時,您是否可以啓動子進程?您嘗試啓動的.exe是否有可能取決於缺少的DLL? –

+1

返回碼肯定適合行爲,它是STATUS_DLL_INIT_FAILED。這當然會阻止這個過程的開始。它使用的DLL之一從其DllMain()入口點返回FALSE。您需要在開發機器上重新制作這個文件,以便調試它。 –

+0

@HansPassant和MichaelSh謝謝你的建議。我需要嘗試登錄到該用戶會話並查看是否可以手動啓動進程。問題是它不會一直髮生......但是,我的問題是爲什麼CreateProcessAsUser()返回TRUE,當它顯然不啓動任何東西? – ahmd0

回答

6

錯誤0xC0000142是STATUS_DLL_INIT_FAILED(我使用Error Code Lookup Tool確定了這一點)。快速谷歌發現this question,它說:

這個問題的最常見的原因是鏈接到user32.dll一個方案是在它不能跟系統的窗口站和桌面環境中運行。通常,代理等服務運行在其自己的窗口工作站和桌面上,並且user32程序運行正常,但是任何顯示對話框的程序都將掛起,而沒有任何人看到錯誤消息或關閉對話框的機會。

因此,如果您沒有使用user32.dll中的任何函數,則應該刪除該依賴項。如果你正在使用該DLL,那麼我不確定你應該做什麼。一種選擇是使用LoadLibrary動態加載DLL,並在成功時使用它(即,您有一個有效的窗口會話),或者在故障模式下故障時回退。

+0

謝謝。我會盡力。雖然它不難使用user32.dll,你知道...我的代碼肯定不會顯示任何用戶內容。所有它,它打開一個全局命名事件並設置它,然後返回錯誤代碼中的結果。 – ahmd0

+0

如果您運行的是完整性較低的進程,但是如果運行從服務啓動的中等完整性(或更高),則會發生類似這樣的任何原因? –

+0

Upvote爲鏈接到錯誤代碼查找工具,因爲錯誤代碼的搜索是一個痛苦的屁股這些天。 –

5

CreateProcess ...()API將返回TRUE,如果它們可以成功創建內部過程對象並且begin初始化;他們不會等待進程加載並開始運行其可執行映像。在某些情況下,後來的初始化失敗了,但從內核的角度來看,它仍然是一個成功的流程創建。

+0

好點。謝謝。那麼,知道我的流程已經開始「確定」的正確途徑是什麼? – ahmd0

+0

除非您可以通過管道或其他方式直接與進程通信,否則我相信最好的方法是在CreateProcess()之後等待一下並調用GetExitCodeProcess()來檢查STILL_ACTIVE返回碼。 – HerrJoebob

+0

或使用'WaitForInputIdle()'。 –