Click here to Skip to main content
15,887,585 members
Articles / Programming Languages / C#
Article

.NET Diagnostics - III, Enumerate System Services and Dependencies Using C#

Rate me:
Please Sign up or sign in to vote.
1.60/5 (4 votes)
18 Mar 2001 105.7K   773   19   12
How to get the list of all system services on a system and also finds out their dependencies.

Sample Image - NetDiagnostics3.jpg

Introduction

Continuing in the series of writing some diagnostics tools and exploring the System.Diagnostics namespace; this article shows how do you find out what all system services are running on the system and most importantly finding their dependencies. It's the later part that I found very interesting. Every time I open the Services dialog box or Task Manager on my system to look what all services are running, I used to think what will happen if I shut down one of them to recover some resources. But then you have to think, what if this service is part of some other service or application running on the system. This utility application enumerates and displays all the system services running on a system. And it also lists all the services a particular service is dependent upon and the services that depend on this service.

How do you do it?

The .NET framework provides the System.ServiceProcess namespace. This namespace contains classes for installing and running system services. In this namespace, you will find a class named SystemController. A SystemController is nothing but a System Service in NT lingo. This class has a static method GetServices() that returns an array of SystemController objects. This array contains all the services running on a system.

C#
ServiceController [] controllers = 
    ServiceController.GetServices();

After you have obtained this array, enumerate through each element to get details about each service. The SystemController class has a bunch of properties and their names are self-explanatory. I will not go into details of each property. I would suggest you to look in framework documentation for more details.

  • DisplayName - The descriptive name shown for this service in the Service applet.
  • Status - Status of the service e.g., Running, Stopped, etc.
  • ServiceType - Type of service that object references.
  • ServiceName  Short name of the service.
  • CanStop - Indicates if the service can be stopped at any time.
  • CanShutDown - Indicates if the service can be shut down any time.
  • CanPauseAndContinue - If the service can be stopped and continued.
  • DependentServices - List of services that depend on this service.
  • ServicesDependOn - List of services that this service depends on.

The ServiceController class has a couple of methods that can be used to start and stop a service. I have not shown the use of these methods in this utility project. But they are pretty simple to use.

Look at the InitList method in the source code attached with this article. This function shows how to use all the properties of the SystemController class.

C#
// Check the status of this service to see if 
// it can be stopped
bool bCanStop = controllers[i].CanStop;
item.SetSubItem(3, bCanStop ? "Yes" : "No");

// Check if the service recieves notification when 
// system shuts down.
bool bCanShutDown = controllers[i].CanShutdown;
item.SetSubItem(4, bCanShutDown ? "Yes" : "No");

// Check if the service can be paused and continued.
bool bPauseNContinue = controllers[i].CanPauseAndContinue;
item.SetSubItem(5, bPauseNContinue ? "Yes" : "No");

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 1 Pin
dudeua7-Dec-08 22:23
dudeua7-Dec-08 22:23 
QuestionProcess Id ? Pin
Alexis MICHEL16-Oct-07 5:10
Alexis MICHEL16-Oct-07 5:10 
Questionautomatic and manual Pin
jarellan12-Sep-07 23:40
jarellan12-Sep-07 23:40 
AnswerRe: automatic and manual Pin
AaronM_NZ27-Oct-07 15:19
AaronM_NZ27-Oct-07 15:19 
GeneralRe: automatic and manual Pin
gmooney26-Mar-08 5:37
gmooney26-Mar-08 5:37 
AnswerRe: automatic and manual Pin
AaronM_NZ7-Apr-08 0:57
AaronM_NZ7-Apr-08 0:57 
There is a bit involved, you need to open the service manager, then the service, and then perform the changes required. The Microsoft MSDN libray is handy - if you know C++ - http://msdn2.microsoft.com/en-us/library/ms681987.aspx[^]

Here is a bit of code I have put together, to change the basic parameters on the service using the ChangeServiceConfig API. You need to call the ChangeSVCConfig function with the host name, service name (not the display name), executable path, and the start type. You should be able to pick it apart to change just the start type. I was primarily interesting in changing the binary path.

Just note the actual call to the API is looking for Form1 in this example, change this to the name of your class. And youll need a Imports System.Runtime.InteropServices in you class definition.

This code isnt pretty, but it works. Its a cut and paste from a couple of different projects I have been working on, hopefully it does what you need!

