Skip to content
/ muster Public

Windows Service abstraction in .NET with console harness and runner

Notifications You must be signed in to change notification settings

jgoz/muster

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

70 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Muster

[muhs-ter]
(verb) to assemble, as for orders, battle, etc.
(verb phrase) muster in, to enlist into service (in the armed forces).

Muster is a .NET (4.0) project aimed at simplifying most aspects of Windows Services — debugging, testing and deploying.

The core project, Muster, is a service abstraction layer and harnesses (console/service) based on a series of blog posts (part one, part two) by James Michael Hare.

The runner project, Muster.Runner or muster-run.exe, is a console application that can run or install services found in arbitrary assemblies.

Muster is available on NuGet.

This project is currently considered unstable and may not suitable for production use.

Implementing services

All services must implement the IWindowsService interface. The interface defines 4 methods:

  • OnStart(String[] args) — called when the service starts. Must not block the calling thread.
  • OnStop — called when the service is stopped.
  • OnPause — called when the service is paused. Must not block the calling thread.
  • OnContinue — called when the service is resumed from being paused. Must not block the calling thread.
  • OnShutdown — called when the operating system goes for shut down.

Non-Blocking Methods

As noted above, the OnStart, OnPause and OnContinue methods must not block the calling thread. This is to ensure that the service is always able to receive Stop/Pause/Continue signals.

In the future, a service base class may be added to abstract the above threading requirements from the implementor.

Example

[WindowsService("TestService",
    Description = "This is the description that will show up in the Windows Services management console.",
    EventLogSource = "TestServiceLogSource")]
public class TestService : IWindowsService
{
    public void OnStart(String[] args)
    {
        Console.WriteLine("We are starting up.");
    }

    public void OnStop()
    {
        Console.WriteLine("We are stopping.");
    }

    public void OnPause()
    {
        Console.WriteLine("We are pausing.");
    }

    public void OnContinue()
    {
        Console.WriteLine("We are resuming.");
    }

    public void OnShutdown()
    {
        Console.WriteLine("We are shutting down.");
    }

    public void Dispose()
    {
    }
}

Using muster-run, the console runner

The Muster console runner enables IWindowsService implementations to be run from the console without needing to be installed, which can greatly simplify the development/testing cycle. The runner also provides a convenient way to install and uninstall services on the local machine.

Assuming muster-run.exe is on the system path and MyService.dll contains an IWindowsService, the following command is enough to get started:

> muster-run MyService.dll

This will find and run all IWindowsService implementations in the given assembly. While running, the following prompt will be displayed:

> [muster] Currently Running: [Q]uit [P]ause [R]esume

Pressing P will pause all running services, R will resume all paused services and Q will stop all services, exiting the runner.

Usage options

muster-run [OPTIONS]+ Assembly[,Assembly...]

Options:
  -i, --install         Install the specified service(s)
  -u, --uninstall       Uninstall the specified service(s)
  -t, --types=VALUE     Comma-separated list of individual service types
  -c, --config=VALUE    Path to service configuration file
  -h, --help            Show this message and exit

Install

This will install the IWindowsServices in the given Assembly (or Assemblies) on the local machine.

Uninstall

This will uninstall the IWindowsServices contained in the given Assembly/Assmblies from the local machine. Note that the same assembly version should be used for installation and uninstallation.

Types

This allows specifying which services will actually run. The argument should be a comma-separated list of type names (full or partial) from any of the given assemblies.

muster-run --types=ServiceOne,MyCompany.MyServices.ServiceTwo MyServices.dll

Config

This allows specifying a configuration file to be used as the App.config equivalent for all running services. All services must currently share the same configuration file.

Debugging in Visual Studio

During development, Muster allow you to debug into your services from within Visual Studio. Here's how:

  1. (Optional) Set your service project as a StartUp Project
  2. In the Project Properties -> Debug tab, select "Start external program"
  3. Enter the path to muster-run.exe
    • If it's installed on the system path, the executable name is enough
    • If you're using the NuGet package, you can specify a relative path. E.g.
      ..\..\packages\muster.X.Y.Z\bin\muster-run.exe
  4. Set the "Command line arguments" field to the filename of your service assembly. You can add any additional command line options here too, like the configuration file path. E.g.
    -c ..\..\MyService.config MyService.dll

Now when you run your project, the Muster console runner will start running all of the services defined in your project.

Compiling and packaging

To compile, run build.cmd. To create a NuGet package, run package.cmd.

This project, including the bundled Mono.Options source, is licenced under the MIT licence.

TODO

  • Service base class to abstract the threading requirements
  • Use real logging strategy (Common.Logging?)
  • Automatically reload AppDomain upon changes to target assemblies
  • WebActivator harness
  • NuGet

About

Windows Service abstraction in .NET with console harness and runner

Resources

Stars

Watchers

Forks

Packages

No packages published