Thursday, September 30, 2010

A Debuggable Windows Service in Csharp

This is a great example of a windows service. I use it in a app that reads email from pop, and updates a database/webapp written in SilverLight for the FrontEnd.

One note, this uses a Timer Approach to initiate the check. I found unless I put a lock around the worker class,I would see the timer fire again, and I get get a breakpoint in another "thread", while debugging the first. The lock fixed the issue. But take note if you using this or something similar.

 using System;
  
 using System.Collections;
  
 using System.ComponentModel;
  
 using System.Configuration.Install;
  
 using System.Reflection;
  
 using System.ServiceProcess;
  
 using System.Threading;
  
 using System.Management;
  
 using Microsoft.Practices.EnterpriseLibrary.Logging;
  
 namespace WhereAmIEmail
  
 {
  
   public class WhereAmIEmail : ServiceBase
  
   {
  
     private Worker myworker;
  
     private Timer serviceTimer;
  
     private Container components = null;
  
     public WhereAmIEmail()
  
     {      
  
       InitializeComponent();     
  
     }
  
     // The main entry point for the process
  
     private static void Main(string[] args)
  
     {
  
       string opt = null;
  
       // check for arguments
  
       if (args.Length > 0)
  
       {
  
         opt = args[0];
  
         if (opt != null && opt.ToLower() == "/install")
  
         {
  
           TransactedInstaller ti = new TransactedInstaller();
  
           ProjectInstaller pi = new ProjectInstaller();
  
           ti.Installers.Add(pi);
  
           String path = String.Format("/assemblypath={0}",
  
                         Assembly.GetExecutingAssembly().Location);
  
           String[] cmdline = {path};
  
           InstallContext ctx = new InstallContext("", cmdline);
  
           ti.Context = ctx;
  
           ti.Install(new Hashtable());
  
         }
  
         else if (opt != null && opt.ToLower() == "/uninstall")
  
         {
  
           TransactedInstaller ti = new TransactedInstaller();
  
           ProjectInstaller mi = new ProjectInstaller();
  
           ti.Installers.Add(mi);
  
           String path = String.Format("/assemblypath={0}",
  
                         Assembly.GetExecutingAssembly().Location);
  
           String[] cmdline = {path};
  
           InstallContext ctx = new InstallContext("", cmdline);
  
           ti.Context = ctx;
  
           ti.Uninstall(null);
  
         }
  
       }
  
       if (opt == null) // e.g. ,nothing on the command line
  
       {
  
 #if ( ! DEBUG )
  
         ServiceBase[] ServicesToRun;
  
         ServicesToRun = new ServiceBase[] {new WhereAmIEmail()};
  
         ServiceBase.Run(ServicesToRun);
  
 #else
  
         // debug code: allows the process to run as a non-service
  
         // will kick off the service start point, but never kill it
  
         // shut down the debugger to exit
  
         WhereAmIEmail service = new WhereAmIEmail();
  
         service.OnStart(null);
  
         Thread.Sleep(Timeout.Infinite);
  
 #endif 
  
       }
  
     }
  
     /// <summary> 
  
     /// Required method for Designer support - do not modify 
  
     /// the contents of this method with the code editor.
  
     /// </summary>
  
     private void InitializeComponent()
  
     {
  
       components = new Container();
  
       this.ServiceName = "WhereAmIEmail";
  
     }
  
     /// <summary>
  
     /// Clean up any resources being used.
  
     /// </summary>
  
     protected override void Dispose(bool disposing)
  
     {
  
       if (disposing)
  
       {
  
         if (components != null)
  
         {
  
           components.Dispose();
  
         }
  
       }
  
       base.Dispose(disposing);
  
     }
  
     /// <summary>
  
     /// Set things in motion so your service can do its work.
  
     /// </summary>
  
     protected override void OnStart(string[] args)
  
     {
  
       myworker = new Worker();
  
       TimerCallback timerDelegate = new TimerCallback(myworker.DoWork);
  
       serviceTimer = new Timer(timerDelegate, null, 10000, 10000);
  
     }
  
     /// <summary>
  
     /// Stop this service.
  
     /// </summary>
  
     protected override void OnStop()
  
     {
  
       // test.Stop() ;
  
     }
  
   }
  
 }
  

0 comments: