soapergem
soapergem

Reputation: 9989

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

I have a simple WPF application. Under normal use, App.xaml will launch MainWindow.xaml. But I would like to set it up so that if it is invoked with a special command line argument, that it will function as a console application instead.

So here's roughly what my App.xaml.cs file looks like:

using System;

namespace MyProject
{
    public partial class App : Application
    {
        public void App_OnStartup(object sender, StartupEventArgs e)
        {
            if (e.Args.Length == 1 && e.Args[0].Equals("/console"))
            {
                Console.WriteLine("this is a test");
                Environment.Exit(0);
            }
            else
            {
                var mainWindow = new MainWindow();
                mainWindow.Show();
            }
        }
    }
}

I would expect that when I run MyProject.exe /console from the command line, it would print the string "this is a test". But right now it doesn't print anything. How can I get it to work?

Upvotes: 10

Views: 19412

Answers (2)

Mark Feldman
Mark Feldman

Reputation: 16119

If you don't want the Application object to be created then you should create a separate class containing a Main entry point:

class Startup
{
    [STAThreadAttribute]
    public static int Main(string[] args)
    {
        if (args.Length == 0)
        {
            // run windowed
            App app = new App();
            app.InitializeComponent();
            app.Run();
        }
        else
        {
            // run console
            ConsoleManager.Show();
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }

        return 0;
    }
}

You'll also need to go into your application settings and change "Startup object" to "YourProjectNamespace.Startup", see this article for more details.

The console functions I'm calling come from the accepted answer to this question which shows how to tap into the standard Console streams.

Upvotes: 5

Backs
Backs

Reputation: 24903

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

Upvotes: 20

Related Questions