我根据创建带有重定向输入和输出的子进程文章创建了一个程序,但是它无法使用std::cout和printf,因此从这样的程序中我只获得了“Hello, momma”字符串,cout和printf部分没有任何输出:
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
const char *buffer = "Hello, momma";
std::cout << buffer << " - iostream version\n";
printf("%s - stdio version", buffer);
DWORD dwWritten = 0;
WriteFile(hStdOut, buffer, strlen(buffer), &dwWritten, NULL);
return 0;
}
问:我如何拦截cout和printf输出?我无法访问子程序的源代码,只需要拦截其输出。
如果仅运行子进程,则输出如下:
Hello, momma - iostream 版本
Hello, momma - stdio 版本Hello, momma
因此,您可以看到所有三个版本都已打印。
根据要求,这是父程序的代码:
void RedirectIO(HANDLE &hRead, HANDLE &hWrite)
{
SECURITY_ATTRIBUTES attr;
ZeroMemory(&attr, sizeof(attr));
attr.nLength = sizeof(attr);
attr.bInheritHandle = true;
CreatePipe(&hRead, &hWrite, &attr, 0);
SetHandleInformation(hRead, HANDLE_FLAG_INHERIT, 0);
}
bool CreateChild(std::string CommandLine, DWORD WaitTime, HANDLE hInRead, HANDLE hOutWrite)
{
STARTUPINFO SI;
PROCESS_INFORMATION PI;
ZeroMemory(&SI, sizeof(SI));
ZeroMemory(&PI, sizeof(PI));
SI.cb = sizeof(SI);
SI.hStdError = hOutWrite;
SI.hStdInput = hInRead;
SI.hStdOutput = hOutWrite;
SI.dwFlags |= STARTF_USESTDHANDLES;
bool success = CreateProcess(0, const_cast<char*>(CommandLine.c_str()), 0, 0, true, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, 0, 0, &SI,&PI);
if (success)
{
WaitForSingleObject(PI.hProcess, WaitTime);
CloseHandle(PI.hProcess);
CloseHandle(PI.hThread);
}
return success;
}
int main()
{
HANDLE hRead = nullptr;
HANDLE hWrite = nullptr;
RedirectIO(hRead, hWrite);
CreateChild("stdouterrin.exe", INFINITE, nullptr, hWrite);
DWORD ReadCount = 0;
char Buffer[1024] = {0};
std::string data = std::string();
while(true)
{
if (!ReadFile(hRead, Buffer, sizeof(Buffer) / sizeof(char), &ReadCount, 0))
break;
if (!ReadCount) break;
Buffer[ReadCount] = '\0';
data.append(&Buffer[0], ReadCount);
std::cout<<"Read From Child:\n\n"<<data.c_str()<<"\n";
}
return 0;
}
strlen()
有什么问题吗?当然WriteFile()
不使用它,因为传递给WriteFile()
的输入缓冲区不一定是以空字符结尾的字符串。相反,WriteFile()
依赖于调用者知道如何计算正确的长度,在这种情况下,strlen()
是正确的方法。 - bames53strlen()
更容易出错。只要他使用char *
,那么strlen()
是最好的选择。也许你建议使用std::string
,在这种情况下,我通常赞同。 - bames53