如何在Windows应用程序中将输出句柄设置为已打开的控制台

时间:2017-08-06 17:32:52

标签: c# winforms

我有一个WinForm项目,它打开一个调试控制台。这在C ++游戏开发中非常常见。当我在C#中尝试这个时,我没有得到理想的结果。我认为这是因为我需要将标准输出设置到控制台。

我跟着这个: http://vbcity.com/blogs/jatkinson/archive/2010/02/17/windows-interop-inside-kernel32-part-1-allocconsole-amp-createhardlink.aspx

虽然它使用了Console.WriteLine(),但它会跳过将输出句柄设置为控制台。如何在C#中设置它?

我的代码:

namespace MVS
{
    public partial class frmMVS : Form
    {
        [DllImport("kernel32")]
        static extern bool AllocConsole();

        public frmMVS()
        {
            InitializeComponent(); 

            AllocConsole(); 
            Console.WriteLine("Hello World!");
        } 
    }
}

当前尝试(虽然没有输出到控制台): 资料来源:No console output when using AllocConsole and target architecture x86

namespace MVS
{
    public partial class frmMVS : Form
    { 
        public frmMVS()
        {
            InitializeComponent();

            CreateConsole();

            Console.WriteLine("Hello World!");
        }

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

目前的解决方案: 目前,我目前的解决方案是删除所有这些互操作代码,并从我的Windows应用程序中将输出类型设置为控制台应用程序。这允许窗体和控制台并排工作。由于运行应用程序的用户也会看到控制台,因此请记住在发布之前将输出类型设置回Windows。由于控制台无论如何都用于调试,这似乎是一个简单的解决方案。我不知道在我开发时它会如何影响解决方案,所以另一种选择仍然是有意义的。

1 个答案:

答案 0 :(得分:0)

出于调试目的,这个简单的解决方案最终对我有效:

  

在Windows窗体项目中,1)转到项目 - >我的项目   属性 - >将输出类型从“Windows应用程序”设置为“控制台”   应用'。 2)保存,你就完成了。

现在您可以像通常使用Console.WriteLine()一样输出到控制台进行调试。

注意:确保在发布之前将输出类型切换回“Windows应用程序”,否则用户将看到控制台窗口。