将CreateProcess输入流重定向到文件

时间:2017-08-25 09:16:14

标签: c++ windows c++11 createprocess

我正在使用CreateProcess替换我的代码中的system()调用。我正在使用:

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

我将其代替:

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;
}

原因是我需要控制允许进程运行多长时间(在这种情况下为2000ms),但似乎此方法不起作用。 我正在将进程的输入重定向到我想要输入的文件的句柄(替换&lt;运算符),但进程没有收到任何内容。但它会在单独的控制台中启动xfoil.exe。

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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 ,否则默认输入是键盘缓冲区