Actualizar un Servicio de Windows sin desinstalar


Actualmente tengo que desinstalar la versión anterior de mi servicio antes de instalar la nueva versión. Estoy bastante seguro de que esto tiene algo que ver con que no sea lo suficientemente inteligente como para actualizar o eliminar las antiguas entradas de servicio antes de agregar las nuevas.

¿Hay alguna manera de que el instalador omita el registro del servicio si ya existe? (Puedo asumir que la carpeta de instalación y el nombre del servicio no cambian entre versiones.)

También, hay una manera de detener automáticamente el servicio al desinstalar?


Editar:

Estoy usando paquetes MSI y el proyecto de instalación de Visual Studio.

Author: GEOCHET, 2008-11-29

6 answers

He hecho esto con WiX, que genera.Archivos MSI usando los comandos ServiceInstall y SeviceControl:

<Component Id='c_WSService' Guid='*'>
    <File Id='f_WSService' Name='WSService.exe' Vital='yes' Source='..\wssvr\release\wsservice.exe' />
    <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>

Esto detiene el servicio, instala la nueva versión y reinicia el servicio.

 17
Author: Ferruccio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-05 04:20:35

Utilice la herramienta sc desde una línea de comandos para detener e iniciar el servicio:

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

Cuando se detenga el servicio, actualice los archivos correspondientes y vuelva a iniciar el servicio. Usted debe ser capaz de hacer eso desde su instalador también. Si utiliza Wix para su instalador, eche un vistazo al elemento ServiceControl.

 9
Author: David Pokluda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-29 21:24:29

No uso proyectos de instalación de Visual Studio, por lo que podría estar equivocado, pero parece que no tiene soporte para las tablas ServiceInstall y ServiceControl, que son características estándar de Windows Installer. Esas dos tablas son especialmente para instalar y actualizar servicios....

Wix lo soporta ( ver este ejemplo), Tal vez puedas crear un módulo merge, y usarlo en tu proyecto.

De lo contrario esto podría ayudar: Instalación de servicios con Visual Studio (Phil Wilson)

 8
Author: wimh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-29 21:09:57

¿No puede simplemente detener el servicio, sobrescribir el ejecutable del servicio y luego reiniciar el servicio?

 2
Author: jalf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-29 19:47:05

Usted puede hacer DLL separado que servicio cargaría y llamaría cada vez que hace su trabajo. Asegúrese de que el servicio descarga DLL después de su uso.

Use debe cargarlo en un Dominio de aplicación separado.

ASÍ QUE http://msdn.microsoft.com/en-us/library/c5b8a8f9.aspx

 0
Author: Din,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-29 20:20:35

Mi solución de hacky es modificar el archivo ProjectInstaller.vb para que emita un comando para detener y eliminar el servicio y luego se detiene un poco. Probablemente no tan limpio desde una perspectiva de instalación como modificar el archivo msi, pero mucho más legible/lógico para quien hereda mi código.

Tenga en cuenta que el bit RunCommandCom es descaradamente cribbed de Cómo ejecutar comandos DOS/CMD/Símbolo del sistema desde VB.NET?

Usando este método combinado con el código de Cómo iniciar automáticamente su servicio después de instalar? puede tener la experiencia de instalación de servicio que desee: un servicio que se instala y se inicia automáticamente, y sobrescribirá un servicio que se esté ejecutando actualmente si lo hay.

'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
 0
Author: edhubbell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:19