0

This question relates to restarting an application.

I have seen this question. However, the question, and as far as I have been able to tell, the answers, are almost a decade old, and none of them seem to provide an answer to this specific question ( of how to define second Application object once the first has had its .Shutdown method called ).

Attempting to declare new App( ) after the first has had its .Shutdown( ) method called results in the following exception:

enter image description here

Is there anything that I can do with the original App object to prevent his from happening?

In compliance with the Minimal, Complete and Verifiable Example requirements:

MAKE CERTAIN THAT App.xaml HAS ITS BUILD ACTION SET TO Page.

App.xaml.cs:

using System;

namespace MCVE {
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
    public partial class App {
        private static bool _isRestarting = true;
        public static bool IsRestarting {
            get => _isRestarting;
            set => _isRestarting = value;
        }

        [STAThread]
        public static void Main( ) {
            while ( IsRestarting ) {
                IsRestarting = false;
                App program = new App( );
                program.InitializeComponent( );
                program.Run( );
            }
        }
    }   
}

MainWindow.xaml:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    x:Class="MCVE.MainWindow"
    mc:Ignorable="d" Title="MainWindow" Height="450" Width="800">
    <UniformGrid Rows="1">
        <Button Content="Restart" Click="Restart" />
        <Button Content="Exit" Click="Shutdown" />
    </UniformGrid>
</Window>

MainWindow.Xaml.cs:

using System.Windows;

namespace MCVE {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window {
        public MainWindow( ) {
            InitializeComponent( );
        }

        private void Restart( object sender, RoutedEventArgs e ) {
            App.IsRestarting = true;
            Shutdown( sender, e );
        }

        private void Shutdown( object sender, RoutedEventArgs e ) =>
            Application.Current?.Shutdown( );
    }
}

To Reproduce: Click the button that says Restart.

Will
  • 3,413
  • 7
  • 50
  • 107
  • You need to restart the process again, not just start a new instance of the `App` class. See [`Process.Start`](https://msdn.microsoft.com/en-us/library/h6ak8zt5(v=vs.110).aspx) – Ron Beyer Apr 17 '18 at 20:49
  • @RonBeyer Okay. And in the case where a process has been started by another process, say, when debugging an application in Visual Studio - how do i go about handing off the new process to the calling processes "parent" process? But I suppose that should go in a new question... – Will Apr 17 '18 at 20:55
  • [`System.Diagnostics.Debugger.Launch()`](https://msdn.microsoft.com/en-us/library/system.diagnostics.debugger.launch(v=vs.110).aspx), you may have to pass parameters to the new app to tell it that a debugger was previously attached. – Ron Beyer Apr 17 '18 at 21:00
  • @RonBeyer Suppose I could just `#if DEBUG` it to launch the debugger if it's not attached... Still feels less than ideal but meh. whatever. Thanks for the tips. Hopefully there is some more perfect answer to this. like, how to clear the `AppDomain` of shutdown application instances. – Will Apr 17 '18 at 21:04
  • You can't "clear" the base AppDomain because it can't be unloaded or "reset". The only way to "clear" (unload) an AppDomain is to create a new one, but you can't replace the default. – Ron Beyer Apr 17 '18 at 21:10

1 Answers1

2

The Application class is designed to only run once and be associated with the lifetime of the AppDomain it is loaded into. Even if you could find some way to work around that, it would be going against the intentions of how the class should be used. (See the remarks section here.)

Rather than fighting with the established intention of a specific class, I recommend taking a step back and thinking about what you are trying to accomplish. If you want to restart the entire application, consider starting a new process. If you want to unload and then reload a bunch of things, build that functionality into your code at the appropriate level within the scope of a single Application instance.

Depending what you are trying to accomplish, you may also want to consider reading up on AppDomain (can start here, but there are probably better resources if you search around). An AppDomain is specifically designed to be an encapsulated standalone arena where you can load and unload a bunch of stuff by loading and unloading the whole domain.

I believe it is also possible to run an Application instance in each domain, but I have never tried anything like that. If you do something like this, you should probably avoid running an Application instance in the default domain since that domain can never be unloaded except by shutting down the process.

Xavier
  • 3,254
  • 15
  • 22