Обновите службу Windows без удаления - PullRequest
30 голосов
/ 29 ноября 2008

В настоящее время я должен удалить старую версию своего сервиса перед установкой новой версии. Я почти уверен, что это как-то связано с тем, что он недостаточно умен, чтобы обновлять или удалять старые записи службы перед добавлением новых.

Есть ли способ заставить установщик пропустить регистрацию службы, если она уже существует? (Могу предположить, что папка установки и имя службы не меняются между версиями.)

Кроме того, есть ли способ автоматической остановки службы при удалении?


Edit:

Я использую пакеты MSI и проект установки Visual Studio.

Ответы [ 6 ]

17 голосов
/ 30 ноября 2008

Я сделал это с помощью WiX, который генерирует файлы .MSI с помощью команд ServiceInstall & 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>

Это останавливает службу, устанавливает новую версию и перезапускает службу.

9 голосов
/ 30 ноября 2008

Используйте sc инструмент из командной строки, чтобы остановить и запустить службу:

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

Когда служба остановлена, обновите соответствующие файлы и снова запустите службу. Вы должны быть в состоянии сделать это и из установщика. Если вы используете Wix для своего установщика, взгляните на ServiceControl element.

8 голосов
/ 30 ноября 2008

Я не использую проекты установки Visual Studio, поэтому могу ошибаться, но, похоже, он не поддерживает таблицы ServiceInstall и ServiceControl, которые являются стандартными функциями установщика Windows. Эти две таблицы специально предназначены для установки и обновления служб ....

Wix поддерживает его ( см. Этот пример ). Возможно, вы сможете создать модуль слияния и использовать его в своем проекте.

В противном случае это может помочь: Установка служб с помощью Visual Studio (Фил Уилсон)

2 голосов
/ 29 ноября 2008

Разве вы не можете просто остановить службу и переписать исполняемый файл службы, а затем перезапустить службу?

0 голосов
/ 11 января 2013

Мое хакерское решение - изменить файл ProjectInstaller.vb, чтобы он выдал команду, чтобы остановить и удалить службу, а затем немного сделал паузу. Вероятно, не такой аккуратный с точки зрения установки, как изменение файла msi, но гораздо более читаемый / логичный для тех, кто наследует мой код.

Обратите внимание, что бит RunCommandCom явно взломан из Как запускать команды DOS / CMD / Command Prompt из VB.NET?

Используя этот метод в сочетании с кодом из Как автоматически запустить службу после установки? вы можете получить желаемую возможность установки службы - Служба, которая устанавливается и запускается автоматически и перезаписывает текущую службу если есть один.

'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 голосов
/ 29 ноября 2008

Вы можете создать отдельную DLL, которую служба будет загружать и вызывать каждый раз, когда она выполняет свою работу. Убедитесь, что служба выгружает DLL после использования.

Использование должно загрузить его в отдельный домен приложения.

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

...