1

First off, I know some proper ways of making a truly interactive Windows Service.

The situation is, I do have a tool that does not interact with the user as such. However, it does display non-blocking notifications both via popup windows and via the Windows Notification Area (aka System Tray). It also writes a logfile of the notifications it displays.

This tool is normally spawned by a main user application and as long as the main application is a normal application, these notifications do work as intended.

When this tool is spawned by a Windows Service, no notifications are displayed, naturally. (The Desktop Session for the service isn't visible.) But this would be OK, we have the logfile and these notifications are just - notifications, nothing the user absolutely must see under all circumstances.

The question now becomes: Is a process running in the context of a Service (the Service itself or any process it starts) "allowed" to make Windows API calls that display a visible GUI?

  • Will most Windows API calls (e.g. creating and showing a window, using Shell_NotifyIcon, etc.) behave the same in the invisible session of the service?
  • Or would I have to make sure throughout the source code, that no GUI displaying/modifying stuff is called in the context of the service?

And yes, calling ::MessageBox is a bad idea because it will block. But I can handle these calls.

And yes, this could be designed better, but it's what I have at the moment and it would be nice if I hadn't to rip the whole tool apart to make sure no GUI related code is run in the service.

Martin Ba
  • 37,187
  • 33
  • 183
  • 337
  • A hint in a passing sentence: [The GUI calls will succeed but no GUI will ever be shown.](http://www.brianbondy.com/blog/id/100/) – Martin Ba Jun 28 '13 at 13:28
  • The only way seems to be using WTSEnumerateSessions and CreateProcessAsUser -- see this [SO article](http://stackoverflow.com/a/267866/1850797) – Edward Clements Jun 28 '13 at 14:27
  • @EdwardClements: Thanks for the link. However note that I do *not* need to display the GUI elements when run in a Service context. I just want to know whether *trying* to display non-blocking GUI elements could pose a problem from a Service. – Martin Ba Jun 28 '13 at 14:39
  • 1
    Sorry, my mistake -- I don't think any GDI call will fail (I had an old service which displayed progress messages in a dialog box window, it still runs without errors on Win7/WinServer2008R2, of course without displaying anything) – Edward Clements Jun 28 '13 at 14:56

2 Answers2

2

GUI elements from a Windows Service are shown on Session 0. On Windows XP & 2003, users were allowed to log in to Session 0 and interact normally with the windows created by a service, but Microsoft put a knife in the heart of interactive services in Vista (and beyond) by isolating Session 0.

So, to answer your specific questions:

Is a process running in the context of a Service (the Service itself or any process it starts) "allowed" to make Windows API calls that display a visible GUI? Will most Windows API calls (e.g. creating and showing a window, using Shell_NotifyIcon, etc.) behave the same in the invisible session of the service?

Yes, GUI calls are allowed and should succeed as normal. The only notable exceptions that I know of are those related to tray icons because the process providing the task bar (explorer.exe) is not running in the isolated Session 0.

Or would I have to make sure throughout the source code, that no GUI displaying/modifying stuff is called in the context of the service?

That should not be necessary, though you should proceed cautiously with any GUI interaction from your service. Test thoroughly!

CoreTech
  • 2,345
  • 2
  • 17
  • 24
  • You should avoid presenting UI in a service because you may trigger the UI Detection Service which will switch the user to your service UI temporarily. – Raymond Chen Jun 29 '13 at 06:10
  • @RaymondChen: Please see my analysis of this UI0Detect thing in the other answer: http://stackoverflow.com/a/17400251/321013 -- Am I correct? – Martin Ba Jul 01 '13 at 08:34
0

I would like to provide some info wrt. Raymonds Chen's comment to the other answer

You should avoid presenting UI in a service because you may trigger the UI Detection Service which will switch the user to your service UI temporarily. – Raymond Chen

I find these good articles:

Where one can find explanation on what the UI detection service (UI0Detect) is and does and how it's supposed to work.

Interactive Services Detection (the blinking button on the taskbar) is a mitigation for legacy applications that detects if a service is trying to interact with the desktop. This is handled by the Interactive Services Detection (UI0Detect) service.

However, one must note that this only can work if the service that is trying to view a GUI has the flag "Allow service to interact with desktop" set, because only then the service process will be running on WinSta0of Session0 even allowing it to show anything at all.

Alex Ionescu mentions this:

If UI0Detect.exe ... the SCM has started it at the request of the Window Hook DLL. The service will proceed ... The service first does some validation to make sure it’s running on the correct WinSta0\Default windowstation and desktop and then notifies the SCM of success or failure.

So, to come back to Raymond's comment: As far as I can see, as long as a service doesn't tick the type= interact option (see sc.exe), and normally you don't tick this, the UI0Detect service doesn't do anything and there shouldn't be any "danger" of triggering it.


Note: The information above is based on my limited research and tests on only a single Windows 7 PC.

Community
  • 1
  • 1
Martin Ba
  • 37,187
  • 33
  • 183
  • 337
  • The details of how the UI Detection Service works are all implementation details that are subject to change at any time. Creating UI and hoping that it won't trigger the UI Detection Service is not sound engineering practice because you may elude detection today, but tomorrow things may change. The correct solution is not to display UI at all. – Raymond Chen Jul 01 '13 at 14:33
  • @RaymondChen - I appreciate your concerns here - and you are certainly right in principle. However, *sound engineering practice* also tells me that I shouldn't spend time+energy on something that is extremely unlikely to change -- and given that a service shouldn't be displaying a GUI at all, and the whole UI0Detect thing seems like a legacy clutch, I would be extremely surprised if this would change to display a message where it doesn't today. (And for completeness sake: In my specific case, it would be OK, if not pretty, if it would.) Thanks a lot for your insight! – Martin Ba Jul 02 '13 at 07:02