2014-07-21 33 views
1

成功調用CreateProcess後,我試圖使用GetModuleFileNameEx(lpApplicationName和lpCommandLine參數可能會變化或爲null,因此它們在這種情況下不可靠)獲取創建的進程的路徑。 問題在於GetModuleFileNameEx因錯誤6(ERROR_INVALID_HANDLE)而失敗,並將其緩衝區保留爲無效數據。我無法理解原因,因爲CreateProcess成功並且處理句柄應該在pi.hProcess中正確保存。當CreateProcess調用GetModuleFileNameEx後ERROR_INVALID_HANDLE

希望你能提前一點點亮一下,謝謝!

編輯:更新:我注意到,刪除CREATE_SUSPENDED也可以解決這個問題,但我需要該標誌集。我能怎麼做?

// Defining GetModuleFileNameExA function 
typedef DWORD (WINAPI *fGetModuleFileNameExA) 
(
    HANDLE hProcess, 
    HMODULE hModule, 
    LPSTR lpFilename, 
    DWORD nSize 
); 
//Load dinamically DLL function on program startup: 
fGetModuleFileNameExA _GetModuleFileNameExA = (fGetModuleFileNameExA) GetProcAddress(LoadLibraryA("Psapi.dll"), "GetModuleFileNameExA"); 

// **** OTHER UNRELATED CODE HERE **** 


PROCESS_INFORMATION pi; 

//This call succeeds 
if (!CreateProcessW(ApplicationName, 
        CommandLine, 
        NewProcess.lpProcessAttributes, 
        NewProcess.lpThreadAttributes, 
        NewProcess.bInheritHandles, 
        CREATE_SUSPENDED | CREATE_NEW_CONSOLE, 
        NULL, 
        CurrentDirectory, 
        &NewProcess.bufStartupInfo, 
        &pi) 
     ) MessageBoxA(0, "Error creating process", "", 0); 

    char ProcessPath[MAX_PATH]; 

//Problem here: call fails with error 6 
if (!_GetModuleFileNameExA(pi.hProcess, NULL, ProcessPath, MAX_PATH)) {GetLastError();} 

//Invalid data is displayed 
MessageBoxA(0, ProcessPath, "GetModuleFileNameEx",0); 
+0

刪除'CREATE_SUSPENDED'似乎是解決 –

+1

如果要創建暫停,那麼就沒有模塊信息又是因爲你沒有給進程一個機會加載任何模塊。 –

+1

由於你顯然沒有爲'CreateProcessW'的第一個參數傳遞NULL,你不知道可執行文件的文件名嗎? –

回答

2

CreateProcess documentation MSDN上:

注意函數的過程中已完成初始化之前返回。如果所需的DLL無法找到或無法初始化,則該過程將終止。要獲得進程的終止狀態,請致電GetExitCodeProcess

...

調用線程可以使用WaitForInputIdle功能要等到新的進程已完成初始化,並等待用戶輸入,沒有輸入掛起。這對於父進程和子進程之間的同步很有用,因爲CreateProcess無需等待新進程完成其初始化即可返回。例如,創建過程將在嘗試查找與新過程相關的窗口之前使用WaitForInputIdle。

Similar question