Проблема со службой Windows, программно перезапускающая себя - PullRequest
1 голос
/ 10 февраля 2012

Этот вопрос основан на другом вопросе: Как служба Windows может программно перезапустить себя?

Я реализовал одно из решений в предыдущем вопросе так:

Dim proc As New Process()
Dim psi As New ProcessStartInfo()

psi.CreateNoWindow = True
psi.FileName = "cmd.exe"
psi.Arguments = "/C net stop YOURSERVICENAMEHERE && net start YOURSERVICENAMEHERE"
psi.LoadUserProfile = False
psi.UseShellExecute = False
psi.WindowStyle = ProcessWindowStyle.Hidden
proc.StartInfo = psi
proc.Start()

Я вижу 2 проблемы с этим:

  1. Журнал событий выдает это предупреждение при каждом перезапуске службы: Windows detected your registry file is still in use by other applications or services... 5 user registry handles leaked from ...
  2. Служба может иногда не перезапускать себя. После изучения этого, я думаю, что служба заканчивается до того, как процесс попытается перезапустить ее. Причина этого заключается в том, что команда net stop не будет выполнена, поскольку служба уже остановлена, что приведет к тому, что она не выполнит команду net start.

Вот полный код:

Private Sub Timer_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs) Handles _timer.Elapsed
    ' we do not want the timer stepping on itself (ie. the time interval elapses before the first call is done processing
    _timer.Stop()

    ' do some processing here
    Dim shouldRestart As Boolean = ProcessStuff()

    If shouldRestart Then
        Dim proc As New Process()
        Dim psi As New ProcessStartInfo()

        psi.CreateNoWindow = True
        psi.FileName = "cmd.exe"
        psi.Arguments = "/C net stop ""My Cool Service"" && net start ""My Cool Service"""
        psi.LoadUserProfile = False
        psi.UseShellExecute = False
        psi.WindowStyle = ProcessWindowStyle.Hidden
        proc.StartInfo = psi
        proc.Start()
        Return
    End If

    _timer.Start()
End Sub 

Предполагая, что я прав (большое предположение) с проблемой 2, вы думаете, что замена оператора Return командой Thread.Sleep (10000) сработает?

Ответы [ 2 ]

1 голос
/ 10 февраля 2012

Я думаю, что лучший способ сделать это - запустить командный файл вместо встроенного набора команд.Таким образом, пакетный файл может запустить «net stop» и получить ошибку, которая не влияет на выполнение дополнительных операторов.

Регистрируете ли вы «сбои» (ненормальные завершения) службы в журнале событий, используярегистрация сервиса в services.msc?Если нет, и вы просто говорите ему «перезапустить службу», если исполняемый файл когда-либо выходит по какой-либо причине, тогда это просто;Вместо этого вызовите Application.Exit (), и исполняемый файл службы будет нормально завершен, затем Windows перезапустит его.

Что касается дескрипторов реестра, если ваша служба работает с данными реестра, ваш метод OnStop должен задерживать программувыход, пока все ручки не убраны;это означает, что все фоновые потоки должны быть уведомлены об отмене, и им должно быть разрешено делать это изящно (что, в свою очередь, означает, что многопоточные процессы должны разрабатываться с возможностью отмены без простого их «уничтожения»), все открытые потоки файлов и реестра должны быть закрытыи должным образом утилизируются, и, как правило, служба не должна оставлять никаких «потертых концов».OnStop () может задержать выполнение программы примерно на 10 секунд, пока это происходит;если для полного выхода из службы требуется больше времени, Windows выдаст ошибку, и ваша служба в конечном итоге остановится, но не будет перезапущена.

0 голосов
/ 10 февраля 2012

Будет ли это работать для вас?(Откровенно саморекламирующийся аналогичный ответ, который я сделал) ссылка для ответа на похожую проблему

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...