从控制台应用程序重新打开WPF窗口

我想从Console应用程序打开一个WPF窗口。 在提到这篇文章后 ,它运作正常。

问题是:当用户关闭WPF窗口(手动)时,不能再从控制台重新打开它,抛出exception消息:“无法在同一AppDomain中创建多个System.Windows.Application实例。”

这是代码:

class Program { static void Main(string[] args) { string input=null; while ((input = Console.ReadLine()) == "y") { //Works fine at the first iteration, //But failed at the second iteration. StartWpfThread(); } } private static void OpenWindow() { //Exception(Cannot create more than one System.Windows.Application instance in the same AppDomain.) //is thrown at the second iteration. var app = new System.Windows.Application(); var window = new System.Windows.Window(); app.Run(window); //User closes the opened window manually. } private static void StartWpfThread() { var thread = new Thread(() => { OpenWindow(); }); thread.SetApartmentState(ApartmentState.STA); thread.IsBackground = false; thread.Start(); } } 

如何重新打开WPF窗口?

您不应该与窗口一起创建应用程序,而只能单独创建一次,同时通过分别设置ShutdownMode确保它不会在窗口关闭后退出,例如

 class Program { static Application app; static void Main(string[] args) { var appthread = new Thread(new ThreadStart(() => { app = new Application(); app.ShutdownMode = ShutdownMode.OnExplicitShutdown; app.Run(); })); appthread.SetApartmentState(ApartmentState.STA); appthread.Start(); while (true) { var key =Console.ReadKey().Key; // Press 1 to create a window if (key == ConsoleKey.D1) { // Use of dispatcher necessary as this is a cross-thread operation DispatchToApp(() => new Window().Show()); } // Press 2 to exit if (key == ConsoleKey.D2) { DispatchToApp(() => app.Shutdown()); break; } } } static void DispatchToApp(Action action) { app.Dispatcher.Invoke(action); } } 

此外,如果你想重新打开同一个窗口,确保它永远不会完全关闭,为此你可以处理Closing事件并使用e.Cancel = true;取消它e.Cancel = true; ,然后只需在窗口上调用Hide来“关闭”它,然后再Show “打开”它。

当您将窗口作为参数添加到app.Run时,您可以将应用的生命周期链接到窗口。 不要那样做:

 private static void OpenWindow() { //Exception(Cannot create more than one System.Windows.Application instance in the same AppDomain.) //is thrown at the second iteration. var app = new System.Windows.Application(); var window = new System.Windows.Window(); app.Run(); window.Show(); //User closes the opened window manually. } 

我自己没有机会对此进行测试,但在阅读了您的错误之后,我找到了一些信息。 基本上,听起来你运行的AppDomain只能在每个应用程序中使用一次 – 所以每次你想重新创建应用程序时,你可能需要创建一个新的AppDomain 。 有关详细信息,请参见此处 。

或者,您可以使用System.Diagnostics.Process.Start(...)来正确启动应用程序。 请参阅此处以获取Process类的文档。

最后,如果您只是想让用户从命令行运行应用程序,则编写命令脚本并从命令行执行该脚本可能更简单。