Click here to Skip to main content
Licence 
First Posted 29 Sep 2005
Views 66,740
Bookmarked 31 times

Service Controller

By | 29 Sep 2005 | Article
How to programmatically control an NT Service.

User Interface

Introduction

Controlling services from code has never been so easy. The .NET framework has taken the cumbersome task of wrapping the Windows API calls that we traditionally used to control services.

Using the code

First, let's get a list of services running on the machine. To do this, we will call the static method GetServices() of the System.ServiceProcess.ServiceController class.

//create an array to hold the list of services
System.ServiceProcess.ServiceController[] services;
//fill the array with the GetServices method
services = System.ServiceProcess.ServiceController.GetServices();

In my application, I load a ComboBox with the list of services running on the machine. To make life easy, I create a DataTable on the fly and add records to it to represent the individual services. Then I bind the DataTable that I created to the ComboBox. I also take some additional steps to sort the data in the DataTable and to add an initial ComboBox entry that prompts the user to "Select A Service".

//Add columns to the DataTable
_tblServices.Columns.Add( new DataColumn( "ServiceName", typeof( System.String ) ));
_tblServices.Columns.Add( new DataColumn( "DisplayName", typeof( System.String ) ));
_tblServices.Columns.Add( new DataColumn( "Index", 
                              typeof( System.Int32 ) )); //used for sorting

System.ServiceProcess.ServiceController[] services;
services = System.ServiceProcess.ServiceController.GetServices();

foreach( System.ServiceProcess.ServiceController controller in services )
{
   DataRow row = _tblServices.NewRow();
   row["ServiceName"] = controller.ServiceName;
   row["DisplayName"] = controller.DisplayName;
   row["Index"] = 1;

   _tblServices.Rows.Add( row );
}

//add a dummy row
DataRow blankRow = _tblServices.NewRow();
blankRow["ServiceName"] = string.Empty;
blankRow["DisplayName"] = "<Select A Service>";
blankRow["Index"] = 0;
_tblServices.Rows.Add( blankRow );

//use a DataView to sort the entries. I use the "Index" 
//Column to force my blank record to the top
DataView view = new DataView( _tblServices, string.Empty, 
                    "Index, DisplayName", 
                    DataViewRowState.CurrentRows );
cbServices.DataSource = view;
cbServices.ValueMember = "ServiceName";
cbServices.DisplayMember = "DisplayName";

//Assign an event handler to the selectedValueChanged Event
cbServices.SelectedValueChanged += 
           new EventHandler(cbServices_SelectedValueChanged);

In the previous code, the ComboBox was assigned an event handler. The SelectedValueChanged event will allow me to update the GUI according to the status of the selected service. In order to get the status of the service I instantiate a new ServiceController object and pass in the Service Name. Then I enable/disable each button depending on the current service status.

private void cbServices_SelectedValueChanged(object sender, System.EventArgs e)
{
    ServiceController controller = GetService();

    if( controller != null )
        UpdateControls( GetService() );
    else
    {
        statusBar1.Text = string.Empty;
        btnStart.Enabled = false;
        btnStop.Enabled = false;
        btnPause.Enabled = false;
        btnContinue.Enabled = false;
    }
}

//Updates the buttons according to the currently selected service
void UpdateControls( ServiceController controller )
{
    btnPause.Enabled = ( controller.Status == ServiceControllerStatus.Running 
                                 && controller.CanPauseAndContinue == true );
    btnStop.Enabled = ( controller.Status == ServiceControllerStatus.Running 
                                             && controller.CanStop == true );
    btnContinue.Enabled = ( controller.Status == ServiceControllerStatus.Paused 
                                 && controller.CanPauseAndContinue == true );
    btnStart.Enabled = controller.Status == ServiceControllerStatus.Stopped;
    statusBar1.Text = "Status: " + controller.Status.ToString();
}

//Gets the currently selected service
private ServiceController GetService()
{
    if( cbServices.SelectedValue.ToString().Trim() != string.Empty )
        return new ServiceController( (string)cbServices.SelectedValue );
    else
        return null;
}

If you are familiar with services you are probably aware that some services can not be stopped or paused. This can be checked by accessing the CanPauseAndContinue property and the CanStop property of the ServiceController class. Since my UpdateControls() method checks these properties I don't have to check these properties again during the button Click events.

