internal static extern bool CreateProcessAsUser( IntPtr hToken, string lpApplicationName, string lpCommandLine, [In, Out] _SecurityAttributes lpProcessAttributes, [In, Out] _SecurityAttributes lpThreadAttributes, bool bInheritHandles, ProcessCreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In, Out] _StartupInfo lpStartupInfo, [Out] _ProcessInformation lpProcessInformation);
private static Process _LaunchProcessAsUser(string fileName, IntPtr token, IntPtr envBlock, out IntPtr hStdIn, out IntPtr hStdOut, out IntPtr hStdError) { var _saProcess = new _SecurityAttributes { nLength = Marshal.SizeOf(typeof(_SecurityAttributes)) }; var _saThread = new _SecurityAttributes { nLength = Marshal.SizeOf(typeof(_SecurityAttributes)) }; var _pi = new _ProcessInformation(); var _si = new _StartupInfo { cb = Marshal.SizeOf(typeof(_StartupInfo)), lpDesktop = @"WinSta0\Default", wShowWindow = SW.Hide, dwFlags = StartFlags.UseShowWindow | StartFlags.UseStdHandles }; ImpersonationUtils._CreatePipe(out _si.hStdInput, out hStdIn); if (!Win32.SetHandleInformation(_si.hStdInput, HandleFlags.Inherit, HandleFlags.Inherit)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "SetHandleInformation failed."); } ImpersonationUtils._CreatePipe(out hStdOut, out _si.hStdOutput); if (!Win32.SetHandleInformation(_si.hStdOutput, HandleFlags.Inherit, HandleFlags.Inherit)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "SetHandleInformation failed."); } ImpersonationUtils._CreatePipe(out hStdError, out _si.hStdError); if (!Win32.SetHandleInformation(_si.hStdError, HandleFlags.Inherit, HandleFlags.Inherit)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "SetHandleInformation failed."); } if (!Win32.CreateProcessAsUser(token, null, fileName, _saProcess, _saThread, true, ProcessCreationFlags.CreateUnicodeEnvironment, envBlock, null, _si, _pi)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "CreateProcessAsUser failed."); } Win32.CloseHandle(_pi.hProcess); Win32.CloseHandle(_pi.hThread); Win32.CloseHandle(_si.hStdInput); Win32.CloseHandle(_si.hStdOutput); Win32.CloseHandle(_si.hStdError); return(Process.GetProcessById(_pi.dwProcessId)); }