在不卸载的情况下升级Windows服务

时间:2008-11-29 19:31:42

标签: .net windows-services windows-installer

目前我必须在安装新版本之前卸载旧版本的服务。我很确定这与它在提供新服务条目之前不够智能更新或删除旧服务条目有关。

有没有办法让安装程序跳过注册服务(如果它已经存在)? (我可以假设安装文件夹和服务名称在版本之间不会改变。)

另外,有没有办法在卸载时自动停止服务?


编辑:

我正在使用MSI包和Visual Studio安装项目。

6 个答案:

答案 0 :(得分:17)

我使用WiX生成了这个,它使用ServiceInstall&生成.MSI文件。 SeviceControl命令:

<Component Id='c_WSService' Guid='*'>
    <File Id='f_WSService' Name='WSService.exe' Vital='yes' Source='..\wssvr\release\wsservice.exe' KeyPath="yes" />
    <ServiceInstall Id='WSService.exe' Name='WSService' DisplayName='[product name]' Type='ownProcess'
                    Interactive='no' Start='auto' Vital='yes' ErrorControl='normal'
                    Description='Provides local and remote access to [product name] search facilities.' />
    <ServiceControl Id='WSService.exe' Name='WSService' Start='install' Stop='both' Remove='uninstall' Wait='yes' />
</Component>

这会停止服务,安装新版本并重新启动服务。

答案 1 :(得分:9)

从命令行使用 sc 工具停止并启动服务:

sc stop {name of your service}
sc start {name of your service}

当服务停止时,更新相应的文件,然后再次启动服务。您也应该可以从安装程序中执行此操作。如果您使用Wix作为安装程序,请查看ServiceControl元素。

答案 2 :(得分:8)

我不使用Visual Studio安装项目,所以我可能错了,但它似乎不支持作为Windows Installer标准功能的ServiceInstall和ServiceControl表。这两个表专门用于安装和更新服务....

Wix支持它(see this example),也许您可​​以创建合并模块,并在项目中使用它。

否则这可能会有所帮助:Installing Services with Visual Studio (Phil Wilson)

答案 3 :(得分:2)

您不能只停止服务,并覆盖服务可执行文件,然后重新启动服务吗?

答案 4 :(得分:0)

您可以创建单独的DLL,每次执行其工作时,该服务都会加载和调用。确保该服务在使用后卸载DLL。

使用时应将其加载到单独的应用程序域中。

SO http://msdn.microsoft.com/en-us/library/c5b8a8f9.aspx

答案 5 :(得分:0)

我的hacky解决方案是修改ProjectInstaller.vb文件,以便它发出停止和删除服务的命令,然后暂停一下。可能不像修改msi文件那样整体安装,但对于继承我的代码的人来说,更具可读性/逻辑性。

请注意RunCommandCom位来自How to run DOS/CMD/Command Prompt commands from VB.NET?

使用此方法结合How to automatically start your service after install?中的代码,您可以获得所需的服务安装体验 - 自动安装和启动的服务,如果有的话,将覆盖当前正在运行的服务。

'This works.  It leaves the MSI in a state that tells you to reboot the PC, but you really don't need to.

Private Sub ProjectInstaller_BeforeInstall(sender As Object, e As System.Configuration.Install.InstallEventArgs) Handles Me.BeforeInstall

    Dim sEchoMessage As String = String.Empty
    sEchoMessage &= " & ECHO ******************       Please be patient      *******************************"
    sEchoMessage &= " & ECHO Pausing to stop and delete the previous version of the following service:"
    sEchoMessage &= " & ECHO " & ServiceInstaller1.ServiceName
    sEchoMessage &= " & ECHO -------------------------------------------------------------------------------"
    sEchoMessage &= " & ECHO After install is complete, you may see a message that says you need to reboot."
    sEchoMessage &= " & ECHO You may IGNORE this message - The service will be installed and running."
    sEchoMessage &= " & ECHO There is NO Reboot required."
    sEchoMessage &= " & ECHO *******************************************************************************"

    RunCommandCom("sc stop " & ServiceInstaller1.ServiceName & " & sc delete " & ServiceInstaller1.ServiceName & sEchoMessage, 15000)

End Sub

Private Sub RunCommandCom(command As String, mSecSleepAfterExecution As Integer)

    Using p As Process = New Process()
        Dim pi As ProcessStartInfo = New ProcessStartInfo()
        pi.Arguments = " /K " + command
        pi.FileName = "cmd.exe"
        p.StartInfo = pi
        p.Start()
        System.Threading.Thread.Sleep(mSecSleepAfterExecution)
        p.CloseMainWindow()
    End Using

End Sub