当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《WPF应用程序没有输出到控制台?》经验,为你挑选了6个好方法。

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

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

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

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



1> Brian..:

右键单击项目,"属性","应用程序"选项卡,将"输出类型"更改为"控制台应用程序",然后它还将具有控制台.


很棒,但是当从cmd.exe(为一个应用程序创建两个窗口)执行应用程序时,将创建命令行窗口.但为此还有解决方案:您可以通过ShowWindow隐藏cmd窗口(hWnd,0).http://stackoverflow.com/a/10416180/1457197.使用此解决方案,只有在从命令行执行WPF应用程序时,才会在控制台中看到文本.
唯一的问题是,您将在后台打开一个cmd,但是它可以:)。

2> Phobis..:

您可以使用

Trace.WriteLine("text");

这将输出到Visual Studio中的"输出"窗口(调试时).

确保包含诊断程序集:

using System.Diagnostics;


这是最好的答案,但没有最高评级
PS for Windows Store应用程序(Windows运行时)相当于Trace.WriteLine是Debug.WriteLine()

3> John Leidegr..:

在实际调用任何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; }
    }

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

    /// 
    /// 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.
    /// 
    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);
    }
} 


可以首先尝试调用AttachConsole(-1)并检查其返回值以附加到父进程的控制台; 如果返回false,则调用AllocConsole.但是,应用程序仍然首先"返回",然后输出到控制台,如果找到解决方案,我会发布更多内容.此外,如果您将WPF应用程序类型设置为控制台应用程序,问题就会消失,但是当程序启动时,如果没有在屏幕上短暂显示控制台,则无法分离控制台,因此它看起来很尴尬(但如果你能忍受它,它很棒).
呃,实际上不,我认为不可能双管齐下; 控制台应用程序在其PE头中标记为CUI,因此可以自动与CMD协同工作.另一方面,GUI应用程序立即将控制权返回给CMD,即使它可以重新连接到控制台,读取和写入也将与管道中的下一个输出混合,这显然非常糟糕.另一方面,如果您将应用程序标记为控制台应用程序,则只需在应用程序启动时短暂显示CMD; 然后,您可以使用FreeConsole分离和Attach/Alloc等
@Mark是的,但它不起作用......有一个`SetConsoleCtrlHandler`函数,当`CTRL_CLOSE_EVENT`事件发生但你不能对它做任何事情时,它可以被通知,没有什么可以让你的应用程序继续.你将被关闭.如果你觉得自己喜欢黑客攻击,你可能会为控制台进程交换windows消息处理程序而只是删除WM_CLOSE消息,我从未尝试过这个但它可以工作.它只是另一个窗口,但据说,除非你想要接受这个想法,否则你可能会更好地做其他事情.

4> 小智..:

虽然John Leidegren一直在抨击这个想法,但Brian是正确的.我刚刚在Visual Studio中使用它.

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

您必须创建WPF应用程序,然后将OutputType更改为"控制台应用程序".运行项目时,您将看到一个控制台窗口,其前面有WPF窗口.

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



5> Lu55..:

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

例如:

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

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



6> Smitty..:

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

包括这个:

using System.Diagnostics;

然后:

Debug.WriteLine("something");

推荐阅读
mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有