Hi James,
I recently did this myself, and here is code that will allow you to pass "/install" or "/uninstall" as a command line option to install your service. You can change this to automatically install if you'd like. It also accesses the app.config fine (my original service does this in its main loop). As you can see, I am setting it to run as a specific user, but you can set spi.Account = ServiceAccount.LocalSystem; and omit the name and password. Hope this helps:
namespace MyService
{
public class ServiceMonitor : ServiceBase
{
private System.ComponentModel.Container _components = null;
private static string _service_name = "MyServiceName";
public ServiceMonitor()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.CanHandlePowerEvent = true;
this.CanPauseAndContinue = true;
this.CanShutdown = true;
this.CanStop = true;
this.ServiceName = _service_name;
}
protected override void Dispose(bool disposing)
{
if (disposing && _components != null)
{
_components.Dispose();
}
base.Dispose(disposing);
}
static void Main(string[] args)
{
string opt = null;
if (args.Length >= 1)
{
opt = args[0].ToLower();
}
if (opt == "/install" || opt == "/uninstall")
{
TransactedInstaller ti = new TransactedInstaller();
MonitorInstaller mi = new MonitorInstaller(_service_name);
ti.Installers.Add(mi);
string path = String.Format("/assemblypath={0}", Assembly.GetExecutingAssembly().Location);
string[] cmdline = { path };
InstallContext ctx = new InstallContext("", cmdline);
ti.Context = ctx;
if (opt == "/install")
{
Console.WriteLine("Installing");
ti.Install(new Hashtable());
}
else if (opt == "/uninstall")
{
Console.WriteLine("Uninstalling");
try
{
ti.Uninstall(null);
}
catch (InstallException ie)
{
Console.WriteLine(ie.ToString());
}
}
}
else
{
ServiceBase[] services;
services = new ServiceBase[] { new ServiceMonitor() };
ServiceBase.Run(services);
}
}
protected override void OnStart(string[] args)
{
//
// TODO: spawn a new thread or timer to perform actions in the background.
//
base.OnStart(args);
}
protected override void OnStop()
{
//
// TODO: stop your thread or timer
//
base.OnStop();
}
}
[RunInstaller(true)]
public class MonitorInstaller : Installer
{
public MonitorInstaller()
: this("MyServiceName")
{
}
public MonitorInstaller(string service_name)
{
ServiceProcessInstaller spi = new ServiceProcessInstaller();
spi.Account = ServiceAccount.User;
spi.Password = ConfigurationManager.AppSettings["Password"];
spi.Username = ConfigurationManager.AppSettings["Username"];
ServiceInstaller si = new ServiceInstaller();
si.ServiceName = service_name;
si.StartType = ServiceStartMode.Automatic;
si.Description = "MyServiceName";
si.DisplayName = "MyServiceName";
this.Installers.Add(spi);
this.Installers.Add(si);
}
}
}