问题描述
编辑:刚刚发现这只是PowerShell控制台的问题。它似乎可以从cmd.exe运行。正在调查更多...
在Windows GUI(/ SUBSYstem:WINDOWS)应用程序中,附加或创建控制台相对容易,只需将WriteFile插入到stdout。 (如果要使用标准的C / C ++ API,例如How do I get console output in C++ with a Windows program?,可以参与其中,但是如果使用Win32 API WriteFile,这似乎很简单)。
但是我注意到重定向stdout时,该代码在控制台应用程序中工作正常,如果是GUI应用程序,则会炸毁。
下面是基本代码(或在https://github.com/billti/WinCons上查看完整的示例)。只需将以下内容作为头文件包括在内,WinMain
实例化该类后不久,调用CreateConsole
,则对Write
的任何调用都将失败,并带有标记为***
的错误–但仅在重定向输出时启动(例如myapp.exe > .\log.txt
)。如果未重定向,它可以正常工作,并且在控制台应用程序中,任何一种方法都可以正常工作。
注意:附加到父控制台可能会导致交错输出混淆,但是确实可以。
任何想法如何解决这个问题?如何从非控制台Windows应用程序重定向标准输出才能正常工作?
#include <string>
class Log
{
public:
void CreateConsole() {
// In a console app,redirected or not,this returns a valid handle.
// In a non-redirected GUI app,this returns NULL.
// If redirected GUI (e.g. "winapp.exe > .\log.txt") this returns a valid handle.
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hStdOut == NULL || hStdOut == INVALID_HANDLE_VALUE) {
// If launched from a console,then Attach work,else must Alloc.
if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
if (!AllocConsole()) {
throw std::exception("Failed to allocate a console");
}
}
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hStdOut == INVALID_HANDLE_VALUE || hStdOut == NULL) {
throw std::exception("Invalid stdout");
}
}
hasConsole = true;
}
void Write(const std::string& msg) {
DWORD written = 0;
DWORD err = 0;
if (hasConsole) {
if (!WriteFile(hStdOut,msg.c_str(),msg.length(),&written,nullptr)) {
// *** If output is being redirected in a GUI app,this always fails with ***
// 0xE8 ERROR_NO_DATA "The pipe is being closed."
err = GetLastError();
throw std::exception("Failed to write to console");
}
}
}
private:
bool hasConsole = false;
HANDLE hStdOut = INVALID_HANDLE_VALUE;
};
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)