c# - 使用 AllocConsole 和目标体系结构 x86 时没有控制台输出

标签 c# .net pinvoke

我有一个 WinForms 项目,如果用户想要一个调试控制台,我会使用 AllocConsole() 分配一个控制台。

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

我也试过this回答,但是没有用,我也试了Console.SetOut(GetStdHandle(-11)),也没用。

将目标架构设置为“任何 CPU”对我来说不是一个选项。

所以这是我的两个问题:

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

最佳答案

启用“启用 native 代码调试”时,使用 AllocConsole 打包的控制台的输出将重定向到调试输出窗口。

这只发生在 x86 而不是 AnyCPU 的原因是因为您只能在 x86 应用程序中调试 native 代码。

请注意,此行为仅发生在使用 AllocConsole 创建的控制台上。控制台应用程序的输出不会被重定向。

编辑:控制台不输出文本的另一个原因是您在调用 AllocConsole 之前写入了控制台。

无论出于何种原因,如果重定向,此代码将恢复输出,并在无效时重新打开控制台。它使用魔数(Magic Number) 7stdout 的句柄通常等于此值。

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();
}

参见 How to detect if Console.In (stdin) has been redirected?另一种检测控制台句柄是否已重定向的方法。

关于c# - 使用 AllocConsole 和目标体系结构 x86 时没有控制台输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15604014/

相关文章:

c# - Unity3D - 选择哪种网络解决方案?

.net - 颠覆忽略模式效果不佳

c# - 获取传递给子模块 (C#.NET dll) 内的主模块 (VC++ exe) 的参数

c# - 异常 : System. DllNotFoundException - 使用 .NET Core 2.1 调用 CoolProp( native C++ 库)函数

c# - Ajax 错误 - 在 ASP.NET MVC 应用程序中抛出错误

c# - 我想从 C# 中的文本文件中读取一些双数据

c# - 为什么我的 winform 在打开 Access 数据库 (.accdb) 时会调整大小,我该如何解决?

c# - 在 Unity : Best practice 中解析类型时传递构造函数参数

c# - 如何明确、精确地控制构图范围?

C# p/invoke,从所有者绘制的列表框中读取数据