private void btnStop_Click(object sender, System.EventArgs e)
{
    System.ServiceProcess.ServiceController controller = GetService();
    controller.Stop();
    WaitForStatus( controller, ServiceControllerStatus.Stopped, 
                                        new TimeSpan( 0,1,0) );
    UpdateControls( controller );
}

private void btnStart_Click(object sender, System.EventArgs e)
{
    System.ServiceProcess.ServiceController controller = GetService();
    controller.Start();
    WaitForStatus( controller, ServiceControllerStatus.Running, 
                                        new TimeSpan( 0,1,0) );
    UpdateControls( controller );
}

private void btnPause_Click(object sender, System.EventArgs e)
{
    System.ServiceProcess.ServiceController controller = GetService();
    controller.Pause();
    WaitForStatus( controller, ServiceControllerStatus.Paused, 
                                       new TimeSpan( 0,1,0) );
    UpdateControls( controller );
}

private void btnContinue_Click(object sender, System.EventArgs e)
{
    System.ServiceProcess.ServiceController controller = GetService();
    controller.Continue();
    WaitForStatus( controller, ServiceControllerStatus.Running, 
                                        new TimeSpan( 0,1,0) );
    UpdateControls( controller );
}

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

About the Author

Michael Ceranski

Software Developer (Senior)
Concepts2Code
United States United States

Member

Michael is the co-founder and master consultant for Concepts2Code, a software consulting company based in Buffalo, New York. He's been programming since the early 1990's. His vast programming experience includes VB, Delphi, C#, ASP, ASP.NET, Ruby on Rails, Coldfusion and PHP. Michael also is a Microsoft Certified Application Developer and a Certified Technology Specialist for SQL Server.
 
Visit his blog.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralGetting error PinmemberArpit1172:47 20 Jul '09  
GeneralRe: Getting error PinmemberMichael Ceranski2:53 20 Jul '09  
GeneralRe: Getting error PinmemberArpit1173:17 20 Jul '09  
GeneralGives Error in Windows Vista PinmemberHimal Rupera21:09 21 Jul '08  
QuestionRe: Gives Error in Windows Vista PinmemberMichael Ceranski1:50 22 Jul '08  
AnswerRe: Gives Error in Windows Vista PinmemberTheAsgard23:37 27 Jul '08  
QuestionCannot find the specific windows service Pinmemberbmwgamil10:35 25 Oct '07  
GeneralControlling Services on Remote Server PinmemberRed Scorpion5:12 1 Jun '07  
QuestionAdmission Control For WLAN (DHCP, Service Controller) ? Pinmemberjsyan11:30 8 Apr '07  
I have a notepad,which having a data store into it and then overwrite by a new data every 1 second constantly.
I want to read the data (which is the total bandwidth usage of my whole WLAN)which changing every 1 second.
D'Oh! | :doh:
From here,I want to use the data to do an admission control of the LAN.
This is basically how is the idea:
1) Read the BW data.
2) Set a Bandwidth limit as reference level (eg: 1000000 Mbps)
3) Compare the BW data I read to the BW limit, if exceed the limit,I want to Pause my window DHCP service,So that client go into my LAN.
4) If the BW going below the BW limit, the DHCP service have to automatically Continue again.
 
Anyone can help me on that? What programming language is more suitable to use? In this case,I using Window XP as my platform. As I do some research, I realize there is a API call "service controller" can be use n this case. I am not sure on it and I don't how to deal with the API.
 

Thousands of appreciate enclosed here for those who willing to help me!!
AnswerRe: Admission Control For WLAN (DHCP, Service Controller) ? Pinmemberalhambra-eidos3:43 26 Apr '10  
AnswerRe: Admission Control For WLAN (DHCP, Service Controller) ? Pinmemberwaqqas_jabbar22:50 3 Jan '11  
QuestionService disabled Pinmembervinay28may17:39 24 Jan '07  
AnswerRe: Service disabled PinmemberChadwick Posey9:57 8 May '07  

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

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

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120529.1 | Last Updated 29 Sep 2005
Article Copyright 2005 by Michael Ceranski
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid