如何在 Windows 10 上输出到 UWP 中的控制台?

How to output to console in UWP on Windows 10?

有没有办法写入控制台/命令提示符/powershell(如Console.WriteLine())或 UWP 应用程序中的任何类似内容?

如果控制台不可用,是否有合适的替代方法可以用来向屏幕写入大量文本?

我当然可以做一个XAML控件输出给它,但是和简单的Console.WriteLine()相比好像不太方便。

关于 WPF console 也有非常古老的讨论,但从那里似乎没有任何效果(至少,我找不到 Project-Properties-Application tab-Output Type-Console Application 并且 Trace.WriteLine("text") 不可用)。

您可以使用 System.Diagnostics 命名空间

中的 Debug.WriteLine 方法

MSDN Link

当您开始调试应用程序时,这些消息将显示在输出中 Window(标准 VS 快捷方式是 Ctrl+Alt+O,ReSharper 快捷方式是 Ctrl+W、O)

从 RS4(2018 年年中发布)开始,您可以使用 UWP 构建命令行应用程序或将信息输出到命令行。 pre-release SDK 已经可用,您可以观看Channel 9 video

您可以使用 LoggingChannel class. to create ETW 跟踪事件。

LoggingChannel 的妙处在于您可以进行复杂的跟踪(并使用 PerfView, etc.), but you can also have a simple equivalent of Debug.WriteLine in terms of simplicity with the LoggingChannel.LogMessage Method

等高级工具
public void LogMessage(String eventString)

public void LogMessage(String eventString, LoggingLevel level)

这比 Debug.WriteLine 有很多优点:

  • 速度快得多,您可以轻松记录数百万条消息,而 Debug.WriteLine 速度非常慢(基于古老的 Windows' OutputDebugString 函数)。
  • 它不会阻止发送者或接收者。
  • 每个频道都由自己的 guid 标识,而使用 Debug.WriteLine 你可以从任何地方获取所有痕迹,每个人,找到自己的有点麻烦。
  • 您可以使用跟踪级别(严重、错误、信息、详细、警告)
  • 您可以使用 PerfView(如果您确实需要)或 Device Portal or any other ETW tool

所以,要发送一些痕迹,只需添加:

// somewhere in your initialization code, like in `App` constructor
private readonly static LoggingChannel _channel = new LoggingChannel("MyApp",
        new LoggingChannelOptions(),
        new Guid("01234567-01234-01234-01234-012345678901")); // change this guid, it's yours!

....
// everywhere in your code. add simple string traces like this
_channel.LogMessage("hello from UWP!");
....

现在,除了使用 PerfView 或其他 ETW 工具之外,如果您想要一种在本地计算机上显示这些跟踪的简单方法,您可以使用我编写的名为 WpfTraceSpy 的免费开源 GUI 工具,可在此处获取:https://github.com/smourier/TraceSpy#wpftracespy 或者这里是一个示例 .NET Framework 控制台应用程序,它将所有跟踪及其级别输出到控制台:

using System;
using System.Runtime.InteropServices;
using Microsoft.Diagnostics.Tracing; // you need to add the Microsoft.Diagnostics.Tracing.TraceEvent nuget package
using Microsoft.Diagnostics.Tracing.Session;

namespace TraceTest
{
    class Program
    {
        static void Main()
        {
            // create a real time user mode session
            using (var session = new TraceEventSession("MySession"))
            {
                // use UWP logging channel provider
                session.EnableProvider(new Guid("01234567-01234-01234-01234-012345678901")); // use the same guid as for your LoggingChannel

                session.Source.AllEvents += Source_AllEvents;

                // Set up Ctrl-C to stop the session
                Console.CancelKeyPress += (object s, ConsoleCancelEventArgs a) => session.Stop();

                session.Source.Process();   // Listen (forever) for events
            }
        }

        private static void Source_AllEvents(TraceEvent obj)
        {
            // note: this is for the LoggingChannel.LogMessage Method only! you may crash with other providers or methods
            var len = (int)(ushort)Marshal.ReadInt16(obj.DataStart);
            var stringMessage = Marshal.PtrToStringUni(obj.DataStart + 2, len / 2);

            // Output the event text message. You could filter using level.
            // TraceEvent also contains a lot of useful informations (timing, process, etc.)
            Console.WriteLine(obj.Level + ":" + stringMessage);
        }
    }
}

我还想补充一点,debug.writeline 似乎在主线程上效果最好,因此如果使用 async/await,请使用 Device.BeginInvokeOnMainThread(() => Debug.WriteLine(response)); 之类的东西打印到控制台