public static System.Diagnostics.Process StartProcessWithToken(IntPtr token, string appName, string cmdLine) { IntPtr environmentBlock = IntPtr.Zero; try { // Default nil security attribute SafeNativeMethods.SECURITY_ATTRIBUTES defSec = new SafeNativeMethods.SECURITY_ATTRIBUTES(); defSec.nLength = Marshal.SizeOf(defSec); defSec.lpSecurityDescriptor = IntPtr.Zero; defSec.bInheritHandle = 0; // Create an environment block if (!SafeNativeMethods.CreateEnvironmentBlock(ref environmentBlock, token, false)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "CreateEnvironmentBlock"); } // Now we can finally get into the business at hand and setup our process info SafeNativeMethods.STARTUPINFO startInfo = new SafeNativeMethods.STARTUPINFO(); startInfo.cb = Marshal.SizeOf(startInfo); startInfo.wShowWindow = 0; startInfo.lpDesktop = "Winsta0\\Default"; // TBD: Support other desktops? SafeNativeMethods.PROCESS_INFORMATION procInfo = new SafeNativeMethods.PROCESS_INFORMATION(); if (!SafeNativeMethods.CreateProcessAsUser(token, appName, cmdLine, ref defSec, ref defSec, false, SafeNativeMethods.CREATE_UNICODE_ENVIRONMENT, environmentBlock, null, ref startInfo, out procInfo)) { int lastError = Marshal.GetLastWin32Error(); throw new Win32Exception(lastError, "CreateProcessAsUser"); } // We made it, process is running! Closing our handles to it ensures it doesn't orphan, // then we just use its pid to return a process object SafeNativeMethods.CloseHandle(procInfo.hProcess); SafeNativeMethods.CloseHandle(procInfo.hThread); return(System.Diagnostics.Process.GetProcessById((int)procInfo.dwProcessId)); } finally { SafeNativeMethods.CloseHandle(environmentBlock); } }
public static System.Diagnostics.Process StartProcessWithToken(IntPtr token, string cmdLine) { IntPtr environmentBlock = IntPtr.Zero; try { // Default nil security attribute SafeNativeMethods.SECURITY_ATTRIBUTES defSec = new SafeNativeMethods.SECURITY_ATTRIBUTES(); defSec.nLength = Marshal.SizeOf(defSec); defSec.lpSecurityDescriptor = IntPtr.Zero; defSec.bInheritHandle = 0; // Create an environment block if (!SafeNativeMethods.CreateEnvironmentBlock(ref environmentBlock, token, false)) throw new Win32Exception(Marshal.GetLastWin32Error(), "CreateEnvironmentBlock"); // Now we can finally get into the business at hand and setup our process info SafeNativeMethods.STARTUPINFO startInfo = new SafeNativeMethods.STARTUPINFO(); startInfo.cb = Marshal.SizeOf(startInfo); startInfo.wShowWindow = 0; startInfo.lpDesktop = "Winsta0\\Default"; // TBD: Support other desktops? SafeNativeMethods.PROCESS_INFORMATION procInfo = new SafeNativeMethods.PROCESS_INFORMATION(); if (!SafeNativeMethods.CreateProcessAsUser(token, null, cmdLine, ref defSec, ref defSec, false, SafeNativeMethods.CREATE_UNICODE_ENVIRONMENT, environmentBlock, null, ref startInfo, out procInfo)) { int lastError = Marshal.GetLastWin32Error(); throw new Win32Exception(lastError, "CreateProcessAsUser"); } // We made it, process is running! Closing our handles to it ensures it doesn't orphan, // then we just use its pid to return a process object SafeNativeMethods.CloseHandle(procInfo.hProcess); SafeNativeMethods.CloseHandle(procInfo.hThread); return System.Diagnostics.Process.GetProcessById((int)procInfo.dwProcessId); } finally { SafeNativeMethods.CloseHandle(environmentBlock); } }