views:

351

answers:

7

I understand that Window's Services have no desktop, and can't access any of the user's desktops directly (indeed, they can run when there is no desktop loaded). Why is it though that launching a form in a Window's Service causes an error?

+1  A: 

Because if nobody is going to see the Form, nobody is going to dismiss it - running a modal dialog is a recipe for a hang - so you want it to complain loudly when this happens rather than sit there quietly until you kill the process (or look at a stack trace to determine what'd going on). (The other obvious problem is, who is going to pick the DialogResult if there is more than one possibility?) You want to know when this is happening. (Assert dialogs that dont throw if they cant show anything are a fun way of making people mad.).

In other words, because you want to know when things are confused enough in your code that a dialog is being shown within a service context.

(I'm assuming you're using Windows Forms on .NET, eve though you didnt tag it as such)

(If you have correctly configured things such that the service is allowed to interact with the desktop, you won't get an Exception)

Ruben Bartelink
It is quite possible to interact with a form programmatically even if there is no interactive user.
Stephen Martin
Never thought of that - very good point![In general I was trying to get across the general point that the current impl is a good default for services.(This was the first answer and I'd have written a different one if the others had already been submitted at the time I wrote)]
Ruben Bartelink
My thinking was mainly based on Old Pain re ATLASSERT freezing services :D
Ruben Bartelink
+1  A: 

Ummm... what and whose desktop is that form going to appear on, exactly? A 'desktop' is an operating system concept: each window handle is owned by a specific desktop within a window station belonging to a single (interactive) user. The process within which the service is executing isn't going to find the user's visible desktop in its window station. For a rather dry reference, look at MSDN.

Actually, it's even nastier. You might be able to configure permissions for the service to be able to create a desktop -- but then nobody will see it! Alternatively, you could grant the process the rights to switch desktops, and confuse the heck out of the user!

Pontus Gagge
It will appear in the desktop of the thread that creates it. All threads in Windows NT based OSes are associated with a desktop.
Stephen Martin
OK, right, but a noninteractive window station. Correcting. Correcting.
Pontus Gagge
+1  A: 

A service should run without any user interaction, so there is no need for a form. If a service has to wait around for user feedback then it probably isn't going to be doing what it is supposed to.

Galwegian
A: 

Because at the time when the operating system needs to paint the window there is nothing to draw the form on.

Fabian Vilers
+1  A: 

You have to understand three related concepts: sessions, windows stations and desktops. But because there's a one-to-one relationships between sessions and stations, we can broadly ignore stations for this discussion. A session contains a station (winSta0 being the only interactive station) and stations contain one or more desktops.

Now session architecture differs according to Windows version. For NT <= 5 (XP/2003 and everything before them) services execute in session 0 along with the interactive user's apps. This is why you can configure services to interact with the desktop in these Windows NT versions - they are in the same session. For NT >= 6 (Vista, Server 2008 going forwards), services exists in session 0 but the interactive desktop is in another session. This is what's known as "service hardening", and is basically a security fix.

So since session 0 apps cannot get at the interactive console, it makes no sense for them to attempt to display a user interface of any kind.

Just to make this more confusing, Vista has a temporary kludge to cater for this situation: if an app in session 0 tries to create a dialog, Windows will trap this and present a warning to the user so they switch to a (I presume temporary) desktop where they can interact with the dialog. However this measure is explicitly temporary and you cannot rely upon it being in future Windows releases. I've seen this working in native code, but I suspect you are in managed code and the runtime is being smart enough to catch your behaviour and deliver a metaphorical slap to the hindquarters :-).

Bob Moore
+1  A: 

There's a setting you must enable in order to allow your Windows Service to access certain folders directly (like desktop) or show forms (including MessageBox pop-ups): "Allow service to interact with desktop"

To see this, right click on My Computer => Manage => Services and Applications => Services. Double-click on a service to access its properties. On the "Log On" tab there is a checkbox for this setting.

Here is an article for how to set it programmatically in C#

[Edit] As Stephen Martin points out in the comments: this is only valid advice for pre-Vista versions of Windows.

Dinah
The allow service to interact with the desktop setting has nothing to do with folder access, it no longer works as of Vista and later OSes and is a severe security risk and should never be used in any OS prior to Vista.
Stephen Martin
Fair enough. But "any OS prior to Vista" is kinda misleading. As of today (3-23-09) that means only Vista or the Beta of Windows 7. I, and most people I know, still use XP so I still think this is pretty valid advice. I'll update my post though to make it more clear.
Dinah
The point is that even though you can use it in XP and W2K3, Microsoft and just about everybody else who knows anything about services has been advising against using this setting for more than 10 years now. This setting was introduced for debugging purposes, wasn't supposed to be used live.
Stephen Martin
+1  A: 

When a Windows Service is started it is assigned to a Window Station and Desktop according to well documented, though somewhat obscure rules. As mentioned elsewhere it is not assigned to the interactive desktop (unless it is set to interact with the desktop on a pre-Vista OS) but it definitely runs in a desktop.

It is a common misconception that services cannot use UI elements. In fact many services (such as SQL Server) have in the past used hidden windows and windows messages for thread synchronization and work distribution purposes. There is no reason that a Form cannot be shown in a service. If you are getting an error it is due to something you are doing with the form or some component that is on the form. The most likely issues have to do with whether or not you need an STA thread for your form or are you creating a message pump for your form or something similar.

While you certainly can use a form in a Windows Service you almost certainly shouldn't. There will be threading issues, cross apartment call issues, possible blocking UI issues, etc. There are a very few situations where using a window in a service is a good choice but there is a better way, with no UI, in 99.99% of all cases.

Stephen Martin