WPF:将调试信息输出到控制台

在调试WPF项目时,需要把调试信息输出到Console。除了更改项目输出类型为控制台应用程序外,还可以使用API函数:AttachConsole、AllocConsole和FreeConsole。其中AllocConsole和FreeConsole函数配合使用可以打开/关闭控制台,使用起来更加灵活,优先推荐。下面逐一介绍三种方案。

方案1:修改项目输出类型

在项目属性设置里面,把输出类型改为控制台应用程序,如下图所示:

WPF:将调试信息输出到控制台_第1张图片
修改输出类型
运行生成的项目时,会打开一个控制台窗口,此时项目中所有的 Console.WriteLine();语句输出内容都会打印到控制台里面,效果如下:
WPF:将调试信息输出到控制台_第2张图片
输出效果

方案2:使用AllocConsole和FreeConsole

使用AllocConsole和FreeConsole这种方式最为灵活,可以用AllocConsole新建一个控制台用于打印,然后用FreeConsole关闭它。需要注意的是一个进程只能新建一个控制台。
参考链接:

  • AllocConsole:https://docs.microsoft.com/en-us/windows/console/allocconsole
  • FreeConsole:https://docs.microsoft.com/en-us/windows/console/freeconsole

使用时需要先导入API函数。

/// 
/// Allocates a new console for current process.
/// 
[DllImport("kernel32.dll")]
public static extern Boolean AllocConsole();

/// 
/// Frees the console.
/// 
[DllImport("kernel32.dll")]
public static extern Boolean FreeConsole();

下面介绍一个简单例子,窗口加载时打开一个控制台,关闭时释放控制台,并用定时器定时打印数据:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace Embed
{
    /// 
    /// MainWindow.xaml 的交互逻辑
    /// 
    public partial class MainWindow : Window
    {
        /// 
        /// Allocates a new console for current process.
        /// 
        [DllImport("kernel32.dll")]
        public static extern Boolean AllocConsole();

        /// 
        /// Frees the console.
        /// 
        [DllImport("kernel32.dll")]
        public static extern Boolean FreeConsole();
        
        public MainWindow()
        {
            InitializeComponent();
 
            Loaded += MainWindow_Loaded;
            Closed += MainWindow_Closed;
            
            var timer = new DispatcherTimer
            {
                Interval = TimeSpan.FromSeconds(1)
            };
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            Debug.WriteLine("Debug");
            Trace.WriteLine("Trace");
            Console.WriteLine("Console");
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            AllocConsole();
        }

        private void MainWindow_Closed(object sender, EventArgs e)
        {
            FreeConsole();
        }
    }
}

运行结果同上,与第一个方案相比,方案2可以以编程的方式打开/关闭控制台,使用起来更加灵活方便。

方案3:使用AttachConsole

AttachConsole是把输出附加到指定控制台上。

[DllImport("Kernel32.dll", EntryPoint = "AttachConsole", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern void AttachConsole(int dwProcessId);

dwProcessId = -1,表示使用当前进程的父进程控制台;当dwProcessId = pid,表示使用指定进程的控制台,参考文档见https://docs.microsoft.com/en-us/windows/console/attachconsole。

下面介绍一个简单用法:使用控制台运行WPF程序,并将输出附加到当前控制台上。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace Embed
{
    /// 
    /// MainWindow.xaml 的交互逻辑
    /// 
    public partial class MainWindow : Window
    {
        [DllImport("Kernel32.dll", EntryPoint = "AttachConsole", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern void AttachConsole(int dwProcessId);

        public MainWindow()
        {
            InitializeComponent();

            AttachConsole(-1);

            var timer = new DispatcherTimer
            {
                Interval = TimeSpan.FromSeconds(1)
            };
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            Debug.WriteLine("Debug");
            Trace.WriteLine("Trace");
            Console.WriteLine("Console");
        }
    }
}

运行结果:
WPF:将调试信息输出到控制台_第3张图片
AttachConsole运行结果

版权声明:本文为「txfly」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://www.jianshu.com/p/443d4f749101

你可能感兴趣的