使用AllocConsole和目标体系结构x86时没有控制台输出 [英] No console output when using AllocConsole and target architecture x86

查看:132
本文介绍了使用AllocConsole和目标体系结构x86时没有控制台输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WinForms项目,并且如果用户想要一个调试控制台,则为控制台分配AllocConsole().

I have a WinForms project, and if the user want's a debug console, I allocate a console with AllocConsole().

所有控制台输出都可以在将目标体系结构设置为任何CPU"的情况下正常工作,但是当我将其更改为"x86"时,它不会输出任何内容(Console.Read()仍然可以正常工作).如果我直接打开EXE,则输出有效.看起来Visual Studio会将其重定向到自己的输出"窗口.

All console output works normally with the target architecture set to "Any CPU", but when I change it to "x86" it doesn't output anything (Console.Read() still works as expected). If I open the EXE directly, the output works. It looks like Visual Studio redirects it into it's own "Output" window.

我也尝试了答案,但没有没用,我也尝试了Console.SetOut(GetStdHandle(-11)),也没用.

I also tried this answer, but it didn't work, I also tried Console.SetOut(GetStdHandle(-11)), which didn't work either.

将目标体系结构设置为任何CPU"对我来说是没有选择的.

Setting the target architecture to 'Any CPU' is no option for me.

这是我的两个问题:

  • 为什么只有在目标体系结构设置为x86时才出现这种情况?
  • 在Visual Studio中运行时如何输出到控制台?

推荐答案

启用启用本机代码调试"后,由AllocConsole创建的控制台的输出将重定向到调试输出窗口.

When "Enable native code debugging" is enabled, output from consoles crated with AllocConsole is redirected to the debug output window instead.

之所以只在x86而不是AnyCPU中发生,是因为您只能在x86应用程序中调试本机代码.

The reason this only happens in x86 and not AnyCPU is because you can only debug native code in an x86 application.

请注意,此行为仅在使用AllocConsole创建的控制台中发生.控制台应用程序的输出未重定向.

Note that this behavior only occurs with consoles created with AllocConsole. A console application's output is not redirected.

控制台不输出文本的另一个原因是在调用AllocConsole之前已写入控制台.

The other reason for the console not outputting text is when you've written to the console before calling AllocConsole.

无论出于何种原因,此代码都将在重定向后恢复输出,并在无效时重新打开控制台.它使用魔术数字7 ,这通常是stdout的句柄.

Regardless of the reason, this code will restore output if it was redirected, and reopen the console in case it's invalid. It uses the magic number 7 which is what the handle of stdout usually equals to.

using System;
using System.IO;
using System.Runtime.InteropServices;

public static class ConsoleHelper
{
    public static void CreateConsole()
    {
        AllocConsole();

        // stdout's handle seems to always be equal to 7
        IntPtr defaultStdout = new IntPtr(7);
        IntPtr currentStdout = GetStdHandle(StdOutputHandle);

        if (currentStdout != defaultStdout)
            // reset stdout
            SetStdHandle(StdOutputHandle, defaultStdout);

        // reopen stdout
        TextWriter writer = new StreamWriter(Console.OpenStandardOutput()) 
        { AutoFlush = true };
        Console.SetOut(writer);
    }

    // P/Invoke required:
    private const UInt32 StdOutputHandle = 0xFFFFFFF5;
    [DllImport("kernel32.dll")]
    private static extern IntPtr GetStdHandle(UInt32 nStdHandle);
    [DllImport("kernel32.dll")]
    private static extern void SetStdHandle(UInt32 nStdHandle, IntPtr handle);
    [DllImport("kernel32")]
    static extern bool AllocConsole();
}

请参见如何检测Console.In( stdin)是否已重定向?用于检测控制台句柄是否已重定向的另一种方法.

See How to detect if Console.In (stdin) has been redirected? for another way to detect if the console handles have been redirected.

这篇关于使用AllocConsole和目标体系结构x86时没有控制台输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