c win32 api - GetStdHandle(STD_OUTPUT_HANDLE)无效,非常令人困惑

Ali*_*Ali 2 c winapi

我在WinMain中有以下片段,我从控制台启动这个GUI应用程序.我想将输出重定向到启动我的应用程序的控制台.我得到"句柄无效".GetStdHandle()之后的错误.

但是,如果我使用AllocConsole而不是AttachConsole,它可以正常工作.另外,如果我使用STD_ERROR_HANDLE而不是STD_OUTPUTHANDLE,那么fprintf(stderr,"errror")工作正常.

我看到一个博客条目有同样的问题,但没有解决方案.我在64位Windows 7上使用vc 2010编译器.

谢谢!

bConsole = AttachConsole(ATTACH_PARENT_PROCESS) != FALSE;

if (bConsole)
{
    int fd = 0;
    long lStdOut;
    lStdOut = (long)GetStdHandle(STD_OUTPUT_HANDLE);
    fd = _open_osfhandle(lStdOut, _O_TEXT);
    if (fd > 0)
    {
        *stdout = *_fdopen(fd, "w");
        setvbuf(stdout, NULL, _IONBF, 0 );
    }
}
printf("Test!!!!!!!!!!!!");
Run Code Online (Sandbox Code Playgroud)

Ben*_*igt 6

AttachConsole确实将您的流程与控制台关联,但stdout已经打开(并连接到旧句柄,无论它是什么).

stdout直接覆盖是一个糟糕的主意.相反,你必须freopen("CONOUT$", "w", stdout);得到stdout去到控制台.

但是还有很多其他细节.看看我的问题从cygwin shell启动时写入stdout的地方是什么,没有重定向来解决问题中的问题,然后询问有关某些极端情况的问题.最后是一个包含所有内容的代码示例.


Ben*_*Ben 5

一个的Windows子系统进程(即一个有WinMain)不会有STDOUT,STDERR或STDIN,除非有人专门给一个上推出。假设是因为它是Windows程序,所以您正在通过Windows与之交互。

即GetStdHandle不会将句柄返回到STDOUT,因为您没有STDOUT。

要给它一个,可以这样启动它:

winprog.exe > output.txt 2>&1
Run Code Online (Sandbox Code Playgroud)

如果以这种方式启动,它将同时具有STDOUT和STDERR,它们都将进入命名文件。

正如其他用户已经指出的那样,AttachConsole将为您提供一个控制台(最近的unix / linux等效为TTY),但不会为您提供STDOUT。如果您想要一个,则必须将其设置为单独的步骤。如果您希望它成为控制台,您也可以拥有它。

另一方面,默认情况下,控制台子系统程序(带有的一个main)会将STDIN,STDOUT和STDERR都设置为控制台。您可以从控制台中分离该进程,并根据需要关闭它们。