2015-04-14 9 views
6

Im Namespace System.ServiceProcess gibt es irgendeine Art von Enumeration oder ein anderes direktes Mitglied, um den Starttyp eines Dienstes (Auto, Verzögerte Auto, On Demand, Deaktiviert) eines ServiceController zu bestimmen?Windows-Starttyp erhalten?

Die Idee ist, ein verfügbares Mitglied dieses Namespace (oder anderen Namespace) der .NET-Framework-Klassenbibliothek zu verwenden, um dieses Ding zu bestimmen, anstatt in der Betriebssystemregistrierung oder WMI nach dem Starttyp des Dienstes zu suchen, weil ich könnte Tun Sie das, ich frage nur, ob das .NET-Framework eine einfachere Möglichkeit bietet, dieses Ding zu bestimmen.

Pseudo-Code in VB.Net geschrieben, aber ich konnte ein C# Ansatz verwalten zu:

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 
+0

[Ja] (https://msdn.microsoft.com/en-us/library /system.serviceprocess.servicestartmode%28v=vs.110%29.aspx). –

+0

@TheBlueDog Obwohl es tatsächlich diese Aufzählung gibt, können Sie sie nicht zum Bestimmen des StartTyps eines Dienstes verwenden. Es wird nur zum Installieren von Diensten verwendet. – sloth

+0

@sloth glaubst du, ich könnte einen Trick machen, um einen 'Servicecontroller' in' ServiceInstaller' zu verwandeln, nur um '' ServiceStartMode' 'abzurufen? vielleicht habe ich eine blöde Sache gesagt aber es sollte eine Umgehungslösung existieren, um den Startmodus für einen vorhandenen Dienst unter diesem Namespace abzurufen! @Der Blaue Hund danke für die Info! – ElektroStudios

Antwort

3

Da ich nicht ganz sicher, der Antwort auf meine Hauptfrage bin (ein Mitglied innerhalb .NET Framework-Klassenbibliothek der Lage, diese Informationen zu erhalten) i diesen Registrierungs Ansatz entwickelt haben zumindest die viel schneller Dieses Chaos mit WMI und kann auch feststellen, ob ein Dienst automatisch verzögert wird.

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

Zweitens diese Funktion:

Firstlly eine benutzerdefinierte Enum der tatsächlichen ServiceStartMode Enum zu verlängern

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

Sie könnten WMI verwenden und ManagementObject dies zu erreichen, basierend auf C# – Get Startup Type of a Service (Windows).

So etwas (basierend auf Code in verlinkten Artikel). Das ursprüngliche Beispiel ist in C#, also habe ich eine schnelle Übersetzung in VB.NET versucht, aber die Syntax könnte ein bisschen falsch sein. Ich änderte auch den Methodenrückgabetyp zu String, da ich nicht sicher war, was Sie mit dem Wert tun wollten, sobald Sie es erhielten.

Vergessen Sie nicht, Imports System.Management hinzuzufügen.

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 
+0

Danke, aber deine Lösung beantwortet meine Frage nicht. Ich suche nicht nach anderen Ansätzen (ich kenne sie) Access und Unordnung mit WMI-Abfragen ist eines der Dinge, die ich im Falle von .NET Framework Klassenbibliothek vermeiden möchte, stellt einen direkten Weg, um diese Informationen abrufen. danke sowieso – ElektroStudios

+0

Ah, ok. Entschuldigung, es entsprach nicht dem, wonach du gesucht hast. Viel Glück bei deiner Suche :) – Tim

+0

Jemand hat auf meine Hauptfrage in den Kommentaren geantwortet und dann scheint dein Ansatz der einzige zu sein (ich meine zusammen mit Windows-Registry-Suche). Danke noch einmal. – ElektroStudios

3

Wenn möglich, stellen Sie Ihr Projektziel .NET Framework 4.6.1 Die Klasse ServiceController hat jetzt eine Eigenschaft StartType

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

+0

Danke, aber 'StartType' -Eigenschaft gibt nur einen 'ServiceStartMode'-Wert, das ist eine" unvollständige "Aufzählung von möglichen Startmodi, die ich würde erweitert in meiner akzeptierten Antwort .. – ElektroStudios

+0

@ElektroStudios In meinem Fall alles, was ich brauchte, waren die Werte in 'ServiceStartMode' https://msdn.microsoft.com/en-us/library/system.serviceprocess.servicestartmode(v=vs.110)) .aspx – Rubanov

0

Verwenden
Dim SingleSvc As Object

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