Public Declare Function ChangeServiceConfig Lib "advapi32.dll" Alias "ChangeServiceConfigA" (ByVal hService As Integer, ByVal dwServiceType As svType, ByVal dwStartType As svStartType, ByVal dwErrorControl As svErrorControl, ByVal lpBinaryPathName As String, ByVal lpLoadOrderGroup As String, ByVal lpdwTagId As Integer, ByVal lpDependencies As String, ByVal lpServiceStartName As String, ByVal lpPassword As String, ByVal lpDisplayName As String) As Boolean<br />
    Public Declare Function OpenSCManager Lib "advapi32.dll" Alias "OpenSCManagerA" (ByVal lpMachineName As String, ByVal lpDatabaseName As String, ByVal dwDesiredAccess As Integer) As Integer<br />
    Public Declare Function OpenService Lib "advapi32.dll" Alias "OpenServiceA" (ByVal hSCManager As Integer, ByVal lpServiceName As String, ByVal dwDesiredAccess As Integer) As Integer<br />
<br />
    Public Declare Function QueryServiceConfig Lib "advapi32.dll" Alias "QueryServiceConfigA" (ByVal hService As Integer, <MarshalAs(UnmanagedType.Struct)> ByRef lpServiceConfig As QUERY_SERVICE_CONFIG, ByVal cbBufSize As Integer, ByVal pcbBytesNeeded As Integer) As Boolean<br />
    Public Declare Function CloseServiceHandle Lib "advapi32.dll" (ByVal hSCObject As Integer) As Long<br />
<br />
    Public Const SERVICE_NO_CHANGE = &HFFFFFFFF<br />
<br />
    Public Const SC_MANAGER_CONNECT = 1<br />
    Public Const STANDARD_RIGHTS_REQUIRED = &HF0000<br />
    Public Const SC_MANAGER_CREATE_SERVICE = &H2<br />
    Public Const SC_MANAGER_ENUMERATE_SERVICE = &H4<br />
    Public Const SC_MANAGER_LOCK = &H8<br />
    Public Const SC_MANAGER_QUERY_LOCK_STATUS = &H10<br />
    Public Const SC_MANAGER_MODIFY_BOOT_CONFIG = &H20<br />
    Public Const SERVICE_CHANGE_CONFIG = 2<br />
<br />
    Public Const SC_MANAGER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or SC_MANAGER_CONNECT Or SC_MANAGER_CREATE_SERVICE Or SC_MANAGER_ENUMERATE_SERVICE Or SC_MANAGER_LOCK Or SC_MANAGER_QUERY_LOCK_STATUS Or SC_MANAGER_MODIFY_BOOT_CONFIG)<br />
<br />
    <StructLayout(LayoutKind.Sequential)> _<br />
 Public Structure QUERY_SERVICE_CONFIG<br />
        Public dwServiceType As Integer<br />
        Public dwStartType As Integer<br />
        Public dwErrorControl As Integer<br />
        <MarshalAs(UnmanagedType.LPWStr)> Public pBinaryPathName As String<br />
        <MarshalAs(UnmanagedType.LPWStr)> Public pLoadOrderGroup As String<br />
        Public dwTagId As Integer<br />
        <MarshalAs(UnmanagedType.LPWStr)> Public pDependencies As String<br />
        <MarshalAs(UnmanagedType.LPWStr)> Public pServiceStartName As String<br />
        <MarshalAs(UnmanagedType.LPWStr)> Public pDisplayName As String<br />
    End Structure<br />
<br />
    Public Structure SERVICE_STATUS<br />
        Dim dwServiceType As Integer<br />
        Dim dwCurrentState As Integer<br />
        Dim dwControlsAccepted As Integer<br />
        Dim dwWin32ExitCode As Integer<br />
        Dim dwServiceSpecificExitCode As Integer<br />
        Dim dwCheckPoint As Integer<br />
        Dim dwWaitHint As Integer<br />
    End Structure<br />
<br />
    Public Enum svType As Integer<br />
        SERVICE_KERNEL_DRIVER = &H1<br />
        SERVICE_FILE_SYSTEM_DRIVER = &H2<br />
        SERVICE_WIN32_OWN_PROCESS = &H10<br />
        SERVICE_WIN32_SHARE_PROCESS = &H20<br />
        SERVICE_INTERACTIVE_PROCESS = &H100<br />
        SERVICETYPE_NO_CHANGE = SERVICE_NO_CHANGE<br />
    End Enum<br />
    Public Enum svStartType As Integer<br />
        SERVICE_BOOT_START = &H0<br />
        SERVICE_SYSTEM_START = &H1<br />
        SERVICE_AUTO_START = &H2<br />
        SERVICE_DEMAND_START = &H3<br />
        SERVICE_DISABLED = &H4<br />
        SERVICESTARTTYPE_NO_CHANGE = SERVICE_NO_CHANGE<br />
    End Enum<br />
    Public Enum svErrorControl As Integer<br />
        SERVICE_ERROR_IGNORE = &H0<br />
        SERVICE_ERROR_NORMAL = &H1<br />
        SERVICE_ERROR_SEVERE = &H2<br />
        SERVICE_ERROR_CRITICAL = &H3<br />
        SERVICEERRORCONTROL_NO_CHANGE = SERVICE_NO_CHANGE<br />
    End Enum<br />
<br />
    Public Structure QUERY_SERVICE_LOCK_STATUS<br />
        Dim fIsLocked As Long<br />
        Dim lpLockOwner As String<br />
        Dim dwLockDuration As Long<br />
    End Structure<br />
<br />
    ''' <summary>Calls Windows ChangeServiceConfig API to change a service configuration</summary><br />
    ''' <param name="strMachineName">The computer name</param><br />
    ''' <param name="strServiceName">The windows service name</param><br />
    ''' <param name="strBinPath">The path to the service executable</param><br />
    ''' <param name="intStartType">Integer representing the start type<br />
    ''' 0 = No Change  <br />
    ''' 2 = Automatic  <br />
    ''' 3 = Manual     <br />
    ''' 4 = Disabled</param><br />
    ''' <returns>True for update success, false for failure. Call LastDllError for error information</returns><br />
    ''' <remarks></remarks><br />
    Public Function ChangeSVCConfig(ByVal strMachineName As String, ByVal strServiceName As String, ByVal strBinPath As String, ByVal intStartType As Integer) As Boolean<br />
<br />
        Dim hSCM As Integer<br />
        Dim hSVC As Integer<br />
<br />
        hSCM = OpenSCManager(strMachineName, vbNullString, SC_MANAGER_ALL_ACCESS)<br />
        If hSCM = 0 Then Exit Function<br />
<br />
        hSVC = OpenService(hSCM, strServiceName, SERVICE_CHANGE_CONFIG)<br />
        If hSVC = 0 Then Exit Function<br />
<br />
        Dim svType As svStartType<br />
        Select Case intStartType<br />
            Case 2<br />
                svType = svStartType.SERVICE_AUTO_START<br />
            Case 3<br />
                svType = svStartType.SERVICE_DEMAND_START<br />
            Case 4<br />
                svType = svStartType.SERVICE_DISABLED<br />
            Case Else<br />
                svType = svStartType.SERVICESTARTTYPE_NO_CHANGE<br />
        End Select<br />
<br />
        Try<br />
            ChangeSVCConfig = ChangeServiceConfig(hSVC, Form1.svType.SERVICETYPE_NO_CHANGE, svType, svErrorControl.SERVICEERRORCONTROL_NO_CHANGE, strBinPath, vbNullString, vbNullString, vbNullString, vbNullString, vbNullString, vbNullString)<br />
        Finally<br />
            CloseServiceHandle(hSVC)<br />
            CloseServiceHandle(hSCM)<br />
        End Try<br />
<br />
    End Function

Questionwhere's the form ? Pin
Harkamal Singh12-Jul-07 0:56
Harkamal Singh12-Jul-07 0:56 
Questionhow to get image path Pin
Harkamal Singh12-Jul-07 0:52
Harkamal Singh12-Jul-07 0:52 
QuestionHow to implement in VC Pin
Prateeti22-Aug-02 18:54
Prateeti22-Aug-02 18:54 
GeneralStop time Pin
19-Mar-01 15:25
suss19-Mar-01 15:25 
QuestionHow to dynamic make a service interact with the desktop? Pin
19-Mar-01 15:21
suss19-Mar-01 15:21 
AnswerRe: How to dynamic make a service interact with the desktop? Pin
n4nilesh23-Aug-04 8:30
n4nilesh23-Aug-04 8:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.