Terenced
Terenced

Reputation: 675

WPF / Console Hybrid Application

I writing an application what can either be run on the command line, or with a WPF UI.

[STAThread]
static void Main(string[] args)
{
    // Does magic parse args and sets IsCommandLine to true if flag is present
    ParseArgs(args);     

    if(IsCommandLine)
    {
        // Write a bunch of things to the console
    }
    else
    {
        var app = new App();
        app.Run(new Window());
    }
}

I set the project's Output type to Console Application, I get a console window that popups if I try to execute it by double-clicking the exe. I don't want to show the console window to the user if the flag is not set (passed in via command args).

However, if I set the project's Output type to Windows Application, the double-click behaviour is fine, but when I run it in the console, I get no console output (Console.Writeline)

Upvotes: 16

Views: 23405

Answers (4)

ChrisF
ChrisF

Reputation: 137108

Your best bet would be to abstract out the code that actually does the work to a separate class library that has no UI and then create two applications one Console, the other WPF that call this.

A console application and an WPF application have entirely different application models so you can't reuse the same code in both applications.

Having a separate class library allows you do other things like use it in other applications such as a web site or client/server architecture.

Upvotes: 11

Sasha Yakobchuk
Sasha Yakobchuk

Reputation: 511

Create a WPF app and add the following code to your App class:

public partial class App
{
    protected override void OnStartup(StartupEventArgs e)
    {
        if (e.Args.Length > 0)
        {                
            List<string> lowercaseArgs = e.Args.ToList().ConvertAll(x => x.ToLower());
            if (AttachConsole(ATTACH_PARENT_PROCESS))
            {
                // your console app code                

                Console.Write("\rPress any key to continue...");
                Console.ReadKey();
                FreeConsole();
            }
            Shutdown();
        }
        else
        {
            base.OnStartup(e);
        }
    }

    private const int ATTACH_PARENT_PROCESS = -1;

    [DllImport("kernel32", SetLastError = true)]
    private static extern bool AttachConsole(int dwProcessId);

    [DllImport("kernel32.dll")]
    private static extern bool FreeConsole();
}

Upvotes: 10

Ixonal
Ixonal

Reputation: 646

I know I'm a little late to the party, but figured I could toss in my two cents. You could always keep it as a console application, and then hide the console as per this answer (https://stackoverflow.com/a/3571628/1059953). There is a moment of the console being displayed, then it disappears and the window shows up.

Upvotes: 0

jtimperley
jtimperley

Reputation: 2544

You can conditionally start your WPF application by performing the following steps with the sample below.

  1. Add another entry point with the 'Main' method declarated with STAThreadAttribute. This is required by WPF.
  2. Under your project's 'Build' properties, choose 'Console Application' as your output and your new 'Main' method as the application's 'Startup Object'.

    using System;
    
    public static class Program
    {
        [STAThreadAttribute]
        public static void Main()
        {
            Console.WriteLine("What now?");
            Console.ReadKey(true);
    
            App.Main();
        }
    }
    

Upvotes: 1

Related Questions