Win32:确定stdout句柄是char还是wchar流
我正在为我们的产品编写一个 win32 实用程序函数,该函数需要通过 shell 调用任意程序并记录其输出。 我们通过将标准输出从子进程重定向到管道来实现此目的:
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
CreatePipe(&hReadPipe, &hWritePipe, &saAttr, 0);
// Redirect the first process stdout to our write pipe
// so that we can read its output from the read pipe.
startUpInfo.dwFlags = STARTF_USESTDHANDLES;
startUpInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
startUpInfo.hStdOutput = hWritePipe;
startUpInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
CreateProcessA(NULL, szCmdLine, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startUpInfo[i], &procInfo);
有多种程序可以通过这种方式调用,其中许多程序不受我们的控制。 目前,我们遇到一个问题,许多程序的输出似乎在第一个字符之后被截断——这通常是 WCHAR 字符串被错误地用作 CHAR 的明确标志。
如何判断子进程是否以 CHAR 或 WCHAR 形式写入其标准输出管道?
I'm writing a win32 utility function for our product that needs to call an arbitrary program via the shell and log its output. We do this by redirecting the stdout from the child process into a pipe:
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
CreatePipe(&hReadPipe, &hWritePipe, &saAttr, 0);
// Redirect the first process stdout to our write pipe
// so that we can read its output from the read pipe.
startUpInfo.dwFlags = STARTF_USESTDHANDLES;
startUpInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
startUpInfo.hStdOutput = hWritePipe;
startUpInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
CreateProcessA(NULL, szCmdLine, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startUpInfo[i], &procInfo);
There are a wide variety of programs that may be called this way, many of which are not under our control. Currently we're seeing a problem where the output from many programs appears to be truncated after the first character---usually a sure sign that a WCHAR string is mistakenly being used as a CHAR.
How can I tell if the child process is writing to its stdout pipe as a CHAR or a WCHAR?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为当你联系时你必须协商这一点。 您可以使用 PeekNamedPipe() 并基于猜测如果它看起来像一个 unicode 字符...
I think you have to negotiate that when you connect. You could use PeekNamedPipe() and guess based on if it looks like a unicode character...
最重要的是,没有 100% 可靠的方法可以做到这一点。 进程的输入/输出句柄不是特定于编码的。 它们只是对字节流进行操作。 进程完全有可能暂时写入 ASCII,然后再切换到 Unicode。
不幸的是,不可能从字节流中 100% 准确地判断底层编码是什么。 确定这一点的唯一方法是采用握手协议,其中该过程会告诉您它将使用什么编码。 在这种情况下可能不是一个选择。
有关该主题的链接
The bottom line is there is no 100% reliable way to do this. The input/output handles of a process are not encoding specific. They simply operate on a stream of bytes. It's completely possible for a process to write ASCII for awhile and switch to Unicode later on.
Unfortunately it is not possible to tell from a stream of bytes with 100% accuracy what the underlying encoding is. The only way to determine this is to have a hand shake protocol where the process tells you what encoding it will use. Likely not an option in this case.
Links on the subject