web-dev-qa-db-ja.com

WPFアプリケーションを再起動するにはどうすればよいですか?

WPFアプリケーションを再起動するにはどうすればよいですか?私が使用したWindowsフォーム

System.Windows.Forms.Application.Restart();

WPFでそれを行う方法は?

72
Hooch

私はこれを見つけました:それは動作します。しかし。より良い方法はありますか?

System.Diagnostics.Process.Start(Application.ResourceAssembly.Location);
Application.Current.Shutdown();
91
Hooch

私はこれをWPFで正常に使用しました:

System.Windows.Forms.Application.Restart();
System.Windows.Application.Current.Shutdown();
35
epalm
Application.Restart();

または

System.Diagnostics.Process.Start(Application.ExecutablePath);
Application.Exit();

私のプログラムでは、コンピューター上で実行されるアプリケーションのインスタンスが1つだけであることを保証するミューテックスを持っています。これにより、ミューテックスがタイムリーにリリースされなかったため、新しく起動したアプリケーションが起動しなくなりました。その結果、アプリケーションが再起動していることを示す値をProperties.Settingsに入れました。 Application.Restart()を呼び出す前に、Properties.Settings値がtrueに設定されます。 Program.Main()で、特定のproperty.settings値のチェックも追加しました。trueの場合はfalseにリセットされ、Thread.Sleep(3000)があります。

あなたのプログラムには、ロジックがあるかもしれません:

if (ShouldRestartApp)
{
   Properties.Settings.Default.IsRestarting = true;
   Properties.Settings.Default.Save();
   Application.Restart();
}

Program.Main()で

[STAThread]
static void Main()
{
   Mutex runOnce = null;

   if (Properties.Settings.Default.IsRestarting)
   {
      Properties.Settings.Default.IsRestarting = false;
      Properties.Settings.Default.Save();
      Thread.Sleep(3000);
   }

   try
   {
      runOnce = new Mutex(true, "SOME_MUTEX_NAME");

      if (runOnce.WaitOne(TimeSpan.Zero))
      {
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);
         Application.Run(new Form1());
      }
   }
   finally
   {
      if (null != runOnce)
         runOnce.Close();
   }
}

それでおしまい。

10
Pascalsz

1秒後にコマンドラインでプログラムの新しいインスタンスを実行します。遅延現在のインスタンスのシャットダウン中。

_ProcessStartInfo Info = new ProcessStartInfo();
Info.Arguments = "/C choice /C Y /N /D Y /T 1 & START \"\" \"" + Assembly.GetEntryAssembly().Location + "\"";
Info.WindowStyle = ProcessWindowStyle.Hidden;
Info.CreateNoWindow = true;
Info.FileName = "cmd.exe";
Process.Start(Info);
Process.GetCurrentProcess().Kill();
_

編集:

私はコードを修正しました:

代わりに:Assembly.GetExecutingAssembly().Location

これ:Assembly.GetEntryAssembly().Location

これは、関数が個別のdllで実行される場合に重要です。

そして-

代わりに:Application.Current.Shutdown();

これ:Process.GetCurrentProcess().Kill();

WinFormsとWPFの両方で動作します。両方に対応するように設計されたdllを作成する場合、非常に重要です。

9
magicode
Application.Current.Shutdown();
System.Windows.Forms.Application.Restart();

この順序でうまくいきましたが、別の方法でアプリの別のインスタンスを開始しました。

7
Jraco11

これらの提案されたソリューションは動作する可能性がありますが、別のコメンターが述べたように、彼らはちょっとしたハックのように感じます。これを行うもう少しクリーンな方法は、現在の(閉じている)アプリケーションが終了するのを待つための遅延(5秒など)を含むバッチファイルを実行することです。

これにより、2つのアプリケーションインスタンスが同時に開くことを防ぎます。私の場合、2つのアプリケーションインスタンスを同時に開くことは無効です。ハードウェアリソースを使用しているアプリケーションのため、ミューテックスを使用して1つのアプリケーションのみを開いています。

Windowsバッチファイルの例( "restart.bat"):

sleep 5
start "" "C:\Dev\MyApplication.exe"

WPFアプリケーションで、次のコードを追加します。

// Launch the restart batch file
Process.Start(@"C:\Dev\restart.bat");

// Close the current application
Application.Current.MainWindow.Close();
2
dodgy_coder
 Application.Restart();
 Process.GetCurrentProcess().Kill();

私にとって魅力的な仕事

1
abrfra

Hoochの例を取り上げて、私は以下を使用しました。

using System.Runtime.CompilerServices;

private void RestartMyApp([CallerMemberName] string callerName = "")
{
    Application.Current.Exit += (s, e) =>
    {
        const string allowedCallingMethod = "ButtonBase_OnClick"; // todo: Set your calling method here

        if (callerName == allowedCallingMethod)
        {
            Process.Start(Application.ResourceAssembly.Location);
        }
     };

     Application.Current.Shutdown(); // Environment.Exit(0); would also suffice 
}
0
breen