tags:

views:

4645

answers:

6

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?

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

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.

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.

A: 

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

Geoffrey Chetwood
I don't know about WPF, but this certainly isn't the case for WinForms. Console.WriteLine works fine there, but, of course, you won't see the console, you will see it in the Debugger output window and if you listen to the standard output.
Jeff Yates
you can set the project to a Console application and it will still run as a Windows app but it will also have a visible console
Mark Cidade
That's incorrect, the build process of a non console application does not attach a console by deffault. You can do this manually by calling the AllocConsole() Win32 API function before any call to Console.Write, the Console class will then be initialized to work with that Console window.
John Leidegren
+4  A: 

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

Brian
A WPF application will not launch properly like that...
John Leidegren
A WPF application _will_ launch properly like that...
ing0
+5  A: 

You can use

Trace.WriteLine("text");

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

make sure to have the Diagnostics assembly included:

using System.Diagnostics;
Phobis
A: 

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

Erode
+10  A: 

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).

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.

With the following class, you just need to write ConsoleManager.Show() somewhere before any call to 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);
    }
}
John Leidegren
Rodney Foley
Thanks for posting this, it has really helped me
Dale Halliwell
Nice hack with setting the _out and _error to null. Smart!
BFree
Is it possible to embed the console window within a WPF window using this or any other technique?
InfinitiesLoop
Why would you want to do this? After all -- it won't look good, and I can easily make WPF control to have the same features (but it would look better).
macias
+1  A: 

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

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

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.

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.