vb.net 获取 Windows 服务启动类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29620205/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 19:00:54  来源:igfitidea点击:

Get Windows service start type?

.netvb.netwindows-servicesservicecontroller

提问by ElektroStudios

In the System.ServiceProcessnamespace, is there any kind of enumeration or other direct member to determine a Service's Start Type (Auto, Delayed Auto, On Demand, Disabled) of a ServiceController?

System.ServiceProcess命名空间中,是否有任何类型的枚举或其他直接成员来确定服务的启动类型(自动、延迟自动、按需、禁用)ServiceController

The idea is to use an available member of that namespace (or other namespace) of the .NET framework class library to determine that thing, instead of looking into the OS registry or WMI for the service's start type, because I could do that, I'm only asking if the .NET framework exposes an easier way to determine that thing.

这个想法是使用 .NET 框架类库的该命名空间(或其他命名空间)的一个可用成员来确定那个东西,而不是查看 OS 注册表或 WMI 以获取服务的启动类型,因为我可以做到这一点,我我只是在问 .NET 框架是否公开了一种更简单的方法来确定那件事。

Pseudo-Code written in VB.Net but I could manage a C# approach too:

用 VB.Net 编写的伪代码,但我也可以管理 C# 方法:

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

采纳答案by ElektroStudios

Since I'm not totally sure of the answer to my main question (a member inside .net framework class library capable to get this info) i've developed this registry approach which at least is much more fast that messing with WMI and also can determine if a service is autostart delayed.

由于我不完全确定我的主要问题的答案(.net 框架类库中的成员能够获取此信息),因此我开发了这种注册表方法,它至少比与 WMI 混淆的速度要快得多,并且还可以确定服务是否自动启动延迟。

Firstlly a custom enum to extend the actual ServiceStartModeenum:

首先自定义枚举来扩展实际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

Secondly, this function:

其次,这个功能:

''' <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

回答by Rubanov

If possible, set your project target .NET framework to 4.6.1 or higher. The class ServiceControllernow has a property StartType

如果可能,将项目目标 .NET 框架设置为 4.6.1 或更高版本。该类ServiceController现在有一个属性StartType

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

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

回答by Tim

You could use WMI and ManagementObjectto achieve this, based on C# – Get Startup Type of a Service (Windows).

您可以使用 WMI 和ManagementObject来实现这一点,基于C# – Get Startup Type of a Service (Windows)

Something like this (based on code in linked article). The original example is in C#, so I've attempted a quick translation to VB.NET on the fly, but the syntax may be a bit wrong. I also modified the method return type to Stringsince as I wasn't sure what you wanted to do with the value once you got it.

像这样的东西(基于链接文章中的代码)。最初的例子是用 C# 编写的,所以我尝试快速转换为 VB.NET,但语法可能有点错误。我还修改了方法返回类型,String因为我不确定一旦你得到它你想用它做什么。

Don't forget to add Imports System.Management.

不要忘记添加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

回答by Everton Tomazi

Use
Dim SingleSvc As Object

使用
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

Run in Framework 4 Tanks

在 Framework 4 Tanks 中运行