Завершение работы приложения WPF из App.xaml.cs

В настоящее время я пишу приложение WPF, которое выполняет обработку аргументов командной строки в App.xaml.cs (что необходимо, потому что событие Startup кажется рекомендуемым способом получения этих аргументов). Исходя из аргументов, я хочу выйти из программы уже в тот момент, что, насколько я знаю, должно быть сделано в WPF с Application.Current.Shutdown() или в этом случае (как я в текущем объекте приложения), вероятно, также просто this.Shutdown(),

Единственная проблема состоит в том, что это, кажется, не работает правильно. Я прошел через отладчик и код после Shutdown() Строка все еще выполняется, что приводит к ошибкам в методе, так как я ожидал, что приложение не будет жить так долго. Также все еще загружается главное окно (объявленное в атрибуте StartupUri в XAML).

Я проверил документацию этого метода и ничего не нашел в комментариях, которые говорят мне, что я не должен использовать его во время Application.Startup или же Application совсем.

Итак, как правильно выйти из программы в этот момент, т.е. е. Startup обработчик события в Application объект?

4 ответа

Решение

Сначала удалите свойство StartupUri из App.xaml, а затем используйте следующее:

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

Если вы удаляете StartupUri из app.xaml для приложения с MainWindow, вам необходимо убедиться, что вы сделали следующий вызов в вашем методе OnStartup, иначе приложение не завершится, когда закроется ваше MainWindow.

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

@Frank Schwieterman, что-то в этом роде может помочь вам с проблемой окна консоли.

Я сделал это немного иначе, чтобы не настраивать StartupUri а также ShutdownModeсвойства. Сначала отредактируйте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>

Затем добавьте Application_Startup к коду вместе с OnExit:

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

Напишите в 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;  
    }  
    ...
}
Другие вопросы по тегам