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

我从一个非常简单的 WPF 测试应用程序中使用 Console.WriteLine(),但是当我从命令行执行该应用程序时,我看不到任何内容被写入控制台。有人知道这是怎么回事吗?

我可以通过在 VS2008中创建一个 WPF 应用程序,并在执行它的任何地方简单地添加 Console.WriteLine("text")来重现它。有什么想法吗?

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

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

159515 次浏览

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

你可以用

Trace.WriteLine("text");

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

确保将诊断程序集包括在内:

using System.Diagnostics;

我在 Output 窗口中使用 Console. WriteLine () ..。

在实际调用任何控制台之前,必须手动创建控制台窗口。编写方法。这将初始化控制台以正常工作,而不会更改项目类型(对于 WPF 应用程序而言,这种类型无法正常工作)。

下面是一个完整的源代码示例,展示了 Console Manager 类的外观,以及如何使用它来启用/禁用控制台(与项目类型无关)。

使用下面的类,您只需要在调用 Console.Write之前在某个地方编写 ConsoleManager.Show()..。

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

虽然约翰 · 莱德格伦一直否定这个想法,但布莱恩是对的。我只是在视觉工作室里把它运行起来。

要清楚,WPF 应用程序在默认情况下不会创建控制台窗口。

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

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

通过使用 命令行重定向命令行重定向可以看到用于控制台的输出。

例如:

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

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

看看这篇文章,对我很有帮助。下载代码示例:

Http://www.codeproject.com/articles/335909/embedding-a-console-in-a-c-application

旧文章,但是我遇到了这个问题,所以如果你想在 Visual Studio 的 WPF 项目中输出一些东西到 Output,现在的方法是:

包括:

using System.Diagnostics;

然后:

Debug.WriteLine("something");

我已经创建了一个解决方案,混合了各种职位的信息。

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

还有一个名为 Console View 的类实现了三个公共方法: Show ()、 Close ()和 Release ()。最后一个是让控制台保持打开状态,并激活 Close 按钮以获得视图结果。

这些表单称为 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
}

类的代码

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
}

我希望这个结果有用。

Brian 的解决方案 是在 WPF 应用程序启动时打开 一直都是控制台。如果您希望 动态的启用控制台输出(例如,仅在使用某些命令行参数启动时) ,请调用 AttachConsole:

[DllImport("kernel32.dll")]
static extern bool AttachConsole(uint dwProcessId);


const uint ATTACH_PARENT_PROCESS = 0x0ffffffff;

然后,当您想开始写入控制台时:

AttachConsole(ATTACH_PARENT_PROCESS);
Console.WriteLine("Hello world!");
Console.WriteLine("Writing to the hosting console!");