Click here to Skip to main content
11,927,711 members (52,511 online)
Click here to Skip to main content
Add your own
alternative version


54 bookmarked

C# Generic Dynamic Windows Service using .NET Reflection

, 31 Jan 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
A technique to create Windows Service apps that's configurable and dynamic by using the .NET Reflection.


This article shows a technique to design Windows Service apps with the following goals:

  1. Can be debugged like a "Console" application without the need to invoke the "Installer" program.
  2. The main "Windows Service" code should be reusable and can be rapidly applied to any new "Windows Service" application development.
  3. Separates the "Server Logic" and allows dynamic switching if desired.
  4. The details of the "Windows Service" during installation are configurable via an XML file.
  5. The loading of the server logic is configurable via an XML file.

The sample code I presented here is the basic framework and has been tested with Visual Studio 2008 and .NET 3.5 Framework. But the concept should be applicable to other versions as well.


If you have never created a Windows Service application, there is a "walkthrough" article on the MSDN library site. Obviously, there're many useful articles on The Code Project as well.

Using the Code

By using the presented technique, to create a Windows Service app will just require you to create a new "Console" project using the Visual Studio.

The sample Visual Studio solution consists of 4 projects. They are:

  1. GDWS.Common - That's where the generic reusable code for the Windows Service sits.
  2. GDWS.ExampleService - This is an example "server" logic that's aimed to be built as a .NET assembly.
  3. GDWS.ExampleServiceProgram - This is an example "Console" app that actually invokes the server logic.
  4. SetupExampleService - This is a typical "Setup & Deployment" project to demonstrate that this technique also works seamlessly with the standard setup mechanism.

In a nutshell, the Main() program is as simple as this:

namespace GDWS.ExampleServiceProgram
  class Program
    static void Main(string[] args)


  public class ExampleServiceInstaller : CustomServiceInstaller

Class - CustomServiceInstaller

This class mainly reads the ServiceInstall.xml file in order to tell Windows Installer the "Service Name", the "Service Display Name", and the "Service Descriptions".

Class - ServiceMainProgram

In order to load the "server logic" dynamically, .NET Reflection is used to load the DLL that encapsulates the server logic. The two constructors are private, and you use the two static methods to invoke the process.

public class ServiceMainProgram
  public static void Service(string[] args, Type type)...

  public static void Service(string[] args)...

The static method that takes two arguments requires you to submit a Type, so that during creation of an object internally it can use Reflection to find out that the two required static methods StartThreadProc and StopThreadProc are present.

The second static method that takes only one argument reads the name of the Type from the ServiceConfig.xml file, which also tells it where to find the server logic assembly DLL. Once the path of the DLL is located, the assembly is loaded by using Reflection.

private Type LoadAssemby(string configFileName)
  Assembly asm = Assembly.LoadFile(Path.GetFullPath(assemblyFullPath));
  Type type = asm.GetType(typeName);

Once the Type is found and checked, the following code can utilize the reflected methods:

private void Run()
  if (debugMode) RunDebug();
    ServiceBase[] servicesToRun = new ServiceBase[]
        { new GenericService(threadProcType) };

private void RunDebug()
  MethodInfo mStart = threadProcType.GetMethod(START_THREAD_PROC);
  // assuming static method, hence no need to pass any instantiated object
  mStart.Invoke(null, null);
  bool stop = false;
  while (!stop)
    if (k.KeyChar == 'q' || k.KeyChar == 'Q')
      MethodInfo mStop = threadProcType.GetMethod(STOP_THREAD_PROC);
      // assuming static method, hence no need to pass any instantiated object
      mStop.Invoke(null, null);
      stop = true;


For debugging purposes, define a command line argument debug or under the Command Prompt, just type yourservice.exe debug to invoke the program into debug mode.

Installing as a Proper Windows Service

You can install the sample service app using the bundled Setup project.

To quickly test the app as a Windows Service, you can use the installutil.exe and uninstall it by calling installutil.exe /u.


<?xml version="1.0" encoding="utf-8" ?>
<ServiceName value="ExampleService"/>
<ServiceDisplayName value="An Example Service"/>
<ServiceDescription value="An example service
    that demonstrates a generic and dynamic technique."/>


<?xml version="1.0" encoding="utf-8" ?>
<ServiceAssemblyFullPath value=
<TypeName value="GDWS.ExampleService.ThreadProcExample"/>

Please note that, although the ServiceAssemblyFullPath is specified as a relative path, the code will try to locate it locally if it cannot find it at the first instance.


  • 2008-01-22: Article created


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

United Kingdom United Kingdom
No Biography provided

You may also be interested in...

Comments and Discussions

QuestionService work in debug mode but does not in release Pin
romanlopg7-Dec-09 9:09
memberromanlopg7-Dec-09 9:09 
AnswerRe: Service work in debug mode but does not in release Pin
romanlopg7-Dec-09 11:31
memberromanlopg7-Dec-09 11:31 
GeneralRe: Service work in debug mode but does not in release Pin
AH9-Dec-09 6:14
memberAH9-Dec-09 6:14 
GeneralUnable to run the console program in Release Mode Pin
noms18-Oct-09 20:28
membernoms18-Oct-09 20:28 
GeneralRe: Unable to run the console program in Release Mode Pin
AH18-Oct-09 22:27
memberAH18-Oct-09 22:27 
QuestionCan't able to Run the sample Code Pin
noms4-Aug-09 19:48
membernoms4-Aug-09 19:48 
AnswerRe: Can't able to Run the sample Code Pin
AH4-Aug-09 22:05
memberAH4-Aug-09 22:05 
QuestionWhy call this method ServiceMain? Pin
binarycheese21-Apr-09 6:32
memberbinarycheese21-Apr-09 6:32 
AnswerRe: Why call this method ServiceMain? Pin
AH21-Apr-09 7:19
memberAH21-Apr-09 7:19 
GeneralConflict between TWO 'Generic Dynamic Windows Services' Pin
KeesDekker21-Apr-09 2:03
memberKeesDekker21-Apr-09 2:03 
GeneralRe: Conflict between TWO 'Generic Dynamic Windows Services' Pin
AH21-Apr-09 2:58
memberAH21-Apr-09 2:58 
GeneralError 1053 .... Pin
Kris-I26-Mar-09 9:37
memberKris-I26-Mar-09 9:37 
GeneralRe: Error 1053 .... Pin
AH26-Mar-09 12:22
memberAH26-Mar-09 12:22 
GeneralRe: Error 1053 .... Pin
Kris-I27-Mar-09 0:41
memberKris-I27-Mar-09 0:41 
GeneralRe: Error 1053 .... Pin
AH27-Mar-09 2:36
memberAH27-Mar-09 2:36 
GeneralA Question.. Pin
zeroresult22-Jan-08 16:58
memberzeroresult22-Jan-08 16:58 
GeneralRe: A Question.. Pin
Anand Morbia23-Jan-08 0:57
memberAnand Morbia23-Jan-08 0:57 
GeneralRe: A Question.. Pin
AH23-Jan-08 3:17
memberAH23-Jan-08 3:17 
Generalreally useful~ Pin
iBDev22-Jan-08 16:31
memberiBDev22-Jan-08 16:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.151126.1 | Last Updated 31 Jan 2008
Article Copyright 2008 by AH
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid