I am writing a windows service that will be doing a lot of network communication, and I need a way to notify a user (if logged on) of any exceptions/errors. I know it is bad practice to allow a service to interact with the desktop, so is there an alternative way to notify a user that an error has occurred? I am aware of event logging, but I would also like to be able to show a notification bubble from the system tray or something that catches the user's attention.
What about using another app to interact with this application and notify the user about the errors? This way you can have "option" to users. May be switch off alerts, email etc
Typically, you'll have a secondary app that the service can notify. For example, you can have a system tray icon (ugh) that pops up balloons (double ugh) when something important occurs. The app itself can then present an interface for settings for your service as well.
Please consider using Event Log and a separate application just for monitoring. You can also consider using emails or MSMQ.
You could make use of some existing notification app like Growl: http://www.growlforwindows.com/gfw/. This would allow the user to "opt in".
You will have to provide an alternative to the "interact with desktop" option. It is no longer supported in Vista and Win7. Giving a restricted user access to an UI that runs on a highly privileged account was considered too great a security risk. Google "session 0 isolation" to find details on this.
You'll need to use one of the process interop mechanisms supported by .NET to setup interaction between your service and a UI app. For simple message passing use either a socket or named pipe. The pipe name needs to have the "Global\" prefix to be visible to all sessions. For more intricate interactions you can use Remoting or WCF.
Be sure to deal with the possibility that the user decides to not run or kill off the desktop app. You should log any error with the EventLog class.
To solve this problem, I've created a Windows Forms application that the user can start and stop at will. Of course, the Windows service is running in the background 24/7. When the application is started, it uses Windows Communication Foundation (WCF) to query the service for it's current status - is it active, how many clients are connected, how many bytes have been collected, etc. This information is then presented to the user inside the application.
I've tried to mimic the behavior of Task Manager, so I've also added a System.Windows.Forms.NotifyIcon
to the main form of the application that displays an icon in the system tray. When the application is open, the system tray icon is shown. The user can minimize the application to the task bar or can hide the application altogether. The tray icon only goes away when the user closes the application. The tray icon also supports double-clicks to re-open the application and a pop-up menu for quick access to functionality.
In any case, the point I want to make is that WCF is the most straightforward way to have your service and front-end application communicate. People will argue about the supposed 'steep' learning curve associated with WCF, but I did not experience that. I find that WCF is a very efficient way to develop inter-process communication. You can watch this video to give you some insight to the WCF programming paradigm.