public static void StartAsActiveUser(this Process process) { // Sanity check. if (process.StartInfo == null) { throw new InvalidOperationException("The StartInfo property must be defined"); } if (string.IsNullOrEmpty(process.StartInfo.FileName)) { throw new InvalidOperationException("The StartInfo.FileName property must be defined"); } // Retrieve the active session ID and its related user token. var sessionId = Kernel32.WTSGetActiveConsoleSessionId(); var userTokenPtr = new IntPtr(); if (!WtsApi32.WTSQueryUserToken(sessionId, out userTokenPtr)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Duplicate the user token so that it can be used to create a process. var duplicateUserTokenPtr = new IntPtr(); if (!AdvApi32.DuplicateTokenEx(userTokenPtr, AdvApi32.MAXIMUM_ALLOWED, null, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, TOKEN_TYPE.TokenPrimary, out duplicateUserTokenPtr)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Create an environment block for the interactive process. var environmentPtr = new IntPtr(); if (!UserEnv.CreateEnvironmentBlock(out environmentPtr, duplicateUserTokenPtr, false)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Create the process under the target user’s context. var processFlags = CREATE_PROCESS_FLAGS.NORMAL_PRIORITY_CLASS | CREATE_PROCESS_FLAGS.CREATE_NEW_CONSOLE | CREATE_PROCESS_FLAGS.CREATE_UNICODE_ENVIRONMENT; var processInfo = new PROCESS_INFORMATION(); var startupInfo = new STARTUPINFO(); startupInfo.cb = Marshal.SizeOf(startupInfo); if (!AdvApi32.CreateProcessAsUser ( duplicateUserTokenPtr, process.StartInfo.FileName, process.StartInfo.Arguments, null, null, false, processFlags, environmentPtr, null, ref startupInfo, out processInfo )) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Free used resources. Kernel32.CloseHandle(processInfo.hProcess); Kernel32.CloseHandle(processInfo.hThread); if (userTokenPtr != null) { Kernel32.CloseHandle(userTokenPtr); } if (duplicateUserTokenPtr != null) { Kernel32.CloseHandle(duplicateUserTokenPtr); } if (environmentPtr != null) { UserEnv.DestroyEnvironmentBlock(environmentPtr); } }