私は、新しいバージョンがあるときに自動的にアプリケーションを再起動するためのWindowsサービスを手に入れようとしています。私のコードは以下の通りですが、実際には動作します。私の質問はこれです:どこか大きなノーノーはありますか?私は、別々のスレッドでアプリドメインを作成するのは初めてです。これを実現するためのより洗練された方法があるかどうかを知りたいと思います。また、私がこれをどのように扱っているかについて、私は大きな盲点があるかもしれないと心配しています。アドバイスをいただければ幸いです。別のスレッドにアプリケーションドメインを持つ自己更新アプリケーション
2つの一般的な部分があります:実行中のWindowsサービス、別のプロセスで自分のアプリケーションを起動し、そのアプリケーションの新しいバージョンが利用可能であることを検出するためにポーリングします。 2番目の部分は、起動、更新、再起動される実際のアプリです。
まず、サービスが開始されると、LoadApp()が呼び出され、アプリケーションの実行が開始されます。
private void Process(object stateInfo)
{
if (!Monitor.TryEnter(_locker)) { return; }
try
{
// Check for new binaries. If new, copy the files and restart the app domain.
if (!NewAppVersionReady()) { return; }
DeleteFiles();
CopyFiles();
RestartAppDomain();
}
finally
{
Monitor.Exit(_locker);
}
}
RestartAppDomain()次のようになります。そして、
private void LoadApp()
{
// ** appDomainSetup here **
this._appDomain = AppDomain.CreateDomain("MyUpdatedApp", AppDomain.CurrentDomain.Evidence, appDomainSetup);
this._tokenSource = new CancellationTokenSource();
Task.Factory.StartNew(() =>
{
try
{
this._appDomain.ExecuteAssembly(assembly);
}
catch (AppDomainUnloadedException ex)
{
Debug.WriteLine(ex.ToString());
}
}, _tokenSource.Token);
}
、10秒ごとに、タイマーは、このメソッドを呼び出します。このメソッドの2行目にappドメインをアンロードすると、例外が発生することに注意してください。 (私は例外をキャッチし、基本的にはそれを無視してその周りを取得する。)
private void RestartAppDomain()
{
this._tokenSource.Cancel();
AppDomain.Unload(this._appDomain);
LoadApp();
}
編集:私は以来、AppDomain.Unload()ラインが不要であることが判明しました。それがなければ、サービスはまだ新しいバージョンでアプリケーションを更新してから、新しいバージョンのアプリケーションを開始します。私の大きな関心事は、トークンソースでCancel()を呼び出すことです。私はアプリを強制的にシャットダウンするのではなく、正常にシャットダウンできるようにしたいと思っています。
あなたはそれが働いていることを聞いてうれしい!私は非常に似たようなことをやっているので、あなたのコード/擬似コードの比較をもっと見ることに興味があり、お互いに何かを学ぶことができるかもしれません。私の主な目標は、データベースでアセンブリをホストすることでしたが、共通の依存関係(IStartStopインターフェイス、余分なDLL)の必要性を避けるなど、管理できるいくつかのきれいな側面があります。 – Thracx
どうやって共通の依存関係を避けましたか? –