No Output to Console from a Wpf Application

No output to console from a WPF application?

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

Is it possible to have a WPF application print console output?

We have special class for this purpose:

internal static class ConsoleAllocator
{
[DllImport(@"kernel32.dll", SetLastError = true)]
static extern bool AllocConsole();

[DllImport(@"kernel32.dll")]
static extern IntPtr GetConsoleWindow();

[DllImport(@"user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

const int SwHide = 0;
const int SwShow = 5;


public static void ShowConsoleWindow()
{
var handle = GetConsoleWindow();

if (handle == IntPtr.Zero)
{
AllocConsole();
}
else
{
ShowWindow(handle, SwShow);
}
}

public static void HideConsoleWindow()
{
var handle = GetConsoleWindow();

ShowWindow(handle, SwHide);
}
}

Just call ConsoleAllocator.ShowConsoleWindow() and then write to Console

Output Console.WriteLine from WPF Windows Applications to actual console

After digging up a bit, I found this answer. The code is now:

namespace WpfConsoleTest
{
public partial class App : Application
{
[DllImport("Kernel32.dll")]
public static extern bool AttachConsole(int processId);

protected override void OnStartup(StartupEventArgs e)
{
AttachConsole(-1);
Console.WriteLine("Start");
System.Threading.Thread.Sleep(1000);
Console.WriteLine("Stop");
Shutdown(0);
}
}
}

Calling the exe directly still has a nasty side effect, connected with the call returning immediately:

C:\test>WpfConsoleTest.exe

C:\test>Start
Stop

^^^^
The cursor will stay here waiting for the user to press enter!

The solution is, once again, to use start:

C:\test>start /wait WpfConsoleTest.exe
Start
Stop

Thanks for input!

How to block console from returning with WPF application attached to console while App is still running

The AttachConsole re-uses the existing console use AllocConsole() instead. This will block the console unless the parent process is running and will close the console as soon as the program finishes execution.

[DllImport("kernel32.dll")]
static extern bool AllocConsole();

Launch console application from WPF application in debug and release modes

Just change project "Output type" to "Console Application" and you will see both: app window and console.

Sample Image

WPF + Reflection + Console output are not working

Ok, I've finally found the solution.

1) Set WPF project type to "Console WPF application" in the properties of the project.

2) After main window loaded, close console window by calling "FreeConsole()" method of "kernel32.dll" library.

3) Before use of the class library in WPF, call "AllocConsole()" method of "kernel32.dll".

4) When console window is not needed, hide console window by "FreeConsole()".

Steps 3 and 4 are repeats when it need.

And I recommend write somehow helper class, wrapped invokes of "kernel32.dll" functions for work with console window.



Related Topics



Leave a reply



Submit