Category Archives: .Net 2.0

Windows Services in C#: Adding the Installer (part 3)

OK, you’ve crafted your service, now you’re ready to install it so you can test. To do so you’ll need to create an installer for your project. However, you don’t create an installer in the traditional fashion.

Instead, switch to the “TimeLoggerService.cs [Design]” tab. Now in that big gray area right click, and pick “Add Installer”.

[Picture of Add Installer Menu]

Visual Studio will do some magic and you’ll have a new ProjectInstaller.cs added to your project. It also added a few new references to the solution. If the “ProjectInstaller.cs [Design]” tab is not up, bring it up, and click on the serviceInstaller1 item.

Let’s start by giving it a decent name, I chose ArcaneTimeLoggerServiceInstaller. Now for the Description property I entered “The Arcane Code Time Logging Service”. For DisplayName I gave it “Arcane Code Time Logger”. Finally, I’m leaving the StartType property to Manual, you may wish to alter this for your “real world” service.

Now go back and click on the serviceProcessInstaller1. We’ll change it’s name to ArcaneTimeLoggerServiceProcessInstaller. If you remember the discussion from part 1, you will recall a discussion about the security. Here in the Account property is where you will want to set that. Since all this sample does is a minimal amount of logging, I can go with a fairly low level of security and set to “LocalSystem”.

OK, we’re almost done. Right click the project name (in my case TimeLogger) and select properties from the menu. (Note, make sure to click the project, not the solution!) Now on the Application tab, under “Startup object” pick TimeLogger.Program. Now save everything and build your project.

Assuming your build was successful, you can now install and test your windows service. There are two ways to install, we can use the installutil.exe, or create a full blown MSI installer. Since we are just at the point of debugging, we will use the simple installutil.exe.

To preset all the pathing you’ll need for install util, we’ll need to open a Visual Studio Command Window. Start, All Programs, Microsoft Visual Studio 2005, Visual Studio Tools, Visual Studio Command Window. If you are running under Vista, STOP! Do NOT click on Visual Studio Command Window. Instead, right click and pick “Run as Administrator”. Again that’s for Vista, for XP just click since you likely have Admin rights.

The moral is without Admin rights InstallUtil fails every time, and it drove me up the wall trying to figure this out.

Now in the command window navigate to the bin\debug folder where your project compiled. Type in installutil TimeLogger.exe (or whatever you named your exe).

[Picture of Command Prompt]

If everything goes well, you s hould get the messages “The Commit phase completed successfully” and “The transacted install has completed”. Now let’s go see if we were successful.

Open the Microsoft Management Console (Start, Run, MMC)). When it opens, pick the Services and EventViewer snap-ins. Under Services, you should easily find the ArcaneTimeLogger, just double click on it and start it. Once it starts you can close the dialog.

Now head over to the Event Viewer. Click on the “Create Custom View”, to make it easy to find our log events. In the “Create Custom View” dialog, select “By source” and in the drop down check the ones for ArcaneTimeLogging. Click OK to close.

[Picture of Create Custom View]

Your view should now update to look something like this:

[Picture of MMC with our Events]

Congratulations, you’ve now coded and installed a basic windows service, and more over logged events from your service. This sample app we just created can serve as a basic template for all of your future windows services.

By the way, we should probably not get carried away with the euporia. Let’s take a moment and clean up. Return to the services area of the MMC and double click on our ArcaneTimeLogger. Now Stop the service, so it won’t be continually logging the time.

Now that it’s not running, let’s uninstall it. Return to the Visual Studio Command Window and simply type the command “installutil /u TimeLogger.exe”. The /u switch will tell InstallUtil to uninstall our service named TimeLogger.exe. And with that you’ve take care of your clean up work. Tomorrow we’ll talk a bit about debugging a windows service.

Windows Services in C#: Getting Started (part 2)

Yesterday we covered the basics you need to understand in order to write Windows Services. With that out of the way, it’s time to roll up our sleeves and write some code.

To get started, open Visual Studio and select new project. Windows Service won’t appear in the top level list of Visual C# items, instead you’ll need to drill down and in the tree under Visual C# select Windows. Now you should see “Windows Service” appear in the list of templates. Pick it, then go down and key in a name. For this demo I’m going to do something very simple, so let’s call it “TimeLogger” and press OK.

[New Project Dialog]

Now let’s take a moment to see what has been created for us. Over the in the solution explorer, beside the properties and references you’ll see two files, program.cs and service1.cs. Let’s look inside Program.cs, shall we?

    static void Main()

    {

      ServiceBase[] ServicesToRun;

 

      // More than one user Service may run within the same process. To add

      // another service to this process, change the following line to

      // create a second service object. For example,

      //

      //  ServicesToRun = new ServiceBase[] {new Service1(), new MySecondUserService()};

      //

      ServicesToRun = new ServiceBase[] { new Service1() };

 

      ServiceBase.Run(ServicesToRun);

    }

 

This simple code does an incredible amount. First, it creates an array of ServiceBase objects named ServicesToRun. This will hold the list of all the services this project will hold. Next it adds the single service that was automatically generated for you, Service1, to the array, and finally it calls the Run method to launch all of the services.
 
The first thing we’ll want to do is change the name of Service1 to something more meaningful. Click on the file name in Solution Explorer, and change it’s name from Service1 to TimeLoggerService. You’ll then be asked if you want to change all references, say Yes to let VS take care of all the work for you. You should now see that Program.cs has been updated:
 

      ServicesToRun = new ServiceBase[] { new TimeLoggerService() };

If you had other services to run, you’d add them to the array prior to the ServiceBase.Run command. What’s important to note though is the Run command launches the service file in it’s own thread, then keeps on trucking returning control back to windows.

Specifically, it’s the Service Control Manager (SCM) which is launching your app via the Main method in program.cs, then expecting control back. If you didn’t use Run, but instead tried to process a bunch of time consuming commands, the SCM would eventually time out and report your service failed to start. For that reason it’s important to put no extra code in the Main method other than what’s needed to get to the ServiceBase.Run command.

Now let’s take a look at the TimeLoggerService class. Double click on it in the Solution Explorer, and you will see a new editor tab appear with “TimeLoggerService.cs [Design]” in the title. The big gray area doesn’t show you much, so let’s ignore it for right now and look at the Properties window.

The most important property is ServiceName. This is the one you really want to change, as it’s the one that shows up throughout the Windows infrastructure. Windows can only have one version of a service going, so if you don’t change it the next project you start will also have the default name “Service1” and the two will collide like an iceberg with the Titanic. I’m changing the name to ArcaneTimeLogger.

AutoLog is another property to note, when true (the default) messages for the starting, stopping, etc. of your service will be taken care of for you. Since you can never have too much info, I would leave this set to true.

Next are a series of “Can” properties: CanHandlePowerEvent, CanHandleSessionChange, CanPauseandContinue, CanShutdown, and CanStop. If any of these are set to true, you will have to then insert a method to handle the event (or events in the case of Pause and Continue).

OK, that handles all of the important properties we need to examine. Let’s look at some code. Open the TimeLoggerService.cs so you can see the code.

  public partial class TimeLoggerService : ServiceBase

  {

    public TimeLoggerService()

    {

      InitializeComponent();

    }

 

    protected override void OnStart(string[] args)

    {

      // TODO: Add code here to start your service.

    }

 

    protected override void OnStop()

    {

      // TODO: Add code here to perform any tear-down necessary to stop your service.

    }

  }

The first thing you should notice is our class inherits from ServiceBase. The ServiceBase has two methods you must implement, OnStart and OnStop, and you’ll notice Visual Studio has helpfully created them for you. If you want to start your own service class from scratch, be sure to inherit from ServiceBase and implement these two methods.

Now let’s add a little code. We’ll add a timer and log the time every minute. Here’s the complete class:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Diagnostics;

using System.ServiceProcess;

using System.Text;

using System.Timers;

 

namespace TimeLogger

{

  public partial class TimeLoggerService : ServiceBase

  {

    // Note we had to add System.Timers to the using area

    private Timer _timer = null;

 

    public TimeLoggerService()

    {

      InitializeComponent();

      // Set the timer to fire every sixty seconds

      // (remember the timer is in millisecond resolution,

      //  so 1000 = 1 second. )

      _timer = new Timer(60000);

 

      // Now tell the timer when the timer fires

      // (the Elapsed event) call the _timer_Elapsed

      // method in our code

      _timer.Elapsed += new

        System.Timers.ElapsedEventHandler(_timer_Elapsed);

    }

 

    protected override void OnStart(string[] args)

    {

      _timer.Start();

    }

 

    protected override void OnStop()

    {

      _timer.Stop();

    }

 

    protected override void OnContinue()

    {

      base.OnContinue();

      _timer.Start();

    }

 

    protected override void OnPause()

    {

      base.OnPause();

      _timer.Stop();

    }

 

    protected override void OnShutdown()

    {

      base.OnShutdown();

      _timer.Stop();

    }

 

    // This method is called when the timer fires

    // it’s elapsed event. It will write the time

    // to the event log.

    protected void _timer_Elapsed(object sender, ElapsedEventArgs e)

    {

      EventLog evt = new EventLog(“ArcaneTimeLogger”);

      string message = “Arcane Time:”

        + DateTime.Now.ToShortDateString() + ” “

        + DateTime.Now.ToShortTimeString();

      evt.Source = “ArcaneTimeLoggerService”;

      evt.WriteEntry(message, EventLogEntryType.Information);

    }

  }

}

The code is pretty self explanatory; I added OnContinue, OnPause (which are the implementations of CanPauseAndContinue), and OnShutdown (for CanShutdown) methods and set those properties to true. I then added a method, _timer_Elapsed, that will do all the work when the timer fires. Also note I had to add a reference to System.Timers to be able to use them.

OK, we now have a spiffy new service just eager and ready to be run. Well, if you recall from part 1 you simply can’t run a windows service, you have to install it. And that’s a big subject we’ll cover tomorrow in part 3!

Windows Services in C#: Getting Started (Part 1)

On occasion you have need for an application that will run all of the time on a workstation or server, whether anyone is logged into that workstation, or perhaps running in the background. For those requirements you’ll want to create a Windows Service.

There are a few things you have to keep in mind when creating a Windows Service. The first, and most important is that there is no user interface. Because Windows Services run in the background, even when no user is logged in, most times (especially when running on a server) there is no one to display a user interface to. As such, things like MessageBoxes and Forms are not allowed. Instead, if you need to log messages and the like it’s recommend you use the Event Logger. (For more info see my series on event logging, it started on January 16 of this year and ran to the 19th, http://shrinkster.com/p6d).

The next thing you will want to decide is how you’d like your service to start. You have three choices; in Manual mode (which is the default) either a user or some program event must start the service. In Automatic mode, windows will automatically kick off the event for you, and start it running when Windows itself starts up. Finally, in Disabled mode, nobody can start it until the start up type is changed.

Now you need to think about security, what permissions will your service need? LocalService is the most secure, it gets sandboxed on a local station and any access to insecure tasks, such as writing to the hard disk, are restricted. This is a good choice when you want to create an app that monitors something on the box and logs it’s output to the event log, but needs little other in the way of resources.

For a server you might wish to bump up to NetworkService. This will allow communication with other PCs on the network, but still manages any potentially harmful access to the machine.

If you need unlimited privileges, you’ll need to set your security to LocalSystem. I encourage you to really think about this before you pick LocalSystem as your level, as you open yourself up to severe vulnerabilities if anyone were to hack your code. However I do recognize there are some cases where it’s the only way to make it work, or perhaps you are in a situation where it’s safe to do so (perhaps your machine is not on the internet).

The final, and default choice is User. With User, you pass in a user id and password, and your service has the same permissions as that user. The ideal situation would be to create a special user account just for this service, and set the permissions just high enough to get the job done, and no higher. Also you’ll likely want to setup an ID with a non-expiring password. If you omit a user id/password then the person who launches the service will be prompted for a valid user id/password at run time, probably not a desirable option.

You should also be aware that debugging a windows service is very different from your typical debugging, whether you are used to WinForms or ASP.Net coding. We’ll cover debugging in a post of its own later in this series.

Just as debugging is different, so is installation. Because of its nature a Windows service has to be installed, you can’t just copy it and run it. Fortunately Visual Studio makes it easy for you by generating a setup project you can use. Again, we’ll cover that later in the series.

OK, you now have all the background you need under your belt, tomorrow we’ll start generating some code!