Skip to content

Instantly share code, notes, and snippets.

@jgauffin
Last active February 15, 2021 13:20
Show Gist options
  • Save jgauffin/6306647 to your computer and use it in GitHub Desktop.
Save jgauffin/6306647 to your computer and use it in GitHub Desktop.
A better windows service helper - Makes it easier to debug windows service, and to uninstall/install them from the command prompt. From my blog post: http://blog.gauffin.org/2013/08/a-better-windows-service-helper/
internal static class Program
{
private static void Main()
{
// runs the app as a console application if the command argument "-console" is used
if (WindowsServiceHelper.RunAsConsoleIfRequested<Service1>())
return;
// uses "-install" and "-uninstall" to manage the service.
if (WindowsServiceHelper.ManageServiceIfRequested(Environment.GetCommandLineArgs()))
return;
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
}
public static class WindowsServiceHelper
{
private static readonly string[] InstallArguments = new[] {"/i", "/install", "-i", "-install"};
private static readonly string[] UninstallArguments = new[] {"/u", "/uninstall", "-u", "-uninstall"};
public static void AttachConsole()
{
AllocConsole();
}
public static bool ManageServiceIfRequested(string[] arguments)
{
try
{
if (!arguments.Any(x => InstallArguments.Contains(x)) &&
!arguments.Any(x => UninstallArguments.Contains(x)))
return false;
AttachConsole();
var serviceFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "InstallUtil.InstallLog");
if (File.Exists(serviceFile))
File.Delete(serviceFile);
if (arguments.Any(x => InstallArguments.Contains(x)))
ManagedInstallerClass.InstallHelper(new[] {Assembly.GetExecutingAssembly().Location});
else if (arguments.Any(x => UninstallArguments.Contains(x)))
ManagedInstallerClass.InstallHelper(new[] {"/u", Assembly.GetExecutingAssembly().Location});
else
return false;
}
catch (Exception exception)
{
Console.WriteLine("Error: " + exception.Message);
}
Console.WriteLine("Service configuration is done. Press any key to exit console");
Console.ReadKey();
return true;
}
public static bool RunAsConsoleIfRequested<T>() where T : ServiceBase, new()
{
if (!Environment.CommandLine.Contains("-console"))
return false;
AttachConsole();
var service = new T();
var onstart = service.GetType().GetMethod("OnStart", BindingFlags.Instance | BindingFlags.NonPublic);
var args = Environment.GetCommandLineArgs().Where(name => name != "-console").ToArray();
onstart.Invoke(service, new object[] {args});
Console.WriteLine("Your service named '" + service.GetType().FullName +
"' is up and running.\r\nPress 'ENTER' to stop it.");
Console.ReadLine();
var onstop = service.GetType().GetMethod("OnStop", BindingFlags.Instance | BindingFlags.NonPublic);
onstop.Invoke(service, null);
Console.WriteLine("Service is stopped. Press any key to exit console");
Console.ReadKey();
return true;
}
[DllImport("kernel32")]
private static extern bool AllocConsole();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment