Получить тип запуска службы Windows?

Есть ли в пространстве имен System.ServiceProcess какое-либо перечисление или другой прямой член для определения типа запуска службы (автоматический, отложенный автоматический, по запросу, отключенный) ServiceController?

Идея состоит в том, чтобы использовать доступный член этого пространства имен (или другого пространства имен) библиотеки классов .NET Framework, чтобы определить это, вместо того, чтобы искать в реестре ОС или WMI тип запуска службы, потому что я мог бы сделать это, я Я только спрашиваю, предоставляет ли .NET framework более простой способ определить это.

Псевдокод, написанный на VB.Net, но я мог бы справиться и с подходом С#:

Public Shared Function GetStartType(ByVal svcName As String) As ServiceControllerStatus

    Dim svc As ServiceController = (From service As ServiceController In ServiceController.GetServices()
         Where service.ServiceName.Equals(svcName, StringComparison.OrdinalIgnoreCase)
        ).FirstOrDefault

    If svc Is Nothing Then
        Throw New ArgumentException("Any service found with the specified name.", "svcName")
    Else
        Using svc
            ' Note that StartTypeEnumValue does not exists.
            Return svc.StartTypeEnumValue
        End Using
    End If

End Function

person ElektroStudios    schedule 14.04.2015    source источник
comment
Да.   -  person The Blue Dog    schedule 14.04.2015
comment
@TheBlueDog Хотя это перечисление действительно существует, вы не можете использовать его для определения StartType службы. Он используется только для установки сервисов.   -  person sloth    schedule 14.04.2015
comment
@sloth как ты думаешь, я мог бы сделать какой-нибудь трюк, чтобы перевести Servicecontroller в ServiceInstaller только для того, чтобы получить ServiceStartMode? возможно, я сказал глупость, но должен существовать обходной путь для получения режима запуска для существующей службы в этом пространстве имен!. @The Blue Dog спасибо за информацию!   -  person ElektroStudios    schedule 14.04.2015
comment
@sloth: Тогда это довольно бессмысленно ...   -  person The Blue Dog    schedule 14.04.2015
comment
@ElektroStudios Нет. Эти два класса не связаны. Вы должны использовать ManagementObjectSearcher или реестр, чтобы получить тип запуска службы.   -  person sloth    schedule 14.04.2015


Ответы (4)


Если возможно, установите целевую платформу .NET для проекта на 4.6.1 или выше. Класс ServiceController теперь имеет свойство StartType

https://msdn.microsoft.com/en-us/library/system.serviceprocess.servicecontroller(v=vs.110).aspx

person Rubanov    schedule 19.04.2016
comment
Спасибо, но свойство StartType просто возвращает значение ServiceStartMode, то есть неполное перечисление возможных режимов запуска, которые я расширил в своем принятом ответе. - person ElektroStudios; 19.04.2016
comment
@ElektroStudios В моем случае все, что мне было нужно, это значения в ServiceStartMode msdn.microsoft.com/en-us/library/ - person Rubanov; 19.04.2016

Вы можете использовать WMI и ManagementObject для достижения этой цели на основе C# — Получить тип запуска службы (Windows).

Что-то вроде этого (на основе кода в связанной статье). Исходный пример написан на C#, поэтому я попытался быстро перевести его на VB.NET на лету, но синтаксис может быть немного неправильным. Я также изменил тип возвращаемого значения метода на String, так как не был уверен, что вы хотите делать со значением после его получения.

Не забудьте добавить Imports System.Management.

Public Shared Function GetStartType(ByVal svcName As String) As String

    Dim startMode As String = String.Empty
    Dim filter As String = String.Format("SELECT StartMode FROM Win32_Service WHERE Name = '{0}'", svcName)
    Dim svc As ManagementObjectSearcher = New ManagementObjectSearcher(filter)

    If svc Is Nothing Then
        Throw New ArgumentException("Any service found with the specified name.", paramName:="svcName")
    Else
        Try
            Dim services As ManagementObjectCollection = svc.Get()

            For Each service As ManagementObject In services
                startMode = service.GetPropertyValue("StartMode").ToString()
            Next
        Catch ex As Exception
            ' Do something if needed
        End Try
    End If

    Return StartMode
End Function
person Tim    schedule 14.04.2015
comment
Спасибо, но ваше решение не отвечает на мой вопрос. Я не ищу других подходов (я их знаю), доступ и возня с запросами WMI - это одна из вещей, которых я хотел бы избежать в случае, если библиотека классов .Net framework предоставляет прямой способ получения этой информации. в любом случае спасибо - person ElektroStudios; 14.04.2015
comment
Ах хорошо. Извините, это не соответствует тому, что вы искали. Удачи в поисках :) - person Tim; 14.04.2015
comment
Кто-то ответил на мой главный вопрос в комментариях, и тогда ваш подход кажется единственным (имею в виду вместе с поиском по реестру Windows). еще раз спасибо. - person ElektroStudios; 14.04.2015
comment
Что ж, поскольку это решение не дает способа определить отложенный автозапуск, я снимаю его, свойство DelayedAutoStart Win32_Service кажется недоступным для выбора из запроса (недоступным). Я не знаю, почему. Я знаю, как это сделать из реестра, но это уродливо и навязчиво (например, запросы WMI). - person ElektroStudios; 14.04.2015

