Click here to Skip to main content
15,886,519 members
Articles / Programming Languages / C#
Tip/Trick

Start/Stop Windows Services from XML Lists

Rate me:
Please Sign up or sign in to vote.
4.83/5 (8 votes)
27 Jun 2014CPOL 14.5K   11   6
Stop unneeded Windows services to free memory

Introduction

My laptop has only 8GB of memory. When SQL Server 2012 Services are running, it isn't possible for me to run either a 4.5GB DataRam Ramdrive (hosting Accuzip USPS postal data) or a 4GB Oracle VM Virtual Box (hosting Windows 8.1x64 and VS "2014" CTP). Instead of manually running SQL Server Configuration Manager and trying to remember what services to start or stop, I wrote a WPF MVVM app to start or stop services based on an XML list.

Background

C#
using System.ServiceProcess.ServiceController

Using the Code

If all the services in the list are stopped, the "Stop" button is disabled.

If all the services in the list are running, the "Start" button is disabled.

To configure for running, change the app.config "xmlPath" user setting to the XML list files path and edit in your SQL Server Name - mine is "MCO" - in StartStopSqlServer.xml.

The XML list file is read into a List<service>.

C#
class service
{
    internal string name;
    internal TimeSpan startTimeout, stopTimeout;
    internal bool stopOnly;
    internal static int DefaultStopMs, DefaultStartMs;
    internal service(string name, int stopMs, int startMs, bool stopOnly)
    {
        this.name = name;
        stopMs = (stopMs > 0) ? stopMs : DefaultStopMs;
        startMs = (startMs > 0) ? startMs : DefaultStartMs;
        stopTimeout = new TimeSpan(0, 0, 0, 0, stopMs);
        startTimeout = new TimeSpan(0, 0, 0, 0, startMs);
        this.stopOnly = stopOnly;
    }    
}
List<service> ssServices = null;

    App.Messenger.Register<string>("InitializeViewModel", (xmlFn) =>
        {
            Status = "Loading";
            using (XmlTextReader xmlReader = new XmlTextReader(xmlFn))
            {
                XDocument xdoc = XDocument.Load(xmlReader);
                service.DefaultStopMs = Convert.ToInt32(xdoc.Root.Attribute
                ("DefaultStopMs") !=null ? xdoc.Root.Attribute
                ("DefaultStopMs").Value : "100" );
                service.DefaultStartMs = Convert.ToInt32(xdoc.Root.Attribute
                ("DefaultStartMs") != null ? xdoc.Root.Attribute
                ("DefaultStartMs").Value : "100");
                var services = from serviceItem in xdoc.Root.Elements()
                               select new service(
                                   serviceItem.Value,
                                   Convert.ToInt32(serviceItem.Attribute("StopMs") != null ? 
                                   serviceItem.Attribute("StopMs").Value : "-1"),
                                   Convert.ToInt32(serviceItem.Attribute("StartMs") != null ? 
                                   serviceItem.Attribute("StartMs").Value : "-1"),
                                   Convert.ToBoolean(serviceItem.Attribute("StopOnly") != null ? 
                                   serviceItem.Attribute("StopOnly").Value : "false")
                                   );
                ssServices = services.ToList();
                L = ssServices.Count;
                WindowHeight = 150;
                Status = "Loaded";
            }
        });
    System.Windows.Input.CommandManager.InvalidateRequerySuggested();
}

