【问题标题】:Automatically Stop Windows Service at Uninstall卸载时自动停止 Windows 服务
【发布时间】:2012-05-25 17:03:42
【问题描述】:

安装我的服务后,我有一个处理程序,它会在安装后启动该服务。

private void InitializeComponent()
{
    ...
    this.VDMServiceInstaller.AfterInstall += ServiceInstaller_AfterInstall;
}


private void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e)
{
    ServiceController sc = new ServiceController("MyService");
    sc.Start();
}

我想在卸载之前停止服务,所以我向 InitializeComponent() 添加了一个额外的处理程序。

this.ServiceInstaller.BeforeUninstall += ServiceInstaller_BeforeUninstall;

并添加了功能:

private void ServiceInstaller_BeforeUninstall(object sender, InstallEventArgs e)
{
    try
    {
        ServiceController sc = new ServiceController("MyService");
        if (sc.CanStop)
        {
            sc.Stop();
            sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);
        }
    }
    catch (Exception exception)
    {}
}

但服务在卸载前不会停止。我是否不正确地使用了 ServiceController.Stop() 函数?

【问题讨论】:

  • 8 年前问过,这仍然是一个问题。在我的例子中,我创建了用于创建另一个 Service2 的 Service1。 Service1 只是具有 API 的包装器,我可以调用这些 API 来启动 Service2。有趣的是,Service1 API 在卸载后将激活超过 2 分钟。我想完全停止服务然后卸载

标签: windows-services servicecontroller


【解决方案1】:

以下内容对您有帮助吗:

    protected override void OnBeforeUninstall(IDictionary savedState)
    {
       ServiceController controller = new ServiceController("ServiceName");

       try
       {

          if(controller.Status == ServiceControllerStatus.Running | controller.Status == ServiceControllerStatus.Paused)
          {
             controller.stop();
          }
          controller.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0,0,0,15));

          controller.Close();
       }
       catch(Exception ex)
       { 
          EventLog log = new EventLog();
          log.WriteEntry("Service failed to stop");
       }

       finally
       {
          base.OnBeforeUninstall(savedState);
       }
   }

【讨论】:

  • 不起作用.. 几乎就像该函数没有被调用,因为该函数还应该引发 BeforeUninstall 事件。
【解决方案2】:

这是我试图阻止的窗口:

我已经测试了所有可用的覆盖,在提示关闭应用程序的对话框出现之前,它们都没有执行。

甚至类构造函数都不够早。

我的结论是,就像安装程序项目一样,您不能在对话框之前通过代码停止服务。

由于没有其他方法可以在项目中执行代码,我看不出有任何方法可以实现这一点。

我真的很希望它有所不同,因为我自己非常需要这个,但是安装程序项目中没有任何“钩子”可用,可以尽早进入以解决问题。


我最好的建议是制作两个安装程序。

一个充当第二个的包装器,并且在安装时正常启动第二个安装程序。

但在卸载时,它会先停止服务,然后再卸载。

但这对我来说太过分了,所以我没有进一步探索。

【讨论】:

    【解决方案3】:

    我想做类似的事情,并最终在我的安装程序项目中使用此代码来处理触发 BeforeUninstall 事件时:

    private void SessionLoginMonitorInstaller_BeforeUninstall(object sender, InstallEventArgs e)
    {
        try
        {
            using (ServiceController sv = new ServiceController(SessionLoginMonitorInstaller.ServiceName))
            {
                if(sv.Status != ServiceControllerStatus.Stopped)
                {
                    sv.Stop();
                    sv.WaitForStatus(ServiceControllerStatus.Stopped);
                }
            }
        }
        catch(Exception ex)
        {
            EventLog.WriteEntry("Logon Monitor Service", ex.Message, EventLogEntryType.Warning);
        }
    }
    

    项目的自定义操作部分也有一个操作来卸载我的 Windows 服务项目的主要输出。这对我有用,并且每次我测试它时都给了我一个干净的卸载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-28
      • 1970-01-01
      • 2010-10-07
      • 2013-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多