program tip

WPF 애플리케이션에서 콘솔로 출력되지 않습니까?

radiobox 2020. 8. 21. 07:29
반응형

WPF 애플리케이션에서 콘솔로 출력되지 않습니까?


매우 간단한 WPF 테스트 응용 프로그램에서 Console.WriteLine ()을 사용하고 있지만 명령 줄에서 응용 프로그램을 실행하면 콘솔에 아무것도 기록되지 않습니다. 여기서 무슨 일이 벌어 질지 아는 사람이 있습니까?

VS 2008에서 WPF 응용 프로그램을 만들고 실행되는 모든 곳에 Console.WriteLine ( "text")을 추가하여 재현 할 수 있습니다. 어떤 아이디어?

지금 필요한 것은 Console.WriteLine ()처럼 간단한 것입니다. 나는 log4net 또는 다른 로깅 솔루션을 사용할 수 있다는 것을 알고 있지만 실제로이 응용 프로그램에 그다지 많은 기능이 필요하지 않습니다.

편집 : Console.WriteLine ()이 콘솔 응용 프로그램 용이라는 것을 기억해야합니다. 오, 어리석은 질문은 없죠? :-) 지금은 System.Diagnostics.Trace.WriteLine ()과 DebugView를 사용하겠습니다.


실제로 Console.Write 메서드를 호출하기 전에 콘솔 창을 수동으로 만들어야합니다. 그러면 프로젝트 유형을 변경하지 않고 콘솔이 제대로 작동하도록 초기화됩니다 (WPF 응용 프로그램의 경우 작동하지 않음).

다음은 ConsoleManager 클래스의 모양과 프로젝트 유형에 관계없이 콘솔을 활성화 / 비활성화하는 데 사용할 수있는 방법에 대한 완전한 소스 코드 예제입니다.

다음 클래스를 사용하면 ...를 ConsoleManager.Show()호출하기 전에 어딘가에 쓰기 만하면 됩니다 Console.Write.

[SuppressUnmanagedCodeSecurity]
public static class ConsoleManager
{
    private const string Kernel32_DllName = "kernel32.dll";

    [DllImport(Kernel32_DllName)]
    private static extern bool AllocConsole();

    [DllImport(Kernel32_DllName)]
    private static extern bool FreeConsole();

    [DllImport(Kernel32_DllName)]
    private static extern IntPtr GetConsoleWindow();

    [DllImport(Kernel32_DllName)]
    private static extern int GetConsoleOutputCP();

    public static bool HasConsole
    {
        get { return GetConsoleWindow() != IntPtr.Zero; }
    }

    /// <summary>
    /// Creates a new console instance if the process is not attached to a console already.
    /// </summary>
    public static void Show()
    {
        //#if DEBUG
        if (!HasConsole)
        {
            AllocConsole();
            InvalidateOutAndError();
        }
        //#endif
    }

    /// <summary>
    /// If the process has a console attached to it, it will be detached and no longer visible. Writing to the System.Console is still possible, but no output will be shown.
    /// </summary>
    public static void Hide()
    {
        //#if DEBUG
        if (HasConsole)
        {
            SetOutAndErrorNull();
            FreeConsole();
        }
        //#endif
    }

    public static void Toggle()
    {
        if (HasConsole)
        {
            Hide();
        }
        else
        {
            Show();
        }
    }

    static void InvalidateOutAndError()
    {
        Type type = typeof(System.Console);

        System.Reflection.FieldInfo _out = type.GetField("_out",
            System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);

        System.Reflection.FieldInfo _error = type.GetField("_error",
            System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);

        System.Reflection.MethodInfo _InitializeStdOutError = type.GetMethod("InitializeStdOutError",
            System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);

        Debug.Assert(_out != null);
        Debug.Assert(_error != null);

        Debug.Assert(_InitializeStdOutError != null);

        _out.SetValue(null, null);
        _error.SetValue(null, null);

        _InitializeStdOutError.Invoke(null, new object[] { true });
    }

    static void SetOutAndErrorNull()
    {
        Console.SetOut(TextWriter.Null);
        Console.SetError(TextWriter.Null);
    }
} 

프로젝트, "속성", "응용 프로그램"탭을 마우스 오른쪽 버튼으로 클릭하고 "출력 유형"을 "콘솔 응용 프로그램"으로 변경하면 콘솔도 있습니다.


당신이 사용할 수있는

Trace.WriteLine("text");

Visual Studio의 "출력"창에 출력됩니다 (디버깅 할 때).

진단 어셈블리가 포함되어 있는지 확인하십시오.

using System.Diagnostics;

John Leidegren이 계속해서 아이디어를 내 세우지 만 Brian이 맞습니다. Visual Studio에서 방금 작동했습니다.

WPF 응용 프로그램을 지우려면 기본적으로 콘솔 창을 만들지 않습니다.

WPF 응용 프로그램을 만든 다음 OutputType을 "콘솔 응용 프로그램"으로 변경해야합니다. 프로젝트를 실행하면 앞에 WPF 창이있는 콘솔 창이 표시됩니다.

그다지 예쁘게 보이지는 않지만 피드백이있는 명령 줄에서 앱을 실행하고 특정 명령 옵션에 대해 WPF 창을 표시하기를 원했기 때문에 유용하다는 것을 알았습니다.


명령 줄 리디렉션 을 사용하여 콘솔 용 출력을 볼 수 있습니다 .

예를 들면 :

C:\src\bin\Debug\Example.exe > output.txt

모든 내용을 output.txt파일에 기록 합니다.


이전 게시물이지만 Visual Studio의 WPF 프로젝트에서 출력에 무언가를 출력하려는 ​​경우 최신 방법은 다음과 같습니다.

포함 :

using System.Diagnostics;

그리고:

Debug.WriteLine("something");

출력 창에서 사용하기 위해 Console.WriteLine ()을 사용합니다.


솔루션을 만들고 다양한 게시물의 정보를 혼합했습니다.

레이블과 하나의 텍스트 상자를 포함하는 양식입니다. 콘솔 출력은 텍스트 상자로 리디렉션됩니다.

Show (), Close () 및 Release ()의 세 가지 공용 메서드를 구현하는 ConsoleView라는 클래스도 있습니다. 마지막은 콘솔을 열어두고 결과보기를 위해 닫기 버튼을 활성화하는 것입니다.

양식을 FrmConsole이라고합니다. 다음은 XAML 및 C # 코드입니다.

사용은 매우 간단합니다.

ConsoleView.Show("Title of the Console");

콘솔을 엽니 다. 사용하다:

System.Console.WriteLine("The debug message");

콘솔에 대한 출력 텍스트입니다.

사용하다:

ConsoleView.Close();

콘솔 닫기.

ConsoleView.Release();

콘솔을 열어두고 닫기 버튼을 활성화합니다.

XAML

<Window x:Class="CustomControls.FrmConsole"
    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:CustomControls"
    mc:Ignorable="d"
    Height="500" Width="600" WindowStyle="None" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" Topmost="True" Icon="Images/icoConsole.png">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="40"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="40"/>
    </Grid.RowDefinitions>
    <Label Grid.Row="0" Name="lblTitulo" HorizontalAlignment="Center" HorizontalContentAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center" FontFamily="Arial" FontSize="14" FontWeight="Bold" Content="Titulo"/>
    <Grid Grid.Row="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="10"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="10"/>
        </Grid.ColumnDefinitions>
        <TextBox Grid.Column="1" Name="txtInner" FontFamily="Arial" FontSize="10" ScrollViewer.CanContentScroll="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" TextWrapping="Wrap"/>
    </Grid>
    <Button Name="btnCerrar" Grid.Row="2" Content="Cerrar" Width="100" Height="30" HorizontalAlignment="Center" HorizontalContentAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center"/>
</Grid>

창의 코드 :

partial class FrmConsole : Window
{
    private class ControlWriter : TextWriter
    {
        private TextBox textbox;
        public ControlWriter(TextBox textbox)
        {
            this.textbox = textbox;
        }

        public override void WriteLine(char value)
        {
            textbox.Dispatcher.Invoke(new Action(() =>
            {
                textbox.AppendText(value.ToString());
                textbox.AppendText(Environment.NewLine);
                textbox.ScrollToEnd();
            }));
        }

        public override void WriteLine(string value)
        {
            textbox.Dispatcher.Invoke(new Action(() =>
            {
                textbox.AppendText(value);
                textbox.AppendText(Environment.NewLine);
                textbox.ScrollToEnd();
            }));
        }

        public override void Write(char value)
        {
            textbox.Dispatcher.Invoke(new Action(() =>
            {
                textbox.AppendText(value.ToString());
                textbox.ScrollToEnd();
            }));
        }

        public override void Write(string value)
        {
            textbox.Dispatcher.Invoke(new Action(() =>
            {
                textbox.AppendText(value);
                textbox.ScrollToEnd();
            }));
        }

        public override Encoding Encoding
        {
            get { return Encoding.UTF8; }

        }
    }

    //DEFINICIONES DE LA CLASE
    #region DEFINICIONES DE LA CLASE

    #endregion


    //CONSTRUCTORES DE LA CLASE
    #region CONSTRUCTORES DE LA CLASE

    public FrmConsole(string titulo)
    {
        InitializeComponent();
        lblTitulo.Content = titulo;
        Clear();
        btnCerrar.Click += new RoutedEventHandler(BtnCerrar_Click);
        Console.SetOut(new ControlWriter(txtInner));
        DesactivarCerrar();
    }

    #endregion


    //PROPIEDADES
    #region PROPIEDADES

    #endregion


    //DELEGADOS
    #region DELEGADOS

    private void BtnCerrar_Click(object sender, RoutedEventArgs e)
    {
        Close();
    }

    #endregion


    //METODOS Y FUNCIONES
    #region METODOS Y FUNCIONES

    public void ActivarCerrar()
    {
        btnCerrar.IsEnabled = true;
    }

    public void Clear()
    {
        txtInner.Clear();
    }

    public void DesactivarCerrar()
    {
        btnCerrar.IsEnabled = false;
    }

    #endregion  
}

ConsoleView 클래스의 코드

static public class ConsoleView
{
    //DEFINICIONES DE LA CLASE
    #region DEFINICIONES DE LA CLASE
    static FrmConsole console;
    static Thread StatusThread;
    static bool isActive = false;
    #endregion

    //CONSTRUCTORES DE LA CLASE
    #region CONSTRUCTORES DE LA CLASE

    #endregion

    //PROPIEDADES
    #region PROPIEDADES

    #endregion

    //DELEGADOS
    #region DELEGADOS

    #endregion

    //METODOS Y FUNCIONES
    #region METODOS Y FUNCIONES

    public static void Show(string label)
    {
        if (isActive)
        {
            return;
        }

        isActive = true;
        //create the thread with its ThreadStart method
        StatusThread = new Thread(() =>
        {
            try
            {
                console = new FrmConsole(label);
                console.ShowDialog();
                //this call is needed so the thread remains open until the dispatcher is closed
                Dispatcher.Run();
            }
            catch (Exception)
            {
            }
        });

        //run the thread in STA mode to make it work correctly
        StatusThread.SetApartmentState(ApartmentState.STA);
        StatusThread.Priority = ThreadPriority.Normal;
        StatusThread.Start();

    }

    public static void Close()
    {
        isActive = false;
        if (console != null)
        {
            //need to use the dispatcher to call the Close method, because the window is created in another thread, and this method is called by the main thread
            console.Dispatcher.InvokeShutdown();
            console = null;
            StatusThread = null;
        }

        console = null;
    }

    public static void Release()
    {
        isActive = false;
        if (console != null)
        {
            console.Dispatcher.Invoke(console.ActivarCerrar);
        }

    }
    #endregion
}

이 결과가 유용하기를 바랍니다.


이 게시물을 확인하면 나에게 매우 도움이되었습니다. 코드 샘플 다운로드 :

http://www.codeproject.com/Articles/335909/Embedding-a-Console-in-aC-Application


내가 아는 한 Console.WriteLine ()은 콘솔 응용 프로그램 전용입니다. 나는 이것이 당신의 문제라고 생각합니다.

참고URL : https://stackoverflow.com/questions/160587/no-output-to-console-from-a-wpf-application

반응형