win32 确保从子进程正确读取所有数据
我想使用 WIN32 API CreateProcess 从另一个 C++ 应用程序启动一个控制台 C++ 应用程序。该子控制台应用程序返回一些结果,我想读取父应用程序中子进程的结果。这是我的代码。
void executeCommand(const std::string& lpCommandLine)
{
PROCESS_INFORMATION processInfo;
STARTUPINFOA startupInfo;
SECURITY_ATTRIBUTES saAttr;
HANDLE stdoutReadHandle = NULL;
HANDLE stdoutWriteHandle = NULL;
std::string outbuf;
DWORD bytes_read;
char tBuf[257];
DWORD exitcode;
BOOL bSuccess = FALSE;
memset(&saAttr, 0, sizeof(saAttr));
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// Create a pipe for the child process's STDOUT.
if (!CreatePipe(&stdoutReadHandle, &stdoutWriteHandle, &saAttr, 5000))
{
return;
}
// Ensure the read handle to the pipe for STDOUT is not inherited.
if (!SetHandleInformation(stdoutReadHandle, HANDLE_FLAG_INHERIT, 0))
{
return;
}
memset(&startupInfo, 0, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
startupInfo.hStdError = stdoutWriteHandle;
startupInfo.hStdOutput = stdoutWriteHandle;
startupInfo.wShowWindow = SW_HIDE;
startupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
startupInfo.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
if (!CreateProcessA(NULL, (LPSTR)lpCommandLine.c_str(), NULL, NULL, TRUE, CREATE_NEW_CONSOLE,
NULL,
0, &startupInfo,
&processInfo))
{
return;
}
CloseHandle(stdoutWriteHandle);
for (;;)
{
bSuccess = ReadFile(stdoutReadHandle, tBuf, 256, &bytes_read, NULL);
if (!bSuccess || bytes_read == 0)
{
break;
}
if (bytes_read > 0)
{
tBuf[bytes_read] = '\0';
outbuf += tBuf;
}
}
cmdOutput_ = outbuf;
if (WaitForSingleObject(processInfo.hProcess, INFINITE) != WAIT_OBJECT_0)
{
return;
}
if (!GetExitCodeProcess(processInfo.hProcess, &exitcode))
{
return;
}
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
现在我的问题是,ReadFile 是否有可能立即返回而不读取任何数据,或者不从子进程 stdout 读取完整数据并且仍然返回非零值(这是成功的)?
如果是这样,那么确保读取完整数据并且只有这样我才能继续父进程的最佳方法是什么?
I would like to launch one console c++ application from another c++ application with WIN32 API CreateProcess. This child console application returns some result and i want to read the result of child process in my parent application. Here is my code.
void executeCommand(const std::string& lpCommandLine)
{
PROCESS_INFORMATION processInfo;
STARTUPINFOA startupInfo;
SECURITY_ATTRIBUTES saAttr;
HANDLE stdoutReadHandle = NULL;
HANDLE stdoutWriteHandle = NULL;
std::string outbuf;
DWORD bytes_read;
char tBuf[257];
DWORD exitcode;
BOOL bSuccess = FALSE;
memset(&saAttr, 0, sizeof(saAttr));
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// Create a pipe for the child process's STDOUT.
if (!CreatePipe(&stdoutReadHandle, &stdoutWriteHandle, &saAttr, 5000))
{
return;
}
// Ensure the read handle to the pipe for STDOUT is not inherited.
if (!SetHandleInformation(stdoutReadHandle, HANDLE_FLAG_INHERIT, 0))
{
return;
}
memset(&startupInfo, 0, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
startupInfo.hStdError = stdoutWriteHandle;
startupInfo.hStdOutput = stdoutWriteHandle;
startupInfo.wShowWindow = SW_HIDE;
startupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
startupInfo.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
if (!CreateProcessA(NULL, (LPSTR)lpCommandLine.c_str(), NULL, NULL, TRUE, CREATE_NEW_CONSOLE,
NULL,
0, &startupInfo,
&processInfo))
{
return;
}
CloseHandle(stdoutWriteHandle);
for (;;)
{
bSuccess = ReadFile(stdoutReadHandle, tBuf, 256, &bytes_read, NULL);
if (!bSuccess || bytes_read == 0)
{
break;
}
if (bytes_read > 0)
{
tBuf[bytes_read] = '\0';
outbuf += tBuf;
}
}
cmdOutput_ = outbuf;
if (WaitForSingleObject(processInfo.hProcess, INFINITE) != WAIT_OBJECT_0)
{
return;
}
if (!GetExitCodeProcess(processInfo.hProcess, &exitcode))
{
return;
}
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
Now my question is, is there possibility that ReadFile returns immediately without reading any data, or without reading complete data from child process stdout and still return non-zero value (which is success)?
If so, then what is the best way to make sure that the complete data is read and only then i can continue parent process?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论