简体   繁体   English

从 App.xaml.cs 关闭 WPF 应用程序

[英]Shutting down a WPF application from App.xaml.cs

I am currently writing a WPF application which does command-line argument handling in App.xaml.cs (which is necessary because the Startup event seems to be the recommended way of getting at those arguments).我目前正在编写一个 WPF 应用程序,它在 App.xaml.cs 中进行命令行参数处理(这是必要的,因为 Startup 事件似乎是获取这些参数的推荐方式)。 Based on the arguments I want to exit the program at that point already which, as far as I know, should be done in WPF with Application.Current.Shutdown() or in this case (as I am in the current application object) probably also just this.Shutdown() .基于 arguments 我想在那个时候退出程序,据我所知,应该在 WPF 中使用Application.Current.Shutdown()或在这种情况下(因为我在当前应用程序对象中)完成也只是this.Shutdown()

The only problem is that this doesn't seem to work right.唯一的问题是这似乎无法正常工作。 I've stepped through with the debugger and code after the Shutdown() line still gets executed which leads to errors afterwards in the method, since I expected the application not to live that long.Shutdown()行仍然被执行之后,我已经逐步完成了调试器和代码,这导致了方法中的错误,因为我预计应用程序不会活那么久。 Also the main window (declared in the StartupUri attribute in XAML) still gets loaded.此外,仍会加载主要的 window(在 XAML 的 StartupUri 属性中声明)。

I've checked the documentation of that method and found nothing in the remarks that tell me that I shouldn't use it during Application.Startup or Application at all.我已经检查了该方法的文档,但在备注中没有发现任何内容告诉我根本不应该在Application.StartupApplication期间使用它。

So, what is the right way to exit the program at that point, ie the Startup event handler in an Application object?那么,此时退出程序的正确方法是什么,即Application object 中的Startup事件处理程序?

First remove the StartupUri property from App.xaml and then use the following:首先从 App.xaml 中删除 StartupUri 属性,然后使用以下内容:

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        bool doShutDown = ...;

        if (doShutDown)
        {
            Shutdown(1);
            return;
        }
        else
        {
            this.StartupUri = new Uri("Window1.xaml", UriKind.Relative);
        }
    }

If you remove the StartupUri from app.xaml for an application with a MainWindow you need to make sure you make the following call in your OnStartup method otherwise the application will not terminate when your MainWindow closes.如果从 app.xaml 中删除具有 MainWindow 的应用程序的 StartupUri,则需要确保在 OnStartup 方法中进行以下调用,否则应用程序不会在 MainWindow 关闭时终止。

this.ShutdownMode = System.Windows.ShutdownMode.OnMainWindowClose;

@Frank Schwieterman, something along these lines may help you with your console window issue. @Frank Schwieterman,这些方面的内容可能会帮助您解决控制台窗口问题。

I did this a little differently to avoid having to set the StartupUri and ShutdownMode properties.为了避免必须设置StartupUriShutdownMode属性,我的做法略有不同。 First edit the App.xaml file and replace StartupUri with Startup :首先编辑App.xaml文件并将StartupUri替换为Startup

<Application x:Class="Menu.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:Menu"
         Startup="Application_Startup">
    <Application.Resources>
    </Application.Resources>
</Application>

Then add Application_Startup to the code along with OnExit :然后将Application_StartupOnExit一起添加到代码中:

public partial class App : Application
{
    private volatile static Mutex s_mutex;

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        s_mutex = new Mutex(true, @"Global\MenuMutex", out bool grantedOwnership);

        if (!grantedOwnership)
        {
            MessageBox.Show($"Another instance is already running!", "Error", MessageBoxButton.OK, MessageBoxImage.Exclamation);
            Current.Shutdown();
        }
        else
            new MainWindow().Show();
    }

    protected override void OnExit(ExitEventArgs e)
    {
        s_mutex?.ReleaseMutex();
        s_mutex?.Dispose();
        s_mutex = null;
        base.OnExit(e);
    }

Write in the Application_Startup:在Application_Startup中写入:

private void Application_Startup(object sender, StartupEventArgs e)  
{  
    ...
    if (!condition)  
    {  
        e.GetType()  
          .GetProperty("PerformDefaultAction", BindingFlags.Instance | BindingFlags.NonPublic)  
          .SetValue(e, false);  
        Shutdown();  
        return;  
    }  
    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM