2013-02-19 21 views
1

我想運行一個使用CreateProcess(...)的進程並在獨立的控制檯窗口中獨立運行它。CreateProcess在Windows 7下不會創建額外的控制檯窗口?

我可以使用system(「...」)函數實現這個功能,但我更喜歡CreateProcess,因爲它使我可以指定環境和工作目錄,獲取進程的句柄以及管道stdin /當我需要的時候。

我在互聯網上發現的所有問題都是相反的問題,即人們有額外的控制檯窗口並希望擺脫它們!看來在早期版本的Windows中打開並顯示新的控制檯窗口是正常行爲?

現在,我無法獲得額外的窗口,即使我跑「的cmd.exe/c ...」

我嘗試使用STARTF_USESHOWWINDOW標誌,沒有運氣。

有沒有人有這個問題?

PS .:顯示GUI窗口,例如: notepad.exe將正常顯示。

這是我的代碼(本質)

PROCESS_INFORMATION processInfo; 
STARTUPINFOA startupInfo; 
ZeroMemory(&startupInfo,sizeof(startupInfo)); 
startupInfo.dwFlags |= CREATE_NEW_CONSOLE; 
startupInfo.dwFlags |= DETACHED_PROCESS; 
ok&=CreateProcessA(NULL, 
    const_cast<char*>(comand.c_str()), // safe for CreateProcessA 
    NULL, NULL, TRUE, NULL, NULL, NULL, 
    &startupInfo, &processInfo); 

我試圖運行C:/Windows/system32/cmd.exe/C有助於 的程序運行,並可以閱讀從輸出管。還沒有窗戶。

回答

10

在使用Win32 API時,MSDN真的是你最好的朋友。現在,您的相關創建標誌如下:

(no flags set) - 子進程(使用CreateProcess()啓動的進程)將與父進程(稱爲CreateProcess()的進程)共享控制檯。

CREATE_NEW_CONSOLE - 子進程將收到一個新的控制檯,在新窗口中打開。正如MSDN明確指出的那樣,此標誌不能與DETACHED_PROCESS一起使用!而這正是你想使用的標誌。

CREATE_NO_WINDOW - 子進程將收到一個新的控制檯,但沒有任何窗口。這是一個令人驚訝的標誌,所以我會再次重申它:子進程將有一個控制檯,您可以在其中編寫輸出,從中可以嘗試讀取輸入等;這個控制檯不同於父進程的控制檯;這個控制檯是不可見的,它沒有可見的窗口,但它存在。這對於在後臺靜靜地運行子進程很有用。請注意,與CREATE_NEW_CONSOLEDETACHED_PROCESS一起使用時,此標誌無效 - 這些標誌覆蓋此標誌。另請注意,啓動GUI應用程序時會忽略此標誌:它不會收到不可見的控制檯。

DETACHED_PROCESS - 子進程將不會收到任何控制檯。 您不能將此標誌與CREATE_NEW_CONSOLE一起使用。

現在更多地關於正確調用CreateProcess()。首先,你應該使用CreateProcessW()。我特別厭倦了無法訪問名爲日本語αβηλ的目錄中的文件的應用程序。

其次,即使您使用ANSI版本,如果您通過NULL環境,則指定CREATE_UNICODE_ENVIRONMENT標誌。如果你不這樣做,PATH最終可能會在子進程中崩潰,而且這個bug非常煩人。第三,不要const_cast<char*>command.c_str()。只需撥打strdup()/wcsdup()就可以了,然後free()CreateProcess()調用返回後。或者如果您確實堅持要修改command,請將&command[0]作爲參數。

四,別忘了設置你的STARTUPINFO結構尺寸:startupInfo.cb = sizeof(startupInfo)。現代Windows(至少XP和7)實際上允許你將這個字段設置爲零而不會產生任何有害後果,但是依賴於此,這是一個不太現實的編程。

哦,雖然我們在這裏:你提到你使用CreateProcess(),因爲它允許你明確地指定孩子的環境。那麼,有一個關於lpEnvironment參數的小問題,這個參數有文檔記載,但很容易被忽略。當您指定NULL時,子代繼承父代的環境。當你指定一些非NULL,父母的環境不會被添加到它。如果你想添加到父母的環境中,你必須使用GetEnvironmentStrings()來獲得它,然後明確地調整它。

2

通過CREATE_NEW_CONSOLEdwCreationFlags時致電CreateProcess。我沒有測試,但我懷疑這迫使創建一個控制檯窗口(可能甚至是非控制檯進程?)您也可以使用DETACHED_PROCESS,而不是從父控制檯分離。