Saturday, August 23, 2014

Make your own Windows Service in Visual Studio 2013 in nine easy steps.

One. Make a new project in Visual Studio 2013. Under the Windows templates within the Visual C# templates there is now a "Windows Service" template. You will want to use this. I name my application JaeschkeService in this example. In Visual Studio 2010 implementations I get the impression that one just made a console application and then made the one class inherit from ServiceBase, bringing in a reference to System.ServiceProcess. Don't do this. I tried to set something up in this manner and whenever I went to start the service I'd get an opaque error message which read:

Error 1053: The service did not respond to the start or control request in a timely fashion.

Two. Make code changes. There are really only two files of interest in the new application. One is the typical Program.cs that exists in any console application. It basically looks like this:

using System.ServiceProcess;
namespace JaeschkeService
{
   static class Program
   {
      static void Main()
      {
         ServiceBase[] ServicesToRun;
         ServicesToRun = new ServiceBase[]
         {
            new Service1()
         };
         ServiceBase.Run(ServicesToRun);
      }
   }
}

 
 

The other is our service. It is called Service1.cs and it basically looks like this:

using System.ServiceProcess;
namespace JaeschkeService
{
   public partial class Service1 : ServiceBase
   {
      public Service1()
      {
         InitializeComponent();
      }
      
      protected override void OnStart(string[] args)
      {
      }
      
      protected override void OnStop()
      {
      }
   }
}

 
 

You may have noticed that Service1.cs does a lot of nothing. Let's fix that. Using suggestions here, I have doctored up Service1.cs to once per minute write the current time to a text file at C:\Whatever\stuff.txt like so:

using System;
using System.IO;
using System.ServiceProcess;
using System.Text;
using System.Timers;
namespace JaeschkeService
{
   public partial class Service1 : ServiceBase
   {
      public Service1()
      {
         InitializeComponent();
      }
      
      protected override void OnStart(string[] args)
      {
         Timer timer = new Timer();
         timer.Interval = 60000;
         timer.Elapsed += OnTimer;
         timer.Start();
      }
      
      protected override void OnStop()
      {
      }
      
      public void OnTimer(object sender, ElapsedEventArgs args)
      {
         string file = @"C:\Whatever\stuff.txt";
         using (Stream stream = new FileStream(file, FileMode.Append))
         {
            byte[] bytes = ASCIIEncoding.ASCII.GetBytes(DateTime.Now + " ... ");
            stream.Write(bytes, 0, bytes.Length);
         }
      }
   }
}

Three. You will need to switch to viewing Service1.cs in the designer mode to make the next few changes, so let's make the switch now. To be honest, you will most likely have started out seeing Service1.cs in designer mode and would have had to manually switch to the code view in the previous step to make the code changes. I guess I should have said something before now. Anyways, you may switch views by right-clicking upon Service1.cs in the Solution Explorer and then picking either "View Designer" or "View Code" from the menu which appears.

Four. If you just click in the designer pane for Service1.cs you will see properties for the service in the "Properties" pane. The default name is just "Service1" and I think we should change this. I change it, the "ServiceName" setting, to "MyService" in this example.

Five. We need an installer. Right-click in the designer pane for Service1.cs and pick "Add Installer" to make this happen.

Six. You will now see a new file for the installer in the Solution Explorer. Build the application at this point. Once you build the application you will be done working in Visual Studio 2013. We are well over halfway through the steps at this point. w00t!

Seven. Next let's install the service by opening the "Developer Command Prompt for VS2103" as administrator, navigating to the Debug folder inside of the bin folder within the project we made, and then running this command:

installutil.exe JaeschkeService.exe

 
 

By the way, if you ever want to uninstall a service, you also navigate to the same place and then run a command like this:

installutil.exe /u JaeschkeService.exe

Eight. You will need to enter credentials for an account to run the service in the "Set Service Login" dialog box which appears. The account you use should be an account that has permissions to do the things you need done. For example, I used an account that had permissions to access and edit C:\Whatever\stuff.txt of course.

Nine. Open the "Services (Local)" list. In Windows 8, I found it by typing "services.msc" at the "Search" at the charm bar. Right-click on the service you just made and pick "Start" to get it running. Double-clicking on the service will expose even more options and at the "General" tab one may set the "Startup type:" to "Automatic" to make the service start automatically when the PC itself starts up. My service was found under the list with the name "MyService" where I started it and let it run a bit. I checked C:\Whatever\stuff.txt and as expected I could see the precious minutes left in the last day I have before I turn forty just ticking away like so:

8/23/2014 10:14:05 PM ... 8/23/2014 10:15:05 PM ... 8/23/2014 10:16:05 PM ...

No comments:

Post a Comment