2

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

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() 函数?

4

3 回答 3

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);
       }
   }
于 2012-05-25T17:28:30.780 回答
0

这是我试图阻止的窗口:

锁定文件对话框

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

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

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

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

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


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

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

但是在卸载时,它首先停止服务,然后卸载第二个。

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

于 2015-03-04T15:44:57.707 回答
0

我想做类似的事情,并最终在我的安装程序项目中使用此代码来处理触发 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 服务项目的主要输出的操作。这对我有用,并且每次我测试它时都给了我一个干净的卸载。

于 2019-02-04T14:50:27.347 回答