【问题标题】:Open WPF application from console and close console window从控制台打开 WPF 应用程序并关闭控制台窗口
【发布时间】:2019-03-09 17:25:58
【问题描述】:

我有一个具有控制台或 WPF 功能的混合应用程序。 WPF 应用程序是否启动或在控制台窗口中完成某些操作取决于启动时的参数。我能够实现这一点(在stackoverflow上有很多例子可以找到)。现在我希望,如果 WPF 应用程序启动,控制台窗口将关闭。但这会显示出来,如果我关闭它,WPF 应用程序也会关闭。

这是我当前的实现。

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()
        {
            // …
        }
    }
}

如果我尝试在新的Thread 中启动应用程序,应用程序将直接关闭,并且不会显示 WPF 窗口。

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

我不知道如何实现这一点。有没有可能做到这一点?

【问题讨论】:

  • 你为什么打电话给Environment.Exit(0);
  • 试试 process.start("yourwpf.exe");
  • @Mat J 我在一个例子中找到了它。如果我删除此行,我会收到一个错误,即调用 Thread 必须是 STA-Thread
  • @Andy 我不认为这会改变什么。这是同一个应用程序,根据参数具有不同的行为,但在两个路径中都使用了一部分。我可以将应用程序划分为控制台应用程序、WPF 应用程序和共享组件。然后我可以从控制台应用程序调用 WPF 应用程序,这将被关闭。但我更愿意将它保存在一个应用程序中。
  • 在新的Thread 中启动 WPF 窗口后,我可以避免 STA 异常。我必须将Thread 启动方法更改为Thread thread = new Thread(...); thread.SetApartmentState(ApartmentState.STA); thread.Start(); 行为与没有新的Thread 相同。

标签: c# wpf console-application


【解决方案1】:

我可以找到解决方案。根据这篇帖子Show/Hide the console window of a C# console application 接受的答案,我隐藏了控制台窗口。

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

现在我有控制台或 WPF 窗口。如果显示 WPF 窗口,则隐藏控制台窗口。

【讨论】:

    【解决方案2】:

    我尝试了以下似乎可行的方法: 创建一个普通的控制台应用程序。在“WPF”参数的情况下,将 WPF 应用程序作为一个新进程启动。如果有任何其他参数 - 调用 DoSomething()

    例子:

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

    【讨论】:

      猜你喜欢
      • 2012-07-20
      • 2011-12-24
      • 1970-01-01
      • 2022-01-14
      • 2017-09-09
      • 2019-01-18
      • 2016-03-30
      • 1970-01-01
      • 2013-06-30
      相关资源
      最近更新 更多