Click here to Skip to main content
15,885,216 members
Articles / High Performance Computing / Parallel Processing
Article

General Windows Service: Debugged as Console Application and Managed with System Tray

Rate me:
Please Sign up or sign in to vote.
4.90/5 (43 votes)
11 Mar 2014CPOL7 min read 48K   2.9K   87   11
General solution for the Windows service: run as console for debugging, self-installing and -uninstalling, providing description, queuing and processing of messages, status observation and control with icon in system tray. The code may be reused for virtually any Windows service.

Introduction

.NET Windows service is one of the most popular types of the Windows projects. And yet Visual Studio offers an inconvenient template for it. The main problem with this template in my opinion is that generated code cannot run as console application for convenient debugging. But this is not the only problem. Dealing with Windows service, the developer normally needs to implement a more adequate thread model than the provided by the Visual Studio template. It would be also nice to manage the service and see its current status with icons and pop-up menu in the system tray. This article and code will address all these problems.

Background

As it was stated above, good practice of using Windows service implies collaboration of the service itself with its control from the system tray. Since windows service does not have visual aspect (and in fact even runs in different from normal applications desktop) another application should ensure proper indication of the service current status in system tray. In our sample this additional application is written in WPF. Normally this additional "tray-targeted" application is running in the same machine with the Windows service. Thus dual WCF with IPC (net.pipe) binding seems to be a natural choice for communication between the two processes where Windows service acts as a server.

Many developers (including me) particularly like when code intending to solve practical problems can be reused easily. For most of the practical cases the entire code provided in this article may be used almost as it is (changing text variables and names of modules only) with just few places to put specific Windows service functionality. All places in the SampleWinService project that may require changes are placed in appropriate regions entitled DIFFERS FOR EACH SERVICE.

User interface of the tray-target application provides appropriate icon indicating current status of the service and pop-up menu which in activated by mouse right click over the icon:

  • Service is not running

    Image 1

    Image 2


  • Service is running

    Image 3

    Image 4

Please note that icon indicating current service state is updated with certain delay after the service state has been changed.

Design

The Windows service SampleWinService possesses the following features:

  • Capable of running either as console application or as Windows service,

  • Being used as Windows service enables self-installing and self-uninstalling,

  • Act as server for "useful" clients and WPF tray-targeted application by hosting WCF dual service object,

  • Provide command-based working paradigm operating as following. Client application sends commands via WCF communication. The commands are queued by WCF service object to command queue. Commands are dequeued and processed by a dedicated working thread running in a loop. Result of the processing is sent to the calling useful client (if required), whereas current Windows service status is sent to the WPF tray-targeted application. Both result and status are sent as callbacks using WCF dual mechanism. Dual WCF is particularly useful in cases when number of useful clients in not very high and they reside within the same LAN with the service machine. Normally the tray-targeted application runs in the same machine with Windows service. So in this case dual WCF with IPC (net.pipe) binding is also a good choice for communication.

In our sample, external applications providing commands cause the service to perform useful work. In real life there can be also other sources of useful command, such as input from hardware, drivers, timers, etc.

Design of our SampleWinService is based on the following reasonable suppositions:

  • Tray-targeted GUI application runs in the same machine with the service,

  • Limited number of clients of the Windows service, and

  • No firewall between the service and all its clients.

The first supposition allows tray-targeted application to use asynchronous notification about changes in the service status provided by the System.Management.ManagementEventWatcher class. The second and the third suppositions justify usage of dual WCF service. Of course, the above suppositions are not mandatory and are made just for simplicity. We will briefly review other cases below, in the Discussion chapter of this article.

Block-diagram of the system is depicted below:

Image 5

Windows Service

Windows service contains WCF service object which accepts calls from useful clients and tray-target client sending commands to the service. The WCF part is implemented in ComminicationSvc project in the Libraries\ServiceLibs folder. Interface

ICommSvc
allows clients to send commands of type Cmd to the service. The interface is implemented by type
CommSvc
. The class
Cmd
contains command name and parameters, as well as information about client who sent the command. Interface ICallback constitutes contract for clients' callback. For client convenience the WCF service supports three endpoints for CommunicationSvc.ICommSvc contract with netNamedPipeBinding, netTcpBinding and wsDualHttpBinding bindings.

Since, according to the above suppositions, our Windows service does not have too many clients and the clients are available for back notification, the service can process clients' commands in a separate worker thread running in a loop. Project CommunicationSvc provides singleton the class CommandQueue<T> for synchronized command queue parameterized with the Cmd command type. The method CommSvc.Command() inqueues incoming commands for processing. Dequeueing and processing of the commands are performed in the main Windows service process SampleWinService. Unnamed method of type PeriodicProcessingDelegate in WorkerThread.StartThread() dequeues commands and processes them with static method CommandProcessor.Process(). This method is responsible for actual processing of commands. It is the only part of the service which varies according to actual task of the given Windows service. After processing methods SendStatusToAllClients() and SendReport() of class SampleWinSvc send status and result of processing to clients as asynchronous callbacks.

Clients

Both tray-targeted and useful clients use client part (proxy) of WCF. To share the same code between different types of clients, it is placed in a separate assembly ClientLib. In addition, tray-targeted client uses specific NotifyIconWpf assembly developed by Philipp Sumi ([1], www.hardcodet.net) providing infrastructure for tray icon and pop-up menu in WPF applications. Both tray-targeted and useful clients implement interface

ICommSvcCallback 
(corresponds to
ICallback 
interface on the server side) to receive notification calls from the service. Interestingly enough, in some cases the tray-targeted GUI application may be used even in stead of Windows service, e. g. when you need to run this application to capture a screenshot which is not possible for Windows service running in different desktop, or just for the sake of simplicity in for non-mission-critical tasks.

Code Sample

In our sample Windows service is presented with SimpleWinService project, and projects IconClient and TestClient represent icon-targeted and useful clients respectively.

Demo

To run demo we have to perform self-registration of the SimpleWinService Windows service. Run file SimpleWinService_Install.cmd (which starts SimpleWinService.exe with argument /install) for this purpose. Than start IconClient.exe and use tray icon and connected to it pop-up menu to control SimpleWinService Windows service and observe its status.

Discussion

Design described above is applicable to many practical cases of usage Windows services. In case of firewall between the service and its client in stead of dual WCF other approaches may be used, like for instance technique of "smart polling" (described e. g. in [2]) when sever holds client's repeatable polling calls on waitable object until either notification about the server event needs to be send to client or certain timeout elapsed. More sophisticated messages queuing and processing mechanism may be taken e. g. from [3].

Conclusions

This article presents solutions for Windows service general design by providing uniform technique for such widely desirable features as possibilities to run it as console application to facilitate debugging, self-installing and -uninstalling, providing description, queuing and processing of messages, as well as the service status observation and control with icon and pop-up menu placed in the system tray. The code accompanying this article may be reused almost as is (with just minor changes at few places marked in code by a specific regions) as a template for virtually any Windows service. I do hope that my fellows CodeProjecteers will find it useful when it comes to Windows service developing.

References

[1] Philipp Sumi. WPF NotifyIcon. CodeProject.
[2] Igor Ladnik. Push Messages in RESTful WCF Web Application with Comet Approach. CodeProject.
[3] Igor Ladnik. Tiny Framework for Parallel Computing. CodeProject.

License

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


Written By
Software Developer (Senior)
Israel Israel


  • Nov 2010: Code Project Contests - Windows Azure Apps - Winner
  • Feb 2011: Code Project Contests - Windows Azure Apps - Grand Prize Winner



Comments and Discussions

 
QuestionHow to launch iconClient with Administrators rights when the user does not have admin rights Pin
rgates5924-Feb-18 14:31
rgates5924-Feb-18 14:31 
GeneralThanks for sharing your efforts with everyone. Pin
George Peters14-May-15 2:52
professionalGeorge Peters14-May-15 2:52 
GeneralRe: Thanks for sharing your efforts with everyone. Pin
Igor Ladnik14-May-15 5:57
professionalIgor Ladnik14-May-15 5:57 
QuestionRights issues... Pin
Thesisus25-May-14 15:18
Thesisus25-May-14 15:18 
After installing the service with admin rights I am unable to control the service via the systray application. Right clicking and running IconClient as Admin results in "A referral was returned from the server." which I assume to mean access denied. Just double clicking and running IconClient normally starts the app and allows me to see it in the systray but attempting to start or stop the service causes a fatal error.

Any ideas?

Thanks
Fear not my insanity, fear the mind it protects.

AnswerRe: Rights issues... Pin
Igor Ladnik14-May-15 5:59
professionalIgor Ladnik14-May-15 5:59 
SuggestionHTTP exception and getting rights to host a HTTP service Pin
Niels Peter Gibe21-Apr-14 22:55
Niels Peter Gibe21-Apr-14 22:55 
GeneralRe: HTTP exception and getting rights to host a HTTP service Pin
Igor Ladnik14-May-15 5:59
professionalIgor Ladnik14-May-15 5:59 
QuestionClient projects incompatible with VS2010? Pin
Dave Cross17-Mar-14 5:03
professionalDave Cross17-Mar-14 5:03 
AnswerRe: Client projects incompatible with VS2010? Pin
Igor Ladnik17-Mar-14 6:51
professionalIgor Ladnik17-Mar-14 6:51 
SuggestionVery good idea Pin
Daniele Alberto Galliano17-Mar-14 0:12
professionalDaniele Alberto Galliano17-Mar-14 0:12 
GeneralRe: Very good idea Pin
Igor Ladnik17-Mar-14 4:16
professionalIgor Ladnik17-Mar-14 4:16 

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.