56

Is there a way to write to console / command prompt / powershell (like Console.WriteLine()) or anything similar in UWP apps?

If console is unavailable is there a proper alternative that I can use instead to write to the screen large amounts of text?

I, of course, can make a XAML control and output to it, but it doesn't seem to be convenient in comparison to simple Console.WriteLine().

There is also very old discussion on WPF console, but nothing seems to work from there (at least, I couldn't find Project-Properties-Application tab-Output Type-Console Application and Trace.WriteLine("text") is unavailable).

Community
  • 1
  • 1
Bad
  • 4,967
  • 4
  • 34
  • 50

4 Answers4

85

You can use Debug.WriteLine method from System.Diagnostics namespace

MSDN Link

When you start debugging your application those messages will be displayed in the Output Window (Standard VS shortcut is Ctrl+Alt+O, ReSharper shortcut is Ctrl+W, O)

Grzegorz Piotrowski
  • 913
  • 1
  • 10
  • 12
  • It seems to be partially a solution, but is there a way to output to a separate window like console? By the way, isn't Output Window Ctrl+Alt+O instead, at least in Visual Studio 2015? – Bad Oct 03 '15 at 16:32
  • 2
    Ah, sorry! Yes, standard shortcut is Ctrl+Alt+O, Ctrl+W, O is ReSharper shortcut. And about separate window like console - UWP works both on Windows Mobile 10 and Windows 10. I think that it isn't possible to run someting like separate window with console. And to be honest - I don't see the point of doing someting like this. If it is for debug purpose then output window is ideal place for this. Other solution is to greate XAML control for display text (as you mention in your question). – Grzegorz Piotrowski Oct 03 '15 at 17:55
  • 1
    Another option is to open new window where you display your logging. [Here is example](https://social.msdn.microsoft.com/Forums/sqlserver/en-US/f1328991-b5e5-48e1-b4ff-536a0013ef9f/is-it-possible-to-open-a-new-window-in-uwp-apps?forum=wpdevelop) You should create a new XAML page (where you could declare some controls that will display additional information) and open it in a new window. But you must implement some custom logic to transfer your information between windows and display it. But still if this is just for the debugging then the best option is to use output window. – Grzegorz Piotrowski Oct 03 '15 at 18:14
  • Is there any possible reason why it does not work in visual studio 2015 update 2? I did not see any message in the Output Window. – Fei Zheng Nov 15 '16 at 16:32
  • @FeiZheng It should work. Check this SO question&answer http://stackoverflow.com/questions/13000507/why-does-system-diagnostics-debug-writeline-not-work-in-visual-studio-2010-c I hope that it will help you. – Grzegorz Piotrowski Nov 15 '16 at 17:32
  • @GrzegorzPiotrowski I did try a bunch of your link except item 4, because I have an error: 'Debug' does not have a definition for 'AutoFlush'. Other items do not work for me. – Fei Zheng Nov 16 '16 at 21:12
  • @FeiZheng That's really strange. Did you try solutions from other answers (other than accepted) in that thread (e.g. uncheck "Redirect all Output Window text to the Immediate Window" option)? – Grzegorz Piotrowski Nov 17 '16 at 13:29
  • Any chance you know how to do this for C++ projects? – serup Jun 08 '18 at 10:22
  • @serup - try this one: https://stackoverflow.com/questions/1333527/how-do-i-print-to-the-debug-output-window-in-a-win32-app – Grzegorz Piotrowski Jun 11 '18 at 08:17
3

Starting with RS4 (the release coming out mid-2018) you can build command - line apps with UWP or output info to the command line. The pre-release SDK is already available and you can watch a Channel 9 video.

Peter Torr - MSFT
  • 11,824
  • 3
  • 18
  • 51
1

You can use the LoggingChannel class. to create ETW trace events.

The cool thing with LoggingChannel is you can do sophisticated traces (and use advanced tools like 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)

or

public void LogMessage(String eventString, LoggingLevel level)

This has numerous advantages over Debug.WriteLine:

  • it's much faster, you can log millions of messages easily, while Debug.WriteLine is dog slow (based on the archaic Windows' OutputDebugString function).
  • it doesn't block the sender nor the receiver.
  • each channel is identified by its own guid, while with Debug.WriteLine you get all traces from everywhere, everyone, it's a bit messy to find your own ones.
  • you can use a trace level (Critical, Error, Information, Verbose, Warning)
  • you can use PerfView (if you really want to) or Device Portal or any other ETW tool.

So, to send some traces, just add this:

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

Now, if you want a simple way to display those traces on your local machine, beyond using PerfView or other ETW tools, you can use a free open source GUI tool I write called WpfTraceSpy available here: https://github.com/smourier/TraceSpy#wpftracespy or here is a sample .NET Framework Console app that will output all traces and their level to the console:

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);
        }
    }
}
Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
0

I just want to also add that debug.writeline seems to best work on the main thread so if async/await is used use something like Device.BeginInvokeOnMainThread(() => Debug.WriteLine(response)); to print to the console

Jfm Meyers
  • 123
  • 1
  • 12