Click here to Skip to main content
Click here to Skip to main content

Start/Stop Windows Services from XML Lists

, 27 Jun 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
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

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

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 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 version="1.0" encoding="utf-8"?>
<Services Type="Amazon Unbox">
  >

License

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

Share

About the Author

Mark Oliver
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 PinprofessionalVolynsky Alex28-Jun-14 10:26 
QuestionIsn't this very much like this PinprofessionalKees van Spelde28-Jun-14 5:06 
AnswerRe: Isn't this very much like this PinmemberMark Oliver28-Jun-14 5:52 
Questionapp code? Pinmembergregch28-Jun-14 3:58 
AnswerRe: app code? PinmemberMark Oliver28-Jun-14 5:02 
GeneralMy vote of 3 PinmemberRenato Moura27-Jun-14 17:55 

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.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150327.1 | Last Updated 27 Jun 2014
Article Copyright 2014 by Mark Oliver
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid