Building Dynamic Service in C#


This is a service that will run an application, and can be used over an over without hard coding any information

The installer and gleans service information from the command line so one does not have to hard code the service name, account and password. It also stores a command in the Registry that will be retrieved and run as a process. The name of the Service itself is append to the ImagePath of the service in order to be passed as a command line argument so the service does not need to know its own name (This part of the Service framework need to be addressed by Microsoft).

using System;
using System.ServiceProcess;
using System.Collections;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Web.Services;
using System.Diagnostics;
using System.IO;
using System.Configuration.Install;
/*
* This is the ProjectInstaller class used to install the project
*/
[RunInstallerAttribute(true)]
public class ProjectInstaller: Installer
{
private static Boolean initialized = false;
private static Boolean installing = false;
private ServiceInstaller serviceInstaller;
private ServiceProcessInstaller processInstaller;
private String command;
public ProjectInstaller()
{
BeforeInstall +=
new InstallEventHandler(BeforeInstallEventHandler);
BeforeUninstall +=
new InstallEventHandler(BeforeUninstallEventHandler);
}
private void initialize()
{
String username =
null;
String password =
null;
Console.WriteLine("\n\n---------------------------------------");
Console.WriteLine("Please Enter the name of the Service:\n");
String serviceName = Console.ReadLine();
Console.WriteLine("\nPlease Enter the Service's user account:\n");
username = Console.ReadLine();
Console.WriteLine("\nPlease Enter the user account password\n");
password = Console.ReadLine();
if (installing)
{
Console.WriteLine("\nPlease Enter the command you wish to execute\n");
this.command = Console.ReadLine();
}
Console.WriteLine("\nThanks Dude!\n");
Console.WriteLine("---------------------------------------");
// Instantiate installers for process and services.
processInstaller = new ServiceProcessInstaller();
serviceInstaller =
new ServiceInstaller();
// The services run under a User Account
processInstaller.Account = ServiceAccount.User;
processInstaller.Username = username;
processInstaller.Password = password;
// The services are started manually.
serviceInstaller.StartType = ServiceStartMode.Manual;
// ServiceName must equal those on ServiceBase derived classes.
serviceInstaller.ServiceName = serviceName;
// Add installers to collection. Order is not important.
Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
initialized =
true;
}
/*
* Installs the Service but adds a parameters entry
* into the registry under the Service.
*/
public override void Install(IDictionary stateServer)
{
Microsoft.Win32.RegistryKey system,
currentControlSet,
services,
service,
config;
try
{
//Let the project installer do its job
base.Install(stateServer);
//Open the HKEY_LOCAL_MACHINE\SYSTEM key
system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");
//Open CurrentControlSet
currentControlSet = system.OpenSubKey("CurrentControlSet");
//Go to the services key
services = currentControlSet.OpenSubKey("Services");
//Open the key for your service, and allow writing
service = services.OpenSubKey(this.serviceInstaller.ServiceName, true);
//Add your service's description as a REG_SZ value named "Description"
service.SetValue("Description", this.serviceInstaller.ServiceName + " Description");
//(Optional) Add some custom information your service will use...
config = service.CreateSubKey("Parameters");
config.SetValue("Arguments", command);
Console.WriteLine(service.GetValue("ImagePath"));
string path = service.GetValue("ImagePath") + " " +
this
.serviceInstaller.ServiceName;
service.SetValue("ImagePath", path);
}
catch(Exception e)
{
Console.WriteLine("An exception was thrown during service installation:\n" + e.ToString());
}
}
/*
* UnInstalls the Service and removes the parameters entry
* from the registry under the Service.
*/
public override void Uninstall(IDictionary stateServer)
{
Microsoft.Win32.RegistryKey system,
currentControlSet,
services,
service;
try
{
//Drill down to the service key and open it with write permission
system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");
currentControlSet = system.OpenSubKey("CurrentControlSet");
services = currentControlSet.OpenSubKey("Services");
service = services.OpenSubKey(
this.serviceInstaller.ServiceName, true);
//Delete any keys you created during installation (or that your service created)
service.DeleteSubKeyTree("Parameters");
}
catch(Exception e)
{
Console.WriteLine("Exception encountered while uninstalling service:\n" + e.ToString());
}
finally
{
//Let the project installer do its job
base.Uninstall(stateServer);
}
}
private void BeforeInstallEventHandler(object sender, InstallEventArgs e)
{
Console.WriteLine("\nBefore Install");
installing =
true;
if (!initialized)
{
initialize();
}
}
private void BeforeUninstallEventHandler(object sender, InstallEventArgs e)
{
Console.WriteLine("\nBefore UnInstall");
installing =
false;
if (!initialized)
{
initialize();
}
}
}
/*
* The SISService class used to run executables
*/
class DynService : System.ServiceProcess.ServiceBase
{
private Process process;
public String processName;
public DynService()
{
this.ServiceName = "BOB";
}
public static void Main(string [] args)
{
SISService service =
new DynService();
if (args.Length != 0)
{
service.ServiceName = args[0];
}
ServiceBase.Run(service);
}
protected override void OnStart(string[] args)
{
process =
new Process();
process.StartInfo.FileName = ReadArguments();
process.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
process.Start();
}
/// <summary>
/// Stop this service.
/// </summary>
protected override void OnStop()
{
process.Kill();
}
protected override void OnShutdown()
{
process.Kill();
}
protected override void OnCustomCommand(int command)
{
if (command == 144)
{
}
}
protected String ReadArguments()
{
Microsoft.Win32.RegistryKey system,
currentControlSet,
services,
service,
param;
//Open the HKEY_LOCAL_MACHINE\SYSTEM key
system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");
//Open CurrentControlSet
currentControlSet = system.OpenSubKey("CurrentControlSet");
//Go to the services key
services = currentControlSet.OpenSubKey("Services");
//Open the key for your service, and allow writing
service = services.OpenSubKey(this.ServiceName, false);
param = service.OpenSubKey("Parameters",
false);
String args = (String) param.GetValue("Arguments");
return args;
}
}


Similar Articles