Calendar

<<  mars 2010  >>
lumamejevesadi
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

View posts in large calendar
Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010

(septembre 22, 2008 08:41)

Let's say we have the following specifications :

  • We want an application that will turn continuously on a machine
  • This application shall require no manual interaction (starting automatically)
  • This application shall monitor a specific folder on the file

The specifications are very simple and we will probably start thinking to a windows service that would be launched in an automatic manner. This service could then use a FileSystemWatcher to do its job.

Let's create our service

  • Create a new Blank Solution
  • Add a new project of type "Windows Service" (this type is available under the Visual C# / Windows section) and let's call it MyWindowsService
  • Automatically, VS will create a new project containing a class called "Service1", inheriting from System.ServiceProcess.ServiceBase
  • Right-Click on the file and choose Rename. Rename it to MyWindowsService
  • Update the constructor to set a service name.
using System.ServiceProcess;
 
namespace MyWindowsService
{
   public partial class MyWindowsService : ServiceBase
   {
      public MyWindowsService()
      {
         InitializeComponent();
         this.ServiceName = "MyPersonalService";
      }
 
      protected override void OnStart(string[] args)
      {
      }
 
      protected override void OnStop()
      {
      }
   }
}

This class exposes a parameterless constructor and two methods OnStart and OnStop. These are the two methods that will be called when the service is being started (or stopped) by Windows. Note that automatically, when a service is being started or stopped, Windows will log an entry in the event viewer.

Let's check this !

Let's deploy our (empty) service 

To do so, we'll need to create a setup project and some installation actions to parameter the way the service is started.

  • Add a new project of type "Setup project" (this type is available under Other Project Types / Setup and deployment)
  • Let's now how add a reference to our project
    • Right-Clic on the setup project and choose "Add / Project Output"
    • Select the project "MyWindowsService", the "Primary Output" and the configuration "Release"
    • Click on OK 

We will need now to control the way the service will be started and to specify it is a service. For that we have two solutions, either we rely on the service itself, or we write it ourself. We will here only see how to create the installer thru the service itself. 

Creating the installer's action class via the Service class itself

  • Double-Click on "MyWindowsService.cs" and right-clic in the designer to choose "Add Installer"
  • This will add a new file called "ProjectInstaller.cs" that contains a "serviceInstaller" and a "serviceProcessInstaller"
  • Check the property of the ServiceInstaller
    • Change the ServiceName to "MyPersonalService" (shall be the same as what you specified in the service constructor)
    • Change the DisplayName to "My Personal Service"
    • Change the StartType to "Automatic"
  • Check the property of the ServiceProcessInstaller
    • Change the Account to... well any value depending of the behaviour you would like. In my case, I will choose "LocalService". You can check the Service.ServiceProcess.ServiceAccount class for more information about this. 

Let's now complete the installer

Now we can complete the installer to add the installer actions we have just created.

  • Right click on the setup project and choose "View / Custom Actions"
  • Now we need to add our installer class to be used for the events "Install" and "Uninstall"
    • Right-Clic on Install and choose "Add Custom Actions"
    • Double clic on Application Folder
    • Select the "Primary Output from MyWindowsService" and click OK
    • Do the same thing for the event "Uninstall"

Now we just need to compile and to install the service to check that it is working.

  • Set yourself in "Release Mode"
  • Right-Clic on the Setup project and choose "Rebuild"
  • Right-Clic on the project and choose "Install"

Let's check the behaviour

As I have said before a service will log some information when being started and stopped. We can so go in the "Services" management window.

 

Note that even if we have put the "start type" to "Automatic", you must start the service manually. It would start automatically only after the next windows reboot !

Let's start the service and check in the Event Viewer.

We can see two new events saying respecively

  • The My Personal Service service was succesfully sent a start control
  • The My Personal Service service entered the running state

So far so good !

Let's complete our service to let him work

Now that we have a functional service, we can complete him to work. We wanted him to monitor a folder. Let's modify our service and do that this way:

using System.IO;
using System.ServiceProcess;
 
namespace MyWindowsService
{
   public partial class MyWindowsService : ServiceBase
   {
      public MyWindowsService()
      {
         InitializeComponent();
         this.ServiceName = "MyPersonalService";
      }
 
      protected override void OnStart(string[] args)
      {
         //1. Let's check only txt files in a specific folder
         string path = @"c:\Temp\MyFolderToMonitor";
         string filter = "*.txt";
         FileSystemWatcher watcher = new FileSystemWatcher(path, filter);
 
         //2. We want information about the filename
         watcher.NotifyFilter = NotifyFilters.FileName;
 
         //3. Let's register the creation event only, and let's start the monitring
         watcher.Created += new FileSystemEventHandler(watcher_Created);
         watcher.EnableRaisingEvents = true;
      }
 
      /// <summary>
      /// When a file is created, we'll just add an entry in the EventLog
      /// Note that this.EventLog will log to the Application Log, 
      /// with the name of the service as source.
      /// To log in another log, you should create yourself an EventLog.
      /// </summary>
      private void watcher_Created(object sender, FileSystemEventArgs e)
      {
         string message = string.Format("{0} : {1}", e.ChangeType, e.Name);
         this.EventLog.WriteEntry(message);
      }
 
      protected override void OnStop()
      {
      }
   }
}

Now we can just rebuild and reinstall the service. We can then start it, create a file in the "Temp\FolderToMonitor" folder and stop the service. If we now look to the EventViewer, what can we see ? Three events :

  • Service started successfully
  • Created: Document1.txt
  • Service stopped successfully

And here we are ! We now have a fully functional windows service.

What's next ?

You could do many more things to improve your service (some proposals will be described in later posts)

Billets liés

Commentaires

janvier 15. 2009 16:36

Excellent article! This really helped me a lot.

Jon Willis

février 24. 2010 10:22

Very good article..

Vinay

Ajouter un commentaire


 

  Country flag





Live preview

mars 12. 2010 03:45

Powered by BlogEngine.NET 1.2.0.0 | Theme by Pierre-Emmanuel Dautreppe