Thursday, 24 September 2009

Installing Windows Services programmatically

After a few problems with using the ManagedInstallerClass (passing arguments in), and noticing that the MSDN docs say it’s not meant to be used in any case, I moved to using this sort of code instead:

 

   1: using System;
   2: using System.Configuration.Install;
   3: using System.ServiceProcess;
   4: using System.Threading;
   5: using System.Diagnostics;
   6: using System.IO;
   7: using System.Reflection;
   8: using System.Collections.Generic;
   9:  
  10: namespace SimpleWindowsServiceManager
  11: {
  12:     class Program
  13:     {
  14:         static void Main(string[] args)
  15:         {
  16:             string fullpath = args[0];
  17:             string[] arguments = args[1].Split(' ');
  18:             string servicename = Path.GetFileNameWithoutExtension(Path.GetFileName(args[0]));
  19:             foreach (string arg in arguments)
  20:             {
  21:                 if (arg.Contains("name"))
  22:                 {
  23:                     string[] bits = arg.Split(new char[] { '=' });
  24:                     servicename = bits[1];
  25:                 }
  26:             }
  27:  
  28:             #region Test to see if it's a service
  29:             try
  30:             {
  31:                 AssemblyInstaller.CheckIfInstallable(fullpath);
  32:             }
  33:             catch (Exception ex)
  34:             {
  35:                 Console.WriteLine("Assembly's not installable");
  36:                 return;
  37:             }
  38:             #endregion
  39:  
  40:             #region install
  41:             Assembly assembly = null;
  42:             try
  43:             {
  44:                 assembly = Assembly.LoadFrom(fullpath); // LoadFrom probes path for dependencies -- LoadFile does not.
  45:             }
  46:             catch (Exception ex)
  47:             {
  48:                 Console.WriteLine("Couldn't load assembly: " + ex.Message);
  49:                 return;
  50:             }
  51:             AssemblyInstaller installer = new AssemblyInstaller(assembly, null);
  52:             Dictionary state = new Dictionary();
  53:             try
  54:             {
  55:                 installer.Install(state);
  56:                 installer.Rollback(state);
  57:             }
  58:             catch (Exception ex)
  59:             {
  60:                 Console.WriteLine("Trouble pre-installing assembly");
  61:                 return;
  62:             }
  63:             #endregion
  64:  
  65:             installer = new AssemblyInstaller(assembly, arguments);
  66:             state = new Dictionary();
  67:  
  68:             #region Install service
  69:             try
  70:             {
  71:                 installer.Install(state);
  72:             }
  73:             catch (InvalidOperationException iex)
  74:             {
  75:                 Console.WriteLine("Install not applicable for this assembly:\n" + iex.Message);
  76:                 return;
  77:             }
  78:             catch (Exception ex)
  79:             {
  80:                 Console.WriteLine(ex.Message);
  81:             }
  82:             #endregion
  83:  
  84:             Console.WriteLine("Getting service controller for " + servicename);
  85:             ServiceController controller = new ServiceController(servicename);
  86:  
  87:             #region Start service
  88:             try
  89:             {
  90:                 Console.WriteLine("Starting service");
  91:                 controller.Start();
  92:             }
  93:             catch (Exception ex)
  94:             {
  95:                 Console.WriteLine(ex.Message);
  96:             }
  97:             #endregion
  98:  
  99:             Thread.Sleep(10000);
 100:  
 101:             #region Stop service
 102:             try
 103:             {
 104:                 Console.WriteLine("Stopping service");
 105:                 controller.Stop();
 106:             }
 107:             catch (Exception ex)
 108:             {
 109:                 Console.WriteLine(ex.Message);
 110:             }
 111:             #endregion
 112:  
 113:             Thread.Sleep(10000);
 114:  
 115:             #region Uninstall service
 116:             try
 117:             {
 118:                 installer.Uninstall(state);
 119:             }
 120:             catch (Exception ex)
 121:             {
 122:                 Console.WriteLine(ex.Message);
 123:             }
 124:             #endregion
 125:         }
 126:     }
 127: }

No comments: