How to start a process from windows service into currently logged in user's session

The problem with Shrike's answer is that it does not work with a user connected over RDP.
Here is my solution, which properly determines the current user's session before creating the process. It has been tested to work on XP and 7.

https://github.com/murrayju/CreateProcessAsUser

Everything you need is wrapped up into a single .NET class with a static method:

public static bool StartProcessAsCurrentUser(string appPath, string cmdLine, string workDir, bool visible)

A blog on MSDN describes a solution

It's a terrific helpful post about starting a new process in interactive session from windows service on Vista/7.

For non-LocalSystem services, the basic idea is:

  • Enumerate the process to get the handle of the Explorer.

  • OpenProcessToken should give you the access token. Note : The account under which your service is running must have appropriate privileges to call this API and get process token.

  • Once you have the token call CreateProcessAsUser with this token. This token already have the right session Id.


It's a bad idea to do so. Although probably not totally impossible, Microsoft did everything to make this as hard as possible, as it enables so-called Shatter Attacks. See what Larry Osterman wrote about it back in 2005:

The primary reason for this being a bad idea is that interactive services enable a class of threats known as "Shatter" attacks (because they "shatter windows", I believe).

If you do a search for "shatter attack", you can see some details of how these security threats work. Microsoft also published KB article 327618 which extends the documentation about interactive services, and Michael Howard wrote an article about interactive services for the MSDN Library. Initially the shatter attacks went after windows components that had background window message pumps (which have long been fixed), but they've also been used to attack 3rd party services that pop up UI.

The second reason it's a bad idea is that the SERVICE_INTERACTIVE_PROCESS flag simply doesn't work correctly. The service UI pops up in the system session (normally session 0). If, on the other hand, the user is running in another session, the user never sees the UI. There are two main scenarios that have a user connecting in another session - Terminal Services, and Fast User Switching. TS isn't that common, but in home scenarios where there are multiple people using a single computer, FUS is often enabled (we have 4 people logged in pretty much all the time on the computer in our kitchen, for example).

The third reason that interactive services is a bad idea is that interactive services aren't guaranteed to work with Windows Vista :) As a part of the security hardening process that went into Windows Vista, interactive users log onto sessions other than the system session - the first interactive user runs in session 1, not session 0. This has the effect of totally cutting shatter attacks off at the knees - user apps can't interact with high privilege windows running in services.

The proposed workaround would be to use an application in the system tray of the user.

If you can safely ignore the issues and warnings above, you might follow the instructions given here:

Developing for Windows: Session 0 Isolation