System Tray Icon with Windows Service
Greetings,
I've been able to place an icon in the System Tray with my Windows Form but am unable to use the same code in my Windows Service, any thoughts?
Thanks,
--Mike
notifyIcon = new NotifyIcon();
notifyIcon.Text = "CodeOne SS";
notifyIcon.Icon = new Icon("c:\\WINDOWS\\HRB.ico");
notifyIcon.Visible = true;
Re: System Tray Icon with Windows Service
Why would you put a NotifyIcon in a Windows Service?
Services usually do not have any interface, why do you want to add an interface to them?
Re: System Tray Icon with Windows Service
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.
Re: System Tray Icon with Windows Service
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.
--Mike
1 Attachment(s)
Re: System Tray Icon with Windows Service
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.
Code:
this.Bounds = new Rectangle(-this.Width * 2, -this.Height * 2, 1, 1);
I'm including a project which should show you how to do it.
This includes code to allow InstallUtil to set the "interact with desktop" setting properly.
Darwen.
2 Attachment(s)
Re: System Tray Icon with Windows Service
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 :D
Hmmm, I feel like an article possibility coming on here.
Darwen.
Re: System Tray Icon with Windows Service
Excellent, works great. I like to idea of a forms app that monitors the service(s). Thanks again.
Re: System Tray Icon with Windows Service
Hello
I took your VS2005 project (thanks! it's exactly what i was looking for) and converted it in VS2008.
On XP it works great I can use it in Debug and install it, all ok( can see the Notify Icon and use it to show and hide the window).
But when I install the Service on Vista it starts but the Notify Icon doesn't appears. Maybe you know the reason?
Thanks for advance.
Re: System Tray Icon with Windows Service
Quote:
Originally Posted by Yolk_gf
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).
Re: System Tray Icon with Windows Service
I love writing stuff which people don't read :
Quote:
it might not work under .NET 2.0 or under Windows Vista
and
Quote:
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.
Darwen.