3

3 つの Windows アプリケーションを一緒にインストールする .net インストーラー アプリケーションで問題に直面しています。これら 3 つのアプリでは、1 つが Windows サービスです。したがって、私のインストーラー プロジェクトには、これら 3 つの Windows アプリからの 3 つの主要な出力があります。

インストールすると、これらすべてが期待どおりにインストールされ、インストール後に Windows サービスが自動的に「開始」されます。

ただし、アプリケーションをアンインストールすると (Windows サービスが「実行中」モードのときに)、インストーラーは「使用中のファイル」ダイアログを表示し、最終的にはサービスがアンインストールされず、他のものが削除されます。ただし、アンインストール前に Windows サービスを停止しておけば、問題なく完了します。

上記の問題は、インストーラー アプリが service.exe ファイル (インストーラーにもバンドルされているため) を削除しようとするために発生すると思います。

以下の代替案を試しました:

  1. サービスを停止しようとしたカスタムインストーラーを追加することで、これを克服しようとしました。しかし、それも機能していないようです。その理由は、デフォルトの「アンインストール」アクションが「アンインストール」カスタム アクションの前に実行されるためです。(失敗した)

  2. Windows サービスアプリケーションの「一次出力」の「永続」プロパティを「true」に設定します。私は、インストーラーがプライマリ出力に関連するファイルを単純にスキップすると想定していました。しかし(失敗)

誰もがこの種の問題に直面したことがあり、同じことについてあなたの考えを共有してください.

アンインストールが正常に完了するように、アンインストール前にサービスを停止するにはどうすればよいですか?

4

1 に答える 1

0

私はずっと前にWindowsサービスで同様の問題を抱えていましたが、WaitForStatus(ServiceControllerStatus)メソッドを呼び出すことで解決できました。サービスをシャットダウンするにはしばらく時間が必要であり、サービスが完全に停止する前に続行しています。Shutdownアンインストールのロジックと、ステータスが停止したときに実行したいことを記述します。

アンインストールしていて、アンインストールする前にサービスを停止したい場合は、アンインストール カスタム アクションをオーバーライドし、それを停止するコードを追加してから、 を呼び出す必要がありますbase.UninstallWaitForStatus15 秒の制限では、サービスの応答性とシャットダウン時の動作によっては、サービスをシャットダウンするのに十分な時間がない場合があることに注意してください。Dispose()また、 (またはこの例のように Close )を呼び出すようにしServiceControllerてください。そうしないと、内部サービス ハンドルがすぐに解放されず、まだ使用中の場合、サービスをアンインストールできないからです。

MSDN リンク

これは、これを実装して EventLogger に記録する方法の単なる例です。

public override void Uninstall(System.Collections.IDictionary savedState)
{
 ServiceController controller = new ServiceController("My Service");
 try
 {
  if (controller.Status == ServiceControllerStatus.Running | controller.Status == ServiceControllerStatus.Paused)
  {
   controller.Stop();
   controller.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 0, 30));
   controller.Close();
  }
 }
 catch (Exception ex)
 {
  string source = "My Service Installer";
  string log = "Application";
  if (!EventLog.SourceExists(source))
  {
   EventLog.CreateEventSource(source, log);
  }
  EventLog eLog = new EventLog();
  eLog.Source = source;
  eLog.WriteEntry(string.Concat(@"The service could not be stopped. Please stop the service manually. Error: ", ex.Message), EventLogEntryType.Error);
 }
 finally
 {
  base.Uninstall(savedState);
 }
}
于 2013-01-23T11:58:58.770 に答える