Поскольку я не совсем уверен в ответе на свой главный вопрос (член внутри библиотеки классов .net framework, способный получить эту информацию), я разработал этот подход к реестру, который, по крайней мере, намного быстрее, чем возиться с WMI, а также может определить, задерживается ли автозапуск службы.

Во-первых, пользовательское перечисление для расширения фактического перечисления ServiceStartMode:

''' <summary>
''' Indicates the start mode of a service.
''' </summary>
Public Enum SvcStartMode As Integer

    ''' <summary>
    ''' Indicates that the service has not a start mode defined.
    ''' Since a service should have a start mode defined, this means an error occured retrieving the start mode.
    ''' </summary>
    Undefinied = 0

    ''' <summary>
    ''' Indicates that the service is to be started (or was started) by the operating system, at system start-up.
    ''' The service is started after other auto-start services are started plus a short delay.
    ''' </summary>
    AutomaticDelayed = 1

    ''' <summary>
    ''' Indicates that the service is to be started (or was started) by the operating system, at system start-up. 
    ''' If an automatically started service depends on a manually started service, 
    ''' the manually started service is also started automatically at system startup.
    ''' </summary>
    Automatic = 2 'ServiceStartMode.Automatic

    ''' <summary>
    ''' Indicates that the service is started only manually, 
    ''' by a user (using the Service Control Manager) or by an application.
    ''' </summary>
    Manual = 3 'ServiceStartMode.Manual

    ''' <summary>
    ''' Indicates that the service is disabled, so that it cannot be started by a user or application.
    ''' </summary>
    Disabled = 4 ' ServiceStartMode.Disabled

End Enum

Во-вторых, эта функция:

''' <summary>
''' Gets the start mode of a service.
''' </summary>
''' <param name="svcName">The service name.</param>
''' <returns>The service's start mode.</returns>
''' <exception cref="ArgumentException">
''' Any service found with the specified name.
''' </exception>
''' <exception cref="Exception">
''' Registry value "Start" not found for service.
''' </exception>
''' <exception cref="Exception">
''' Registry value "DelayedAutoStart" not found for service.
''' </exception>
Public Shared Function GetStartMode(ByVal svcName As String) As SvcStartMode

    Dim reg As RegistryKey = Nothing
    Dim startModeValue As Integer = 0
    Dim delayedAutoStartValue As Integer = 0

    Try
        reg = Registry.LocalMachine.
              OpenSubKey("SYSTEM\CurrentControlSet\Services\" & svcName,
              writable:=False)

        If reg Is Nothing Then
            Throw New ArgumentException("Any service found with the specified name.", 
                                        paramName:="svcName")

        Else
            startModeValue = Convert.ToInt32(reg.GetValue("Start",
                             defaultValue:=-1))

            delayedAutoStartValue = Convert.ToInt32(reg.GetValue("DelayedAutoStart", 
                                    defaultValue:=0))

            If startModeValue = -1 Then
                Throw New Exception(String.Format(
                          "Registry value ""Start"" not found for service '{0}'.", 
                          svcName))

                Return SvcStartMode.Undefinied

            Else
                Return DirectCast(
                       [Enum].Parse(GetType(SvcStartMode),
                                   (startModeValue - delayedAutoStartValue).ToString), 
                                    SvcStartMode)

            End If

        End If

    Catch ex As Exception
        Throw

    Finally
        If reg IsNot Nothing Then
            reg.Dispose()
        End If

    End Try

End Function
person ElektroStudios    schedule 14.04.2015

Использовать
Dim SingleSvc как объект

Dim listaSvcs() As ServiceProcess.ServiceController
Dim SingleSvc As Object
iniservice:
listaSvcs = ServiceProcess.ServiceController.GetServices
Try
    For Each SingleSvc In listaSvcs
        If SingleSvc.ServiceName.IndexOf("postgresql") >= 0 And SingleSvc.StartType.ToString <> "Disabled" Then
            If SingleSvc.Status <> ServiceProcess.ServiceControllerStatus.Running Then
                'MessageBox.Show(SingleSvc.StartType.ToString)
                SingleSvc.Start()
                GoTo iniservice
                End If
            End If
        Next
Catch ex As Exception
    MessageBox.Show(ex.Message)
End Try

Запуск в танках Framework 4

person Everton Tomazi    schedule 26.09.2016