Click here to Skip to main content
15,887,244 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
I have a service running in Windows 7. In Windows 7 all services run in Session 0. From that service I want to create an interactive user session (in a session other than Session 0) and start an application in that session. My problem is that when I call LogonUser to start an interactive user session and then use CreateProcessAsUser to start the application the application ends up running in Session 0.

All of my code is C#.

Here is the relevant code:

C#
[DllImport("advapi32.dll", SetLastError=true)]
static extern bool LogonUser(
    string principal,
    string authority,
    string password,
    UInt32 logonType,
    UInt32 logonProvider,
    out    IntPtr token);

[DllImport("advapi32.dll", SetLastError=true)]
static extern bool CreateProcessAsUser(
    IntPtr hToken,
    string lpApplicationName,
    string lpCommandLine,
    IntPtr lpProcessAttributes,
    IntPtr lpThreadAttributes,
    bool bInheritHandles,
    int dwCreationFlags,
    IntPtr lpEnvironment,
    string lpCurrentDirectory,
    ref STARTUPINFO lpStartupInfo,
    ref PROCESS_INFORMATION lpProcessInformation);

IntPtr token;
LogonUser("UserName", ".", "Password", 
    LogonTypes.Interactive,LogonProviders.Default, out token)

<code to impersonate user>
string hd = Environment.ExpandEnvironmentVariables("%USERPROFILE%");

IntPtr envBlock = IntPtr.Zero;
CreateProcessAsUser(token, "PathToMenu.exe",
    NORMAL_PRIORITY_CLASS |CREATE_UNICODE_ENVIRONMENT,
    "WinSta0\\Default", hd, envBlock, "Menu");


Can anyone tell me what I'm doing wrong?
Posted
Updated 14-Feb-17 22:09pm
v2
Comments
Orcun Iyigun 19-Oct-11 11:30am    
Updated the tags.

What are you doing wrong? You're trying to create an interactive process from a service. Not a good idea since what if there is noone logged in at the time? What if there are multiple logged into the machine at the same time?

You could go into the service properties, LogOn tab, and enable "Allow service to interact with desktop", but that isn't going to do what you expect it to on Windows 7 and up.

What you want to do is very strongly discouraged by Microsoft, mostly for security reasons.
 
Share this answer
 
Comments
kenstern 19-Oct-11 13:27pm    
Dave, yeah - I know. Unfortunately I have some rather unique requirements. I'm actually porting this from Win XP (where it works just fine) to Win 7. Also, Microsoft, and my take from lots of searching, is that this is the 'recommended' way to do what I want. Note that there will be a user logged in (we do that just before the call to CreateProcessAsUser) and we use the token returned from that logon to identify the user/session. So ... understanding that this is a slightly underhanded way of doing things ... why doesn't it work?
Dave Kreskowiak 19-Oct-11 14:16pm    
Now you know why Microsoft has been saying DON'T do this. The functionality has been walled off in 7. You can't create an interactive process on the user Desktop from Session 0 for security reasons. Any thing that your service does that requires user interaction will be restricted to showing up on an alternate desktop. The user will, at most, get a notification that a service wants your attention and give you the option of switching the the service desktop to see what's going on. It's called "Session 0 Isolation".

It used to be, prior to 7 (maybe Vista), that services ran in the same Session as the first user to login to the console, Session 0. Since services normally run with elevated privs, it was possible for a malware service to show a UI to the user in the same session. Hence, the rise of Session 0 Isolation.

S0I was designed to protect users from potentially bad service and driver processes as well as the other way around, protecting legit services from potentially hazardous user applications.

Your code previously only worked because services and user apps could run in the same Session, under different Stations. That doesn't happen anymore under 7. Even services tagged as "Allow Interactive" are stuck running under Session 0, completely isolated from Session 1 and above.

You can create new processes, specifying the Window Station and Desktop to run the process under, but you can NOT specify the Session to run under. Even if the Station and Desktop id's are identical, each Session maintains its own table of Stations and Desktops.

Hmmm... Are you passing the users security token to CreateProcess??
Dave Kreskowiak 19-Oct-11 14:31pm    
You can't change which Session a process is created under, but you CAN change the SessionID for a security token. (BIG) IF the service has the "Act As Part Of the Operating System" privilege, it may be able to change a copy of the security token to match the logged on users session ID. Then you can pass the modified token to CreateProcessAsUser.

... in theory anyway. I have no idea if it's going to work or what else has to be done to get to the user to see the process.
fjdiewornncalwe 19-Oct-11 14:04pm    
Absolutely. In order for a "user" application to be executed from a service, the "Allow to interact..." option must be selected. Thankfully I have had other options rather than implementing this on Win7/2008.
Dave Kreskowiak 19-Oct-11 14:20pm    
Yeah, the only problem with doing that is it's interactive all right, just not on the users Window Station. Under 7, the service will run under WinSta0, but a different WinSta0 than the user sees. The service WinSta0 is still stuck in Session 0, which the user won't see.
Dave is completely wrong! As triend said use CreateProcessAsUser

Subverting Vista UAC in Both 32 and 64 bit Architectures[^]
 
Share this answer
 
v3
Comments
CHill60 11-May-17 4:50am    
That article is dated 2009 and is for Vista. Windows has moved on a bit since then and many of the security holes have been filled in. If you read the entire thread you will find...Quote:Now you know why Microsoft has been saying DON'T do this. The functionality has been walled off in 7. You can't create an interactive process on the user Desktop from Session 0 for security reasons
Robson Carvalho Joaquim 11-May-17 12:08pm    
Your statement isn't true. I use the CreateProcessAsUser in window 10 and work flawlessly

Try yourself and come back here to change your comment.

http://download.microsoft.com/download/7/E/7/7E7662CF-CBEA-470B-A97E-CE7CE0D98DC2/Session0Changes.docx
Dave's answer is wrong, just because the question is about starting a process in a user session (session 1 and above) from a service, not presenting a GUI in session 0.

The way to do this is by impersonating the user of a session and then create the process.
Look at:
WTSQueryUserToken to get the user's primary token
ImpersonateLoggedOnUser
CreateProcessAsUser to start a process on the WinSta0\Default desktop
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900