// The services are start/stopped in the background worker

    backgroundWorker.DoWork += (s, e) =>
        {
            BackgroundWorker bw = (s as BackgroundWorker);
            stop = (e.Argument as bool?).HasValue ? (e.Argument as bool?).Value : true;
            foreach (service se in ssServices)
            {
                if (!stop && se.stopOnly)
                {
                    sleep(displaySleepMS);
                    continue;
                }
            string exceptionMessage = null;
            bool acted = false;
            ServiceController sc = new ServiceController(se.name);
            ServiceControllerStatus scs = ServiceControllerStatus.Stopped;
            try
            {
                scs = sc.Status;
            }
            catch(Exception ex)
            {
                Trace.WriteLine(ex.Message);
            }
            if (scs == (stop ? ServiceControllerStatus.Running : ServiceControllerStatus.Stopped))
            {
                App.Messenger.NotifyColleagues("setStatus", 
                (stop ? "Stopping " : "Starting ") + se.name);
                for (int retry = 0; retry < maxRetries; retry++)
                {
                    try
                    {
                        if (retry > 0)
                            sc = new ServiceController(se.name);
                        if (sc.Status == (stop ? ServiceControllerStatus.Running : ServiceControllerStatus.Stopped))
                            if (stop)
                                sc.Stop();
                            else
                                sc.Start();
                        sc.WaitForStatus(
                            stop ? ServiceControllerStatus.Stopped : ServiceControllerStatus.Running,
                            se.startTimeout);
                        acted = true;
                        actedCount++;
                        break;
                    }
                    catch (Exception ex)
                    {
                        if (retry == maxRetries - 1)
                            exceptionMessage = ex.Message;
                        else
                            sleep(1000);
                    }
                }
            }
            if (exceptionMessage != null)
                App.Messenger.NotifyColleagues("setStatus", 
                se.name + (stop ? " Stop" : " Start")
                    + " Failed: " + exceptionMessage);
            else
                if (acted)
                    App.Messenger.NotifyColleagues("setStatus", 
                    se.name + (stop ? " Stopped" : " Started"));
                else
                    App.Messenger.NotifyColleagues("setStatus", 
                    se.name + " Already" + (stop ? " Stopped" : " Started"));
                    
            sleep(displaySleepMS);
            if (bw.CancellationPending)
            {
                e.Cancel = true;
                break;
            }
        }
        bw.ReportProgress(L);
        sleep(displaySleepMS);
        if (e.Cancel)
            e.Result = "Cancelled";
        else
            e.Result = (stop ? "Stopped " : "Started ") + 
            actedCount.ToString() + " Services"; 
        };

Points of Interest

SQL Server services XML is as follows:

XML
<?xml version="1.0"?>
<Services DefaultStopMs="3000" DefaultStartMs="10000" Type="Sql Server Type">
  <Service StopMs="4000" StartMs="12000">MSSQL$MCO</Service>
  <!--
    Not using
  <Service>MSSQL$SQLEX</Service>
  <Service>MSSQL$SQLEXPRESS</Service>
  -->
  <Service>MSOLAP$MCO</Service>
  <Service>SQLBrowser</Service>
  <Service>MsDtsServer110</Service>
  <Service>SQLWriter</Service>
  <Service>ReportServer$MCO</Service>
  <!-- MSSQLFDLauncher is autostarted by MSSQLSERVER
       when stopping MSSQLSERVER must be stopped before 
       MSSQLFDLauncher, when starting skip MSSQLFDLauncher
  -->
  <Service StopOnly="true">MSSQLFDLauncher$MCO</Service>
  <!--
    Not using
  <Service>SQLAGENT$MCO</Service>
  -->
</Services>

I also included "StartStopAmazonServices.xml" to stop Amazon services.

XML
<?xml version="1.0" encoding="utf-8"?>
<Services Type="Amazon Unbox">
  >
  <!-- 
    When stopping this service, there could be timeout error, 
    then on my PC there is always a "Cannot stop ADVService service on computer '.'." error,
    then the service stops.   Retries have been coded to handle this behavior.
  -->
  <Service StopMs="400000" StartMs="12000">ADVService</Service>
  <Service>Amazon Download Agent</Service>
</Services>

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) JDDA
United States United States
Programming in C# and a little C++ for 12 years; C++ and Data General Assembly language for about 16 years before that. Currently WPF MVVM with Dependency Injection and Unity application programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Volynsky Alex28-Jun-14 9:26
professionalVolynsky Alex28-Jun-14 9:26 
QuestionIsn't this very much like this Pin
Kees van Spelde28-Jun-14 4:06
professionalKees van Spelde28-Jun-14 4:06 
AnswerRe: Isn't this very much like this Pin
Mark Oliver28-Jun-14 4:52
Mark Oliver28-Jun-14 4:52 
Questionapp code? Pin
astodola28-Jun-14 2:58
astodola28-Jun-14 2:58 
AnswerRe: app code? Pin
Mark Oliver28-Jun-14 4:02
Mark Oliver28-Jun-14 4:02 
GeneralMy vote of 3 Pin
Renato Moura27-Jun-14 16:55
professionalRenato Moura27-Jun-14 16:55 

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.