C#でApplication.Restart()
メソッドを使用すると、現在のアプリケーションが再起動します。ただし、これは常に機能するとは限りません。
この問題の理由はありますか、誰かが私に言うことができますか、なぜそれが常に機能しないのですか?
これには多くの理由があります。メソッドが機能しないわけではありません。むしろ、多くの場合、プログラマーは、アプリケーションが自動的にシャットダウンしたり起動したりするのを止めるようなコードをコードに入れたことを忘れます。 2つの例:
そのような落とし穴がないか、コードを確認してください。空白のアプリケーション内でこの動作が発生している場合、コードよりも実際の機能に問題がある可能性が高くなります。
application restart のMicrosoftのソースコードを確認してください。
私の場合(シングルインスタンスではない)、ここで
Application.Restart();
うまくいかなかった、
System.Diagnostics.Process.Start(Application.ExecutablePath);
Application.Exit();
仕事をしました!
この種の問題に遭遇したのは、メインフォームにカスタムFormClosing
イベントハンドラーがあり、それがロジックを実行してイベントをキャンセルしたときだけです。
私は今、別のインスタンスに遭遇しました、そして、あなたのコメントに基づいて、それはあなたが経験していたことを多分反映します。
Mutexを使用してシングルインスタンスアプリケーションを実行しているとき、かなり埋め込まれた場所からApplication.Restart()
を呼び出していました。これには多くのクリーンアップが必要でした。そのため、前のインスタンスが完了する前に再起動が新しいインスタンスを起動していたようであるため、Mutexは新しいインスタンスの起動を妨げていました。
私のプログラムでは、コンピューター上で実行されるアプリケーションのインスタンスが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();
}
}
_
それでおしまい。
ダンプする前にロックしてみてください。完全なアプリダンプを開始する方法は次のとおりです。あなたのために働くかもしれませんが、そうではないかもしれません。
Context.Application.Lock();
Context.Session.Abandon();
Context.Application.RemoveAll();
Context.Application.Restart();
Context.Application.UnLock();
アプリケーションが最初にネットワーク上の場所から起動され、署名されていない場合(警告ダイアログが最初に表示されます)、再起動せずに終了するだけです。
Application.Restart();
Application.ExitThread();
これは私に感謝しました。
このコードを試してください:
bool appNotRestarted = true;
このコードは関数にも含まれている必要があります。
if (appNotRestarted == true)
{
appNotRestarted = false;
Application.Restart();
Application.ExitThread();
}
私はこれが古いスレッドであることを知っていますが、回避策を見つけました。うまくいけば、これが困っている他の誰かを助けるでしょう。
ClickOnceアプリケーションをコードから起動するときに更新シーケンスをトリガーするソリューションが必要でした。 Applicatoin.Restart
はこれをしませんでした。更新を確認し、組み込みの更新マネージャーを呼び出すことができるようにしたかったので、カスタムの更新マネージャーを作成する必要はありませんでした。
'VB Code Sample
Dim strStart As String = System.Environment.GetFolderPath(Environment.SpecialFolder.StartMenu) & "\Programs\Folder\YourApplication.appref-ms"
Application.Exit()
Try
Process.Start(strStart)
Catch ex As Exception
'Do something with the exception
End Try
この回避策で発生する唯一の問題は、ユーザーがスタートメニューからショートカットを削除できることです。それが懸念される場合は、スタートメニューリンクを選択したフォルダー(できればClickOnceアプリケーションフォルダー)にコピーするためのコードを書くことができます。アプリケーションのスタートメニューアイコンは.lnkや.exeではなく、実際には.appref-msリンクであるため、これは重要です。 ClickOnce .appref-msは.applicationファイルへのリンク以上ですか? を参照してください。このリンクではこれについて詳しく説明しています。
このコードは、ClickOnceシングルインスタンスアプリケーションで機能します。
public static void ApplicationRestart(params string[] commandLine)
{
lock (SynchObj)
{
if (Assembly.GetEntryAssembly() == null)
{
throw new NotSupportedException("RestartNotSupported");
}
if (_exiting)
return;
_exiting = true;
if (Environment.OSVersion.Version.Major < 6) return;
bool cancelExit = true;
try
{
foreach (Form f in Application.OpenForms.OfType<Form>().ToList())
{
f.InvokeIfRequired(frm =>
{
frm.FormClosing += (sender, args) => cancelExit = args.Cancel;
frm.Close();
});
if (cancelExit) break;
}
if (cancelExit) return;
Process.Start(new ProcessStartInfo
{
UseShellExecute = true,
WorkingDirectory = Environment.CurrentDirectory,
FileName = Application.ExecutablePath,
Arguments = commandLine.Length > 0 ? string.Join(" ", commandLine) : string.Empty
});
Application.Exit();
}
finally
{
_exiting = false;
}
}
}
.Net 4.7フレームワークでも同じ問題があります。受け入れられた答えは私の成功の鍵でした。 FormClosingイベントには、時間がかかり再起動プロセスを停止するコードがありました。私がやったことは、このようなセンチネルを置くことでした:
If JustCloseIT = False Then
'all closing code, like logging the session log-out to a database and all those goodies we all do.
End If
その後、Application.Restart()が機能しました!