using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
using System.Diagnostics;
using System.Reflection;
using System.ServiceProcess;
using System.Linq;
namespace WeatherService.Framework
{
///
/// A generic windows service installer
///
[RunInstaller(true)]
public partial class WindowsServiceInstaller : Installer
{
///
/// Gets or sets the type of the windows service to install.
///
public WindowsServiceAttribute Configuration { get; set; }
///
/// Creates a blank windows service installer with configuration in ServiceImplementation
///
public WindowsServiceInstaller() : this (typeof(ServiceImplementation))
{
}
///
/// Creates a windows service installer using the type specified.
///
/// The type of the windows service to install.
public WindowsServiceInstaller(Type windowsServiceType)
{
if (!windowsServiceType.GetInterfaces().Contains(typeof(IWindowsService)))
{
throw new ArgumentException("Type to install must implement IWindowsService.",
"windowsServiceType");
}
var attribute = windowsServiceType.GetAttribute();
if (attribute == null)
{
throw new ArgumentException("Type to install must be marked with a WindowsServiceAttribute.",
"windowsServiceType");
}
Configuration = attribute;
}
///
/// Performs a transacted installation at run-time of the AutoCounterInstaller and any other listed installers.
///
/// The other installers to include in the transaction
/// The IWindowsService implementer to install.
public static void RuntimeInstall()
where T : IWindowsService
{
string path = "/assemblypath=" + Assembly.GetEntryAssembly().Location;
using (var ti = new TransactedInstaller())
{
ti.Installers.Add(new WindowsServiceInstaller(typeof (T)));
ti.Context = new InstallContext(null, new [] { path });
ti.Install(new Hashtable());
}
}
///
/// Performs a transacted un-installation at run-time of the AutoCounterInstaller and any other listed installers.
///
/// The other installers to include in the transaction
/// The IWindowsService implementer to install.
public static void RuntimeUnInstall(params Installer[] otherInstallers)
where T : IWindowsService
{
string path = "/assemblypath=" + Assembly.GetEntryAssembly().Location;
using (var ti = new TransactedInstaller())
{
ti.Installers.Add(new WindowsServiceInstaller(typeof (T)));
ti.Context = new InstallContext(null, new [] { path });
ti.Uninstall(null);
}
}
///
/// Installer class, to use run InstallUtil against this .exe
///
/// The saved state for the installation.
public override void Install(System.Collections.IDictionary savedState)
{
ConsoleHarness.WriteToConsole(ConsoleColor.White, "Installing service {0}.", Configuration.Name);
// install the service
ConfigureInstallers();
base.Install(savedState);
// wire up the event log source, if provided
if (!string.IsNullOrWhiteSpace(Configuration.EventLogSource))
{
// create the source if it doesn't exist
if (!EventLog.SourceExists(Configuration.EventLogSource))
{
EventLog.CreateEventSource(Configuration.EventLogSource, "Application");
}
}
}
///
/// Removes the counters, then calls the base uninstall.
///
/// The saved state for the installation.
public override void Uninstall(System.Collections.IDictionary savedState)
{
ConsoleHarness.WriteToConsole(ConsoleColor.White, "Un-Installing service {0}.", Configuration.Name);
// load the assembly file name and the config
ConfigureInstallers();
base.Uninstall(savedState);
// wire up the event log source, if provided
if (!string.IsNullOrWhiteSpace(Configuration.EventLogSource))
{
// create the source if it doesn't exist
if (EventLog.SourceExists(Configuration.EventLogSource))
{
EventLog.DeleteEventSource(Configuration.EventLogSource);
}
}
}
///
/// Rolls back to the state of the counter, and performs the normal rollback.
///
/// The saved state for the installation.
public override void Rollback(System.Collections.IDictionary savedState)
{
ConsoleHarness.WriteToConsole(ConsoleColor.White, "Rolling back service {0}.", Configuration.Name);
// load the assembly file name and the config
ConfigureInstallers();
base.Rollback(savedState);
}
///
/// Method to configure the installers
///
private void ConfigureInstallers()
{
// load the assembly file name and the config
Installers.Add(ConfigureProcessInstaller());
Installers.Add(ConfigureServiceInstaller());
}
///
/// Helper method to configure a process installer for this windows service
///
/// Process installer for this service
private ServiceProcessInstaller ConfigureProcessInstaller()
{
var result = new ServiceProcessInstaller();
// if a user name is not provided, will run under local service acct
if (string.IsNullOrEmpty(Configuration.UserName))
{
result.Account = Configuration.ServiceAccount;
result.Username = null;
result.Password = null;
}
else
{
// otherwise, runs under the specified user authority
result.Account = ServiceAccount.User;
result.Username = Configuration.UserName;
result.Password = Configuration.Password;
}
return result;
}
///
/// Helper method to configure a service installer for this windows service
///
/// Process installer for this service
private ServiceInstaller ConfigureServiceInstaller()
{
// create and config a service installer
var result = new ServiceInstaller
{
ServiceName = Configuration.Name,
DisplayName = Configuration.DisplayName,
Description = Configuration.Description,
StartType = Configuration.StartMode,
};
return result;
}
}
}