Click here to Skip to main content
15,881,413 members
Articles / Programming Languages / C#
Article

Windows Service Test Form

Rate me:
Please Sign up or sign in to vote.
3.90/5 (11 votes)
5 Jul 20061 min read 80.9K   2.6K   47   7
An article on service debugging in VS2005.

Introduction

There are a few articles on the internet on debugging Windows Services in VS 2005. The official method is to attach a debugger to the service process once it has started. This makes it difficult to step through a service's startup process. The article, Debugging Windows Services under Visual Studio .NET, by Lee Humphries shows how to isolate individual methods using the DEBUG preprocessor directive. Here, we go a step further and create a test form as a sort of "service sandbox", to allow more interaction.

The ServiceTestForm keeps its own thread going, sort of like the system service manager. The difference here is that your service may not run as a system user. EventLog may not behave as expected either. It would be wise to use the static EventLog.WriteEntry instead of your EventLog instance.

Using the code

The code uses Anthony Roach’s C# Scheduler service as an example. To apply your own service, copy the embedded class ServiceTestForm into your class, and use the Main below. The form allows you to set breakpoints anywhere, including custom commands. Remember that command IDs below 128 are reserved for system commands.

C#
static void Main()
{
   #if DEBUG
      System.Windows.Forms.Application.Run(
         new ServiceTestForm(new ScheduleService()));
   #else
      System.ServiceProcess.ServiceBase.Run(
         new System.ServiceProcess.ServiceBase[] { new ScheduleService() });
   #endif
}

Points of interest

At first, I thought it would be nice to override ServiceBase.EventLog properties in another preprocessor directive. Maybe it could redirect EventLog entries to the TextBox, but it turns out EventLog.WriteLine isn't virtual. If anybody has a better solution to this, please forumize it and Zip me an email.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Founder
United States United States
John Boero is a C# and graphics hobbyist. Some discoveries are too good to be kept closed, and deserve to be given back to the open community that has provided so much already.

Comments and Discussions

 
GeneralMoving ServiceTestForm outside the service class Pin
Mike Lang31-Aug-07 10:41
Mike Lang31-Aug-07 10:41 
I made a few changes for my use that others may find useful.

1) make the ServiceTestForm a standalone class rather than a subclass of your service.
2) Instead of declaring my custom service type in the form, use ServiceBase.
3) Added a reflection helper method to invoke members on the service (see below). This is because OnStart, OnStop, etc... are all protected methods they cannot be called from an outside class (which is I assume why you had this form as an child class to your service.
4) add another conditional compilation around the entire ServiceTestForm. This removes more code from the release version of the service.

        <br />
        void InvokeServiceMember(string name)<br />
        {<br />
            InvokeServiceMember(name, null);<br />
        }<br />
        void InvokeServiceMember(string name, object args)<br />
        {<br />
            InvokeServiceMember(name, new object[] { args });<br />
        }<br />
        void InvokeServiceMember(string name, object[] args)<br />
        {<br />
            Type serviceType = service.GetType();<br />
<br />
            serviceType.InvokeMember(name,<br />
                System.Reflection.BindingFlags.Instance<br />
                | System.Reflection.BindingFlags.InvokeMethod<br />
                | System.Reflection.BindingFlags.NonPublic<br />
                | System.Reflection.BindingFlags.Public,<br />
                null,<br />
                service,<br />
                new object[] { args });<br />
        }


Update the State property setter where the commands are called:
InvokeServiceMember("OnPause");<br />
  InvokeServiceMember("OnStart", new string[] {""});<br />
  InvokeServiceMember("OnContinue");<br />
  InvokeServiceMember("OnStop");


Michael Lang
(versat1474)
http://www.xquisoft.com/[^]

GeneralAutomated Interface, rather than a one-off Pin
Anderson Imes22-Aug-07 13:56
Anderson Imes22-Aug-07 13:56 
QuestionWhy not to use ServiceController? Pin
HDV18-Jul-06 21:22
HDV18-Jul-06 21:22 
AnswerRe: Why not to use ServiceController? Pin
HDV18-Jul-06 22:35
HDV18-Jul-06 22:35 
GeneralYup... Pin
John Boero19-Jul-06 3:08
John Boero19-Jul-06 3:08 
GeneralThanks! Pin
Herman Chelette11-Jul-06 2:14
Herman Chelette11-Jul-06 2:14 
Generalexcellent Pin
andrewcates7-Jul-06 5:02
andrewcates7-Jul-06 5:02 

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.