trilson86
trilson86

Reputation: 1009

Enumerating open windows from a Windows Service

I would like to enumerate child windows of a given process to check for dialog windows. For reasons I won't go into here, if it finds any, I'd like to subsequently kill that application.

Running a standalone application to do this works without any issues. The application has access (via some P/Invoke calls) to a process's windows and I can subsequently kill that application.

Running the same code as a service, however, does not work as expected. It seems that the user running the service is not able to interact with the desktop (which is a setting I can only see for the LOCAL system account).

Does anyone know of any workarounds to this? Is it possible for me to enumerate a process's windows from a windows service?

FYI -- the code (at least an adaptation of) I'm using is available here: https://stackoverflow.com/a/1405088/2115261

Upvotes: 2

Views: 955

Answers (3)

Harry Johnston
Harry Johnston

Reputation: 36308

You can only enumerate windows on the same terminal services session (aka Remote Desktop session) as your process. However, given appropriate privilege, you can launch a subprocess in another terminal services session to do the work on your behalf, although you need to be aware of the potential security issues depending on how you do this.

Assuming that you've already got a handle to the target process, the simplest approach would be to use OpenProcessToken to get a token in the target session, DuplicateTokenEx to duplicate it, and CreateProcessAsUser to launch the subprocess. Since all you need is a yes/no answer, you can use the process exit code rather than needing an IPC mechanism.

Security implications: since your subprocess is running in the user's context, a knowledgeable user could prevent it from running properly. Also, if you do use an IPC mechanism, you'd have to treat the input from the subprocess as untrusted (check for buffer overruns, etc.).

An alternative approach would be to launch a subprocess in your own context but in the target session. IIRC, you can do this by duplicating your own token and using SetTokenInformation on the duplicate to change TokenSessionId before launching the subprocess with CreateProcessAsUser.

Security implications: the subprocess, and through it the service process and the service account, could be subject to shatter attacks (malicious window messages) and other risks, although the integrity level mechanism may mitigate this to some extent. It is my understanding that creating a separate window station and desktop (with appropriate ACLs) eliminates these risks, but I'm not sure offhand of the impact on the code you want to run. Another mitigation would be to use CreateRestrictedToken to remove all groups and privileges from the token before launching the subprocess.

Unless it is absolutely essential that the user not be able to subvert your ability to detect the existence of the dialog window, I strongly recommend the first approach.

Upvotes: 1

Matthew Watson
Matthew Watson

Reputation: 109537

If you give the service a local system account to log on with, you will be able to tick the "Allow service to interact with desktop" checkbox in the service's properties (from Service Control Manager).

See the "Log On" tab of the Service's Property Pages.

That might work for you. But unfortunately, it probably won't. Still worth a quick try?

Upvotes: 0

Roger Rowland
Roger Rowland

Reputation: 26259

You're probably running Windows 7 (or 8 or Vista), because the ability for Windows Servcies to interact with the desktop was last supported in Windows XP.

There is a white paper on MSDN that describes the changes made for Vista and upwards. Basically, it is now not possible to interact with the desktop in any way.

However, there is an example on CodeProject that demonstrates how to interact with the Task Scheduler from a Windows Service, and the process executed by the Task Scheduler can interact with the desktop. Perhaps this would be a suitable workaround for you.

Upvotes: 3

Related Questions