In actual fact this is very very difficult to do with a .NET service as it doesn't have a windows message loop - which is required for a tray icon.
It's better to have a seperate winforms application with a tray icon which communicates with the service and provides features such as start/stop etc. This is how MSDE does it for instance.
Darwen.
www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.
Thanks for te reply. I have a requirement from my customer that wants to visually know when/if the service is running. I don't want to deploy another app to my client PCs to just monitor my service; there must be a better way.
After some investigation the easiest way of doing this is to have a seperate thread which calls System.Windows.Forms.Application.Run on a form with a notify icon attached.
You'll need to change the service settings to allow "interact with desktop" as well as adding the System.Windows.Forms.dll to your service as a reference.
Example :
Code:
public class WindowsMessageLoopThread
{
private Thread _thread = null;
private AutoResetEvent _startedEvent = new AutoResetEvent(false);
private Form1 _form = null;
public WindowsMessageLoopThread()
{
_thread = new Thread(new ThreadStart(ThreadFunction));
_thread.Start();
_startedEvent.WaitOne();
}
public void Stop()
{
_form.BeginInvoke(new MethodInvoker(_form.Close));
_thread.Join();
}
private void ThreadFunction()
{
_startedEvent.Set();
_form = new Form1();
System.Windows.Forms.Application.Run(_form);
}
}
You should instansiate this class in the OnStart method of your service class (it should be a member of this class) and call Stop in the OnStop method.
To make the form invisible I usually move it to off the screen and make it invisible in the taskbar e.g.
I've modified the service code so that it survives the user logging off and logging back in again.
See, I told you this wasn't easy... aren't I nice guy investigating all of this for you ?
Basically you need to handle both the Microsoft.Win32.SystemEvents.SessionEnding and the Microsoft.Win32.SystemEvents.SessionEnded events to re-start the UI thread.
This is dangerous - it might not work under .NET 2.0 or under Windows Vista, but it seems to work ok for XP and .NET 1.1.
My preferred route, and the one I would normally use in my job, is to have a seperate monitoring application which is run at startup of a user login.
You wanted this though and I've taken it as far as I can do.
Edit: Just tried it under VS2005 and it works fine... wow
Hmmm, I feel like an article possibility coming on here.
Darwen.
Last edited by darwen; April 17th, 2006 at 04:13 PM.
www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.
But when I install the Service on Vista it starts but the Notify Icon doesn't appears. Maybe you know the reason?
The 'interact with the desktop' service setting was a security hole. As such Microsoft dropped support for this on Vista and newer OS's.
To get around this problem you can create a separate tray icon application that gets started when the user logs on. The tray icon app communicates with the service using a WCF service (which can be hosted within the Windows service).
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.