简体   繁体   中英

Process Started using “CreateProcessAsUser” behaves differently than interactive launched process

When launched via CreateProcessAsUser api the embedded webbrowser control within the launched application throws an error "The file could not be written to the cache" when right clicking and selecting "save target as" on certain links within the browser control.

The CreateProcessAsUser call is being made from within a service as part of the OnStart() function. It retrieves the handle for the current user session by enumerating all sessions and checking the state for "WTS_CONNECTSTATE_CLASS.WTSActive"

Launching the exact same executable via double click I am able to download the files without issue.

I've verified that the launched process is running under the same user account via task manager details as well as via System.Security.Principal.WindowsIdentity.GetCurrent().Name.

I've tried running the service using the interactive logon account; doing so prevents the service from being able to launch any executable using the CreateProcessAsUser function. Processes started using System.Diagnostics.Process.Start() are on session 0 and hidden from the interactive desktop and are unable to access any network resources.

I've also tried using System.Diagnostics.Process with user credentials passed via StartInfo, however I get "Access Denied" when calling Start().

 if (WTSEnumerateSessions(
                (IntPtr)WTS_CURRENT_SERVER_HANDLE,  // Current RD Session Host Server handle would be zero.
                0,                                  // This reserved parameter must be zero.
                1,                                  // The version of the enumeration request must be 1.
                ref ppSessionInfo,                  // This would point to an array of session info.
                ref SessionCount                    // This would indicate the length of the above array.
                ))
            {
                for (int nCount = 0; nCount < SessionCount; nCount++)
                {
                    // Extract each session info and check if it is the 
                    // "Active Session" of the current logged-on user.
                    WTS_SESSION_INFO tSessionInfo = (WTS_SESSION_INFO)Marshal.PtrToStructure(
                        ppSessionInfo + nCount * Marshal.SizeOf(typeof(WTS_SESSION_INFO)),
                        typeof(WTS_SESSION_INFO)
                        );

                    if (WTS_CONNECTSTATE_CLASS.WTSActive == tSessionInfo.State)
                    {
                        IntPtr hToken = IntPtr.Zero;
                        if (WTSQueryUserToken(tSessionInfo.SessionID, out hToken))
                        {
                            // Launch the child process interactively 
                            // with the token of the logged-on user.
                            PROCESS_INFORMATION tProcessInfo;
                            STARTUPINFO tStartUpInfo = new STARTUPINFO();
                            tStartUpInfo.cb = Marshal.SizeOf(typeof(STARTUPINFO));

                            bool ChildProcStarted = CreateProcessAsUser(
                                hToken,             // Token of the logged-on user.
                                ChildProcName,      // Name of the process to be started.
                                Args,               // Any command line arguments to be passed.
                                IntPtr.Zero,        // Default Process' attributes.
                                IntPtr.Zero,        // Default Thread's attributes.
                                false,              // Does NOT inherit parent's handles.
                                0,                  // No any specific creation flag.
                                null,               // Default environment path.
                                workingDirectory,   // Default current directory.
                                ref tStartUpInfo,   // Process Startup Info. 
                                out tProcessInfo    // Process information to be returned.
                                );

I expect the behavior of the program launched using the above code to be the same as if it were started interactively from the desktop session - and aside from the webbrowser control and urlmon behaviors it appears to be identical.

Per the suggestion from RbMm, I modified the call to include the environment pointer, lpDesktop specification and the CREATE_UNICODE_ENVIRONMENT flag

                            STARTUPINFO tStartUpInfo = new STARTUPINFO();
                            tStartUpInfo.lpDesktop = "winsta0\\default";
                            tStartUpInfo.cb = Marshal.SizeOf(typeof(STARTUPINFO));
                            IntPtr environment = IntPtr.Zero;
                            if (!CreateEnvironmentBlock(out environment, hToken, true))
                            {
                                environment = IntPtr.Zero;
                                throw new Exception("No Environment");
                            }

                            bool ChildProcStarted = CreateProcessAsUser(
                                hToken,             // Token of the logged-on user.
                                ChildProcName,      // Name of the process to be started.
                                Args,               // Any command line arguments to be passed.
                                IntPtr.Zero,        // Default Process' attributes.
                                IntPtr.Zero,        // Default Thread's attributes.
                                false,              // Does NOT inherit parent's handles.
                                0x00000400,         // CREATE_UNICODE_ENVIRONMENT creation flag.
                                environment,        // Default environment path.
                                workingDirectory,   // Default current directory.
                                ref tStartUpInfo,   // Process Startup Info. 
                                out tProcessInfo    // Process information to be returned.
                                );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM