How to dynamically use a console or windows app

I have a small application that needs to be executed in two modes : not UI or WPF Window. It must depend on command line arguments.

In each mode, I need to show a log with reviews:

  • In WPF Window mode, WPF will take care of rendering the logs,
  • In UI mode, I need a console to show the logs. If my application was launched from the console (mainly cmd.exe), I would like to use it without opening a new one. If my application was launched outside of the console (double click on explorer, CreateProcess, ...), I need to create a new console to output my results and wait for the Read window to open.

I found:

And I know I can statically choose between "Windows Application" or "Console Application" in the project property.

Selecting "Windows Application", GetConsoleWindow () is always 0 and I don't see how to reuse the previous console.

By selecting Console Application, I can reuse the previous console, but when I run from Explorer in WPF window mode, the console is created in the main WPF window.

The question is: how can an application be truly dynamic? Either in WPF Window mode, with WPF windows only (and no console at all), or in a non-UI with a single console (starting one or a new one created).

+3


source to share


1 answer


It was much simpler in Winforms, but not too difficult.

Start with a WPF application project (not a WPF windows console application).

Create a new class Program.cs in the root directory, add the following code:

class Program
{
    [DllImport("Kernel32")]
    public static extern void AllocConsole();

    [DllImport("Kernel32")]
    public static extern void FreeConsole();

    [DllImport("kernel32.dll")]
    static extern bool AttachConsole(uint dwProcessId);

    [STAThread]
    public static void Main(string[] args)
    {
        bool madeConsole = false;
        if (args.Length > 0 && args[0] == "console")
        {

            if (!AttachToConsole())
            {
                AllocConsole();
                Console.WriteLine("Had to create a console");
                madeConsole = true;
            }

            Console.WriteLine("Now I'm a console app!");
            Console.WriteLine("Press any key to exit");
            Console.ReadKey(true);

            if (madeConsole)
                FreeConsole();
        }
        else
        {
            WpfApplication1.App.Main();
        }
    }


    public static bool AttachToConsole()
    {
        const uint ParentProcess = 0xFFFFFFFF;
        if (!AttachConsole(ParentProcess))
            return false;

        Console.Clear();
        Console.WriteLine("Attached to console!");
        return true;
    }

}

      



You now have a Console or WPF Application. In the properties, set the starting object as a method Program.Main

. In the above example, WpfApplication1.App.Main is the old startup object (defined in the App.xaml.cs file).

Edit this doesn't fit one of your requirements for using an existing console and I'll edit it once I figure out how to stay in the same console window.

New edit Now works to use existing console!

+7


source







All Articles