我嘗試使用CreateProcess來運行一個簡單的命令,如hg > test.txt
。我嘗試將字符串作爲一個整體運行(而不是將它分離爲應用程序名稱及其參數)。爲什麼CreateProcess(0, "notepad.exe test.txt", ...)
能正常工作,CreateProcess(0, "hg > test.txt", ...)
不能?如何使用CreateProcess將輸出重定向到文件?
回答
您不能在傳遞給CreateProcess
的命令行中使用stdout重定向。要重定向標準輸出,您需要爲STARTUPINFO
結構中的輸出指定文件句柄。
你也在犯另一個更微妙的錯誤。第二個參數lpCommandLine
必須指向可寫內存,因爲CreateProcess
會覆蓋緩衝區。如果你碰巧使用的是ANSI版本的功能,那麼你會擺脫這一點,但不是爲了Unicode版本。
該函數的Unicode版本,CreateProcessW,可以修改這個字符串的內容。因此,此參數不能是指向只讀內存的指針(例如const變量或文字字符串)。如果此參數是一個常量字符串,則該函數可能會導致訪問衝突。
爲什麼你需要傳入一個可寫緩衝區:[爲什麼'CreateProcess'函數修改它的輸入命令行?](http://blogs.msdn.com/b/oldnewthing/archive/2009/06 /01/9673254.aspx) –
他不一定會犯第二個參數指向可寫內存的錯誤。有可能他沒有定義'UNICODE'編譯,在這種情況下'CreateProcess'是'CreateProcessA',它沒有這個要求。 –
@FrerichRaabe這是當前版本Windows的實現細節。如果你看看MSDN文檔,你會看到第二個參數的類型是'LPTSTR'。無論如何,我在第二段中提出了你的觀點。 –
CreateProcess()啓動進程,它不是命令行itnerpreter。它不知道「>」是什麼,也不會爲你做流重定向。您需要打開文件test.txt自己和句柄傳遞給它的STARTUPINFO結構內的CreateProcess: CreateProcess STARTUPINFO
微軟有一個例子如何重定向標準輸出: http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx。
是的,這種工作,但請記住,該示例中存在一個可防止「ReadFromPipe」退出的錯誤。在你調用這個函數之前,你需要調用:'CloseHandle(g_hChildStd_OUT_Wr);'。此外,您可能需要等待子進程退出,然後再關閉句柄以使用類似下面的方法進行處理:'WaitForSingleObject(piProcInfo.hProcess,INFINITE);'。 – Nux
下面的代碼創建一個無控制檯進程,stdout和stderr重定向到指定的文件。
#include <windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
HANDLE h = CreateFile(_T("out.log"),
FILE_APPEND_DATA,
FILE_SHARE_WRITE | FILE_SHARE_READ,
&sa,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
PROCESS_INFORMATION pi;
STARTUPINFO si;
BOOL ret = FALSE;
DWORD flags = CREATE_NO_WINDOW;
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags |= STARTF_USESTDHANDLES;
si.hStdInput = NULL;
si.hStdError = h;
si.hStdOutput = h;
TCHAR cmd[]= TEXT("Test.exe 30");
ret = CreateProcess(NULL, cmd, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi);
if (ret)
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
return -1;
}
旁邊的代碼說明會很方便。至少註釋 –
在子進程產生後文件可能的CloseHandle()被忽略。 – SerG
不應該hStdInput INVALID_HANDLE_VALUE而不是NULL? –
你應該用params「/ c命令行」運行進程cmd.exe。 這會將輸出重定向到一個文件或通過CreateProcess組織一個管道。
- 1. CreateProcess並重定向輸出
- 2. 將CreateProcess輸入流重定向到一個文件
- 3. 將ttisql輸出重定向到文件
- 4. 將execlp輸出重定向到文件
- 5. Ruby將輸出重定向到文件
- 6. 將lldb輸出重定向到文件
- 7. 將w輸出重定向到文件
- 8. 將ostream重定向到輸出文件
- 9. Windows CreateProcess和輸出重定向
- 10. 重定向輸出到輸出文件
- 11. 重定向vim:使輸出到文件
- 12. 如何將控制檯輸出重定向到文本文件
- 13. 如何將程序輸出重定向到文本文件
- 14. 如何將nosetests的輸出重定向到文本文件?
- 15. 使用PyQt5將qDebug輸出重定向到文件
- 16. 使用forfiles將輸出重定向到文件
- 17. 無法使用CreateProcess重定向標準輸出
- 18. Robot Framework:如何將控制檯輸出重定向到文件
- 19. 如何將某些NSLog輸出重定向到文件
- 20. 如何將gcc編譯器的輸出重定向到文件?
- 21. 如何將findstr的輸出重定向到一個文件?
- 22. 如何將輸出重定向到相同的文件?
- 23. kermit - 如何將輸出重定向到文件
- 24. 如何將Valgrind的輸出重定向到文件?
- 25. 如何將輸出重定向到Pester xml文件?
- 26. 如何將cu的輸出重定向到一個文件?
- 27. 如何將python腳本cmd輸出重定向到文件?
- 28. 如何將標準輸出重定向到Perl中的文件?
- 29. Xcode 5,如何將控制檯輸出重定向到文件
- 30. 如何將ubuntu終端輸出重定向到一個文件?
'CreateProcess'不知道重定向。你爲什麼不使用'system(3)'?讓我猜測:你可以做得比系統(3)更好。 – cnicutar
@cnicutar我一直想知道'函數(數字)'符號的含義。 'system(3)'是什麼意思? –
@Seth Carnegie手冊部分。 '人3系統'。 – cnicutar