|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionThis article shows a technique to design Windows Service apps with the following goals:
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. BackgroundIf 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 CodeBy 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:
In a nutshell, the namespace GDWS.ExampleServiceProgram
{
class Program
{
static void Main(string[] args)
{
ServiceMainProgram.ServiceMain(args);
}
}
[RunInstaller(true)]
public class ExampleServiceInstaller : CustomServiceInstaller
{
}
}
Class - CustomServiceInstallerThis 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 - ServiceMainProgramIn order to load the "server logic" dynamically, .NET Reflection is used to load the DLL that encapsulates the server logic. The two constructors are public class ServiceMainProgram
{
...
...
public static void Service(string[] args, Type type)...
public static void Service(string[] args)...
...
}
The The second private Type LoadAssemby(string configFileName)
{
...
...
Assembly asm = Assembly.LoadFile(Path.GetFullPath(assemblyFullPath));
...
Type type = asm.GetType(typeName);
...
}
Once the private void Run()
{
if (debugMode) RunDebug();
else
{
ServiceBase[] servicesToRun = new ServiceBase[]
{ new GenericService(threadProcType) };
ServiceBase.Run(servicesToRun);
}
}
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;
}
...
}
}
DebuggingFor debugging purposes, define a command line argument Installing as a Proper Windows ServiceYou can install the sample service app using the bundled Setup project. To quickly test the app as a Windows Service, you can use the ServiceConfig.xml<?xml version="1.0" encoding="utf-8" ?>
<ConfigService>
<ServiceName value="ExampleService"/>
<ServiceDisplayName value="An Example Service"/>
<ServiceDescription value="An example service
that demonstrates a generic and dynamic technique."/>
</ConfigService>
ServiceInstall.xml<?xml version="1.0" encoding="utf-8" ?>
<InstallService>
<ServiceAssemblyFullPath value=
"..\..\..\GDWS.ExampleService\bin\Debug\GDWS.ExampleService.dll"/>
<TypeName value="GDWS.ExampleService.ThreadProcExample"/>
</InstallService>
Please note that, although the History
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||