WPFではコンソールを用いてログ情報を出力する

11550 ワード

一、背景
以前のプロジェクトでは、ログ情報をログ4 NETを使用してテキストファイルに出力していました.この方法は、以前のログ情報をよく見るのに適していますが、ログをリアルタイムで表示するのには適していません.Log 4 NETはappenderを構成することでこの問題を簡単に解決できると思っていた.仕方なく、個人レベルは限られており、コンソールプログラムでしか実現できないが、WPFアプリケーションではこの問題は解決されていない.その後、ソリューションをwin 32に転送します.win 32関数を呼び出すことでコンソールに直接情報を出力します.
二、解決策
ヘルプクラス
    public class ConsoleLogHelper
    {

        [System.Security.SuppressUnmanagedCodeSecurity]
        [DllImport("kernel32", CharSet = CharSet.Auto)]
        internal static extern bool AllocConsole();

        [System.Security.SuppressUnmanagedCodeSecurity]
        [DllImport("kernel32", CharSet = CharSet.Auto)]
        internal static extern bool FreeConsole();

        /// 
        ///
        /// 
        public static void OpenConsole()
        {
            try
            {
                var consoleTitle = "App Runtime Log";
                AllocConsole();
                Console.BackgroundColor = ConsoleColor.Black;

                Console.CursorVisible = false;
                Console.Title = consoleTitle;
            }
            catch (Exception)
            {
                throw;
            }
        }


        /// 
        ///
        /// 
        public static void CloseConsole()
        {
            FreeConsole();
        }

        public static void WriteLine(string msg)
        {
            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            Console.WriteLine(msg);
            Console.ForegroundColor = ConsoleColor.White;
        }
        public static void WriteLineError(string msg)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            WriteLine(msg);
        }

        public static void WriteLineError(Exception ex)
        {
            WriteLineError(ex.Message);
        }

        public static void WriteLineInfo(string msg)
        {
            Console.ForegroundColor = ConsoleColor.Cyan;
            WriteLine(msg);
        }

    }

使用 App.cs

    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            ConsoleLogHelper.OpenConsole();
        }

        protected override void OnExit(ExitEventArgs e)
        {
            base.OnExit(e);
            ConsoleLogHelper.CloseConsole();
        }
    }

MainWindowを使います.xaml
<Window x:Class="Log4Net_Appender_Console.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Log4Net_Appender_Console"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel>
            <Button Click="Button_Click_default"
                    Width="200"
                    Height="50">defaultButton>
            <Button Click="Button_Click_error"
                    Width="200"
                    Height="50">errorButton>
            <Button Click="Button_Click_exception"
                    Width="200"
                    Height="50">exceptionButton>
            <Button Click="Button_Click_info"
                    Width="200"
                    Height="50">infoButton>

        StackPanel>

    Grid>
Window>

MainWindowを使います.cs
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Excute(Action<int> action)
        {
            for (int i = 0; i < 10; i++)
            {
                action(i);
            }
        }

        private void Button_Click_default(object sender, RoutedEventArgs e)
        {
            Excute((i)=> {
                Console.WriteLine($"default-->{i.ToString()}");
            });
        }

        private void Button_Click_error(object sender, RoutedEventArgs e)
        {
            Excute((i) => {
                ConsoleLogHelper.WriteLineError($"error-->{i.ToString()}");
            });
        }

        private void Button_Click_exception(object sender, RoutedEventArgs e)
        {
            try
            {
                string a = null;
                a.ToString();
            }
            catch (Exception ex)
            {
                Excute((i) => {
                    ConsoleLogHelper.WriteLineError(ex);
                });
            }
        }

        private void Button_Click_info(object sender, RoutedEventArgs e)
        {
            Excute((i) => {
                ConsoleLogHelper.WriteLineInfo($"info-->{i.ToString()}");
            });
        }
    }

三、分析
コア関数AllocConsole()を使用して、現在のスレッドでコンソールを開きます.そしてConsoleを使う.WriteLine()は、情報をコンソールに出力します.