C# WPF 应用程序没有输出到控制台?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/160587/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 16:12:53  来源:igfitidea点击:

No output to console from a WPF application?

提问by Rob

I'm using Console.WriteLine() from a very simple WPF test application, but when I execute the application from the command line, I'm seeing nothing being written to the console. Does anyone know what might be going on here?

我在一个非常简单的 WPF 测试应用程序中使用 Console.WriteLine(),但是当我从命令行执行应用程序时,我没有看到任何内容写入控制台。有谁知道这里会发生什么?

I can reproduce it by creating a WPF application in VS 2008, and simply adding Console.WriteLine("text") anywhere that get executed. Any ideas?

我可以通过在 VS 2008 中创建 WPF 应用程序来重现它,只需在执行的任何地方添加 Console.WriteLine("text") 即可。有任何想法吗?

All I need for right now is something as simple as Console.WriteLine(). I realize I could use log4net or somet other logging solution, but I really don't need that much functionality for this application.

我现在需要的只是像 Console.WriteLine() 这样简单的东西。我意识到我可以使用 log4net 或其他一些日志记录解决方案,但我真的不需要这个应用程序的那么多功能。

Edit:I should have remembered that Console.WriteLine() is for console applications. Oh well, no stupid questions, right? :-) I'll just use System.Diagnostics.Trace.WriteLine() and DebugView for now.

编辑:我应该记得 Console.WriteLine() 是用于控制台应用程序的。哦,没有愚蠢的问题,对吧?:-) 我现在只使用 System.Diagnostics.Trace.WriteLine() 和 DebugView。

采纳答案by John Leidegren

You'll have to create a Console window manually before you actually call any Console.Write methods. That will init the Console to work properly without changing the project type (which for WPF application won't work).

在实际调用任何 Console.Write 方法之前,您必须手动创建一个控制台窗口。这将使控制台在不更改项目类型的情况下正常工作(这对于 WPF 应用程序将不起作用)。

Here's a complete source code example, of how a ConsoleManager class might look like, and how it can be used to enable/disable the Console, independently of the project type.

这是一个完整的源代码示例,说明了 ConsoleManager 类的外观,以及如何独立于项目类型使用它来启用/禁用控制台。

With the following class, you just need to write ConsoleManager.Show()somewhere before any call to Console.Write...

对于以下课程,您只需要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);
    }
} 

回答by GEOCHET

As far as I know, Console.WriteLine() is only for console applications. I think this is your problem.

据我所知, Console.WriteLine() 仅适用于控制台应用程序。我想这是你的问题。

回答by Brian

Right click on the project, "Properties", "Application" tab, change "Output Type" to "Console Application", and then it will also have a console.

右键单击项目,“属性”,“应用程序”选项卡,将“输出类型”更改为“控制台应用程序”,然后它也会有一个控制台。

回答by Phobis

You can use

您可以使用

Trace.WriteLine("text");

This will output to the "Output" window in Visual Studio (when debugging).

这将输出到 Visual Studio 中的“输出”窗口(调试时)。

make sure to have the Diagnostics assembly included:

确保包含诊断程序集:

using System.Diagnostics;

回答by erodewald

I use Console.WriteLine() for use in the Output window...

我使用 Console.WriteLine() 在输出窗口中使用...

回答by John Leidegren

Although John Leidegren keeps shooting down the idea, Brian is correct. I've just got it working in Visual Studio.

尽管 John Leidegren 不断否定这个想法,但 Brian 是正确的。我刚刚在 Visual Studio 中使用它。

To be clear a WPF application does not create a Console window by default.

需要明确的是,WPF 应用程序默认不会创建控制台窗口。

You have to create a WPF Application and then change the OutputType to "Console Application". When you run the project you will see a console window with your WPF window in front of it.

您必须创建一个 WPF 应用程序,然后将 OutputType 更改为“控制台应用程序”。当您运行该项目时,您将看到一个控制台窗口,它前面有您的 WPF 窗口。

It doesn't look very pretty, but I found it helpful as I wanted my app to be run from the command line with feedback in there, and then for certain command options I would display the WPF window.

它看起来不是很漂亮,但我发现它很有帮助,因为我希望我的应用程序从命令行运行并在那里提供反馈,然后对于某些命令选项,我会显示 WPF 窗口。

回答by Lu55

It's possible to see output intended for console by using command line redirection.

可以使用命令行重定向来查看用于控制台的输出。

For example:

例如:

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

will write all the content to output.txtfile.

将所有内容写入output.txt文件。

回答by Sam Wright

Check out this post, was very helpful for myself. Download the code sample:

看看这个帖子,对自己很有帮助。下载代码示例:

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

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

回答by Smitty

Old post, but I ran into this so if you're trying to output something to Output in a WPF project in Visual Studio, the contemporary method is:

旧帖子,但我遇到了这个,所以如果你想在 Visual Studio 的 WPF 项目中输出一些东西到输出,当代的方法是:

Include this:

包括这个:

using System.Diagnostics;

And then:

进而:

Debug.WriteLine("something");

回答by Emelias Alvarez

I've create a solution, mixed the information of varius post.

我创建了一个解决方案,混合了各种帖子的信息。

Its a form, that contains a label and one textbox. The console output is redirected to the textbox.

它是一种表单,包含一个标签和一个文本框。控制台输出被重定向到文本框。

There are too a class called ConsoleView that implements three publics methods: Show(), Close(), and Release(). The last one is for leave open the console and activate the Close button for view results.

还有一个叫做 ConsoleView 的类,它实现了三个公共方法:Show()、Close() 和 Release()。最后一个是保持打开控制台并激活关闭按钮以查看结果。

The forms is called FrmConsole. Here are the XAML and the c# code.

这些表格称为 FrmConsole。下面是 XAML 和 c# 代码。

The use is very simple:

使用非常简单:

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

For open the console. Use:

用于打开控制台。用:

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

For output text to the console.

用于向控制台输出文本。

Use:

用:

ConsoleView.Close();

For Close the console.

对于关闭控制台。

ConsoleView.Release();

Leaves open the console and enables the Close button

保持打开控制台并启用关闭按钮

XAML

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>

The code of the Window:

窗口代码:

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  
}

the code of ConsoleView class

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
}

I hope this result usefull.

我希望这个结果有用。