1

I've got an hybrid application with either console or WPF functionality. If the WPF application is started or something is done in console window depends on the arguments at start up. I were able to implement this (there are a lot of examples to find at stackoverflow). Now I want that, if the WPF application is started, that the console window will be closed. But this is shown and if I close it, the WPF application is also closed.

This is my current implementation.

using System;
using System.Windows;

namespace MyNamespace
{

    class Program
    {

        [STAThread]
        static void Main(string[] args)
        {
            string option = args[0];

            switch (option)
            {
                case "WPF":
                    RunApplication();

                    break;
                default:
                    DoSomething();

                    break;
            }
        }

        private static void RunApplication()
        {
            Application app = new Application();
            app.Run(new MainWindow());

            Environment.Exit(0);
        }

        private static void DoSomething()
        {
            // …
        }
    }
}

If I try to start the application in a new Thread the application is directly closed and the WPF window will not be shown.

using System.Threading;
using System.Threading.Tasks;

private static void RunApplication()
{
    new Thread(() => {
        Application app = new Application();
        app.Run(new MainWindow());
    }).Start();

    Environment.Exit(0);
}

I have no idea how I could implement this. Is there a possibility to do this?

mburm
  • 1,417
  • 2
  • 17
  • 37
  • Why do you call `Environment.Exit(0);`? – Mat J Mar 09 '19 at 17:35
  • Try process.start("yourwpf.exe"); – Andy Mar 09 '19 at 17:48
  • @Mat J I've found it in one example. If I remove this line I got an error that the calling `Thread` has to be a STA-`Thread`. – mburm Mar 09 '19 at 17:48
  • @Andy I don't think that this will change something. This is the same application which has a different behavior in dependence of the argument but a part is used in both paths. I can devide the application in a console application, WPF application and a shared component. Then I can call the WPF application from the console application and this will be closed. But I would prefer to hold it in one application. – mburm Mar 09 '19 at 17:53
  • I could avoid the STA exception after starting the WPF window in a new `Thread`. I have to change the `Thread` start method to `Thread thread = new Thread(...); thread.SetApartmentState(ApartmentState.STA); thread.Start();` The behavior is the same like without a new `Thread`. – mburm Mar 09 '19 at 18:00

2 Answers2

0

I could find a solution. According of the accepted answer of this post Show/Hide the console window of a C# console application I hide the console window.

using System;
using System.Runtime.InteropServices;
using System.Windows;

namespace DeploymentPreparer
{

    class Program
    {

        [STAThread]
        static void Main(string[] args)
        {
            string option = args[0];

            switch (option)
            {
                case "WPF":
                    RunApplication();

                    break;
                default:
                    DoSomething();

                    break;
            }
        }

        private static void RunApplication()
        {
            ShowWindow(GetConsoleWindow(), SW_HIDE);
            Application app = new Application();
            app.Run(new MainWindow());
        }

        private static void DoSomething()
        {
            // ...
        }

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

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

        const int SW_HIDE = 0;
        const int SW_SHOW = 5;
    }
}

Now I have either the console or the WPF window. If the WPF window is shown the console window is hidden.

mburm
  • 1,417
  • 2
  • 17
  • 37
0

I tried the following method that seems to work: Create a normal Console App. In case of "WPF" argument start the WPF application as a new process. In case of any other argument - call DoSomething()

Example:

using System;
using System.Diagnostics;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            string option = "";
            if (args.Length > 0)
            {
                option = args[0];
            }

            switch (option)
            {
                case "WPF":

                    try
                    {
                        using (Process myProcess = new Process())
                        {
                            myProcess.StartInfo.UseShellExecute = false;

                            // Use correct path to the WPF Application
                            myProcess.StartInfo.FileName = @"C:\Users\Danny\Source\Repo\WpfApp\bin\Debug\WpfApp.exe";
                            myProcess.Start();
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                        Console.WriteLine("Press any key to continue ...");
                        Console.ReadKey();
                    }

                    break;
                default:
                    DoSomething();

                    break;
            }
        }

        private static void DoSomething()
        {
            // …
            Console.WriteLine("Doing Something ...");
            Console.WriteLine("Press any key to continue ...");
            Console.ReadKey();
        }
    }
}
Danny
  • 21
  • 1