views:

779

answers:

4

We have to run a process from a windows service and get a screenshot from it.

We tried the BitBlt and PrintWindow Win32 calls, but both give blank (black) bitmaps.

If we run our code from a normal user process, it works just fine.

Is this something that is even possible? Or could there be another method to try?

Things we tried:

  1. Windows service running as Local System, runs process as Local System -> screenshot fails
  2. Windows service running as Administrator, runs process as Administrator -> screenshot fails.
  3. Windows application running as user XYZ, runs a process as XYZ -> screenshot works with both BitBlt or PrintWindow.
  4. Tried checking "Allow service to interact with desktop" from Local System

We also noticed that PrintWindow works better for our case, it works if the window is behind another window.

For other requirements, both the parent and child processes must be under the same user. We can't really use impersonation from one process to another.

+3  A: 

Have you tried to run as Local System with the "Allow service to interact with desktop" checked?

esac
+1 - This is a good idea if it works. It's certainly the only solution I can think of that might.
David Stratton
See above comment.
Jonathan.Peppers
+2  A: 

I don't think this is possible.

We had to change our scenario where our application wasn't started from a service, but was a standard windows program that has a NotifyIcon in the corner.

If someone still finds a real answer, let me know.

Jonathan.Peppers
A: 

It works using Local System with the "Allow service to interact with desktop"

You can set it programatically using this sample code:

http://www.vbforums.com/showthread.php?t=367177 (it's vb.net but very simple)

ufoq
This works only on XP. Not on Vista or 7. And on XP it has two drawbacks: 1. If you enable this you can run into problems by creating network connections within your service. 2. It will only show up at the desktop of the first user logged in. If you make a fast switch to a second user you won't see anything too.
Oliver
Ad.1 Network connections? By making screenshot? Ad.2 Yes you're right, due to Session 0 Isolation it does not work in Vista/7
ufoq
+1  A: 

Currently i can't find the corresponding links, but the problem is, that a windows service runs in another session than a normal user application.

In XP this was not fully true. Here are all services started in Session 0 and the first user who logs into the system will also run in Session 0. So in that case, tricks like Allow service to interact with desktop work. But if you fast switch to another user he gets the Session 1 and has no chance to interact with the service directly. This is also true if you connect through RDP to a server version (like 2003 or 2008). These logins will also start in a session higher than 0.

Last but not least there is another drawback by using the interaction with the desktop:
If you enable this option and your service is running under the (default) SYSTEM account it won't be able to create a network connection anymore.

The correct way to get a custom GUI that works with a service is to separate them into two processes and do some kind of IPC (inter process communication). So the service will startup when the machine comes up and a GUI application will be started in the user session. In that case the GUI can create a screenshot, send it to the service and the service can do with it, whatever you like.

Oliver