2017-08-25 138 views
3

我使用CreateProcess來替換我的代碼中的system()調用。我用的是:將CreateProcess輸入流重定向到一個文件

system(xfoil.exe < create_results.txt"); 

對此我這個substituing:

PROCESS_INFORMATION ProcessInfo; //This is what we get as an [out] parameter 
STARTUPINFO StartupInfo; //This is an [in] parameter 

LPCWSTR input_file = _tcsdup(TEXT(".\\create_results.txt")); 

HANDLE inpfl = CreateFile(input_file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
StartupInfo.hStdInput = inpfl; 

ZeroMemory(&StartupInfo, sizeof(StartupInfo)); 
StartupInfo.cb = sizeof StartupInfo; //Only compulsory field 
LPCWSTR exe_path =_tcsdup(TEXT(".\\xfoil.exe")); 

if (CreateProcess(exe_path, NULL, 
    NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, 
    NULL, &StartupInfo, &ProcessInfo)) 
{ 
    WaitForSingleObject(&ProcessInfo.hProcess, 2000); 
    CloseHandle(ProcessInfo.hThread); 
    CloseHandle(ProcessInfo.hProcess); 
    CloseHandle(inpfl); 
} 

else 
{ 
    CloseHandle(inpfl); 
    std::cout << "Could not create xfoil process" << std::endl; 
} 

原因是我需要控制進程被允許跑了多久(在這種情況下,2000毫秒)的,但它似乎這種方法不起作用。 我將流程的輸入重定向到我希望作爲輸入的文件的句柄(替換<運算符),但該進程未收到任何內容。但它確實在單獨的控制檯中啓動了xfoil.exe。

+1

訂購事宜!你在哪裏設置'hStdInput',你在哪裏調用'ZeroMemory'? –

+1

你需要呼叫ZeroMemory * BEFORE *你分配給hStdInput –

+1

vtc作爲「簡單的印刷錯誤」 –

回答

3

您需要設置文件安全屬性,以允許繼承手柄和啓動信息標誌,使兒童的過程中使用手柄通過:

::STARTUPINFO startup_information{}; 

::SECURITY_ATTRIBUTES security_attributes 
{ 
    sizeof(::SECURITY_ATTRIBUTES) 
, nullptr 
, TRUE // allow handle to be inherited 
}; 

::HANDLE const inpfl{::CreateFileW(input_file, GENERIC_READ, FILE_SHARE_READ, ::std::addressof(security_attributes), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)}; 
if(INVALID_HANDLE_VALUE == inpfl) 
{ 
    auto const last_error{::GetLastError()}; 
    // handle error... 
} 

startup_information.cb = sizeof(startup_information); 
startup_information.dwFlags = STARTF_USESTDHANDLES; 
startup_information.hStdInput = inpfl; 
+0

爲了完整起見,您應該提到原始代碼中有兩個* bug:不設置'dwFlags',並在分配'hStdInput'後調用'ZeroMemory'。 –

+1

@MartinBonner它實際上是三個錯誤:爲安全屬性提供空指針會導致句柄不可繼承,因此子進程將無法使用它。我猜想op無論如何已經知道'ZeroMemory'。 – VTT

+0

我正在嘗試這個解決方案,絕對看起來像正確的方向。 ZeroMemory是一個我沒有注意到的愚蠢錯誤。不知道國旗和安全屬性。 – Erdorath

0
PROCESS_INFORMATION ProcessInfo; //This is what we get as an [out] parameter 
STARTUPINFO StartupInfo; //This is an [in] parameter 

LPCWSTR input_file = _tcsdup(TEXT(".\\create_results.txt")); 

HANDLE inpfl = CreateFile(input_file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
StartupInfo.hStdInput = inpfl; 

發生StartupInfo.hStdInput什麼下次通話後?

ZeroMemory(&StartupInfo, sizeof(StartupInfo)); 

哎呀... hStdInput現在

歸零最初這樣做......

PROCESS_INFORMATION ProcessInfo = {}; 
STARTUPINFO StartupInfo = {}; 

...將阻止你需要到零什麼... see

此外,根據CreateProcess StartupInfo documentation,你必須爲hStdInput,集dwFlags中STARTF_USESTDHANDLES,否則默認輸入鍵盤緩衝區