Я недавно сделал это сам, и вот код, который позволит вам передать «/ install» или «/ uninstall» в качестве опции командной строки для установки вашего сервиса. Вы можете изменить это для автоматической установки, если хотите. Он также обращается к app.config нормально (мой оригинальный сервис делает это в своем основном цикле). Как вы можете видеть, я настраиваю его для запуска под определенным пользователем, но вы можете установить spi.Account = ServiceAccount.LocalSystem; и пропустите имя и пароль. Надеюсь, это поможет:
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);
}
}
}