/// <summary> /// Runs a command. /// </summary> /// <param name="commandFilePath">The command file path.</param> /// <param name="commandArguments">The command arguments.</param> /// <param name="workingDirectory">The working directory.</param> /// <param name="waitForExit">if set to <c>true</c> wait for exit.</param> /// <returns>The launched process.</returns> /// <exception cref="Exception">Create Process failed.</exception> /// <exception cref="Win32Exception">Creation of the process failed.</exception> public Process RunCommand(string commandFilePath, string commandArguments, string workingDirectory, bool waitForExit) { IntPtr token = new IntPtr(0); IntPtr dupedToken = new IntPtr(0); bool ret; SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); sa.bInheritHandle = false; sa.Length = Marshal.SizeOf(sa); sa.lpSecurityDescriptor = (IntPtr)0; token = WindowsIdentity.GetCurrent().Token; const int SecurityImpersonation = 2; const int TokenType = 1; ret = NativeMethods.DuplicateTokenEx(token, (int)TokenAccessRights.AssignPrimary | (int)TokenAccessRights.Duplicate | (int)TokenAccessRights.Query, ref sa, SecurityImpersonation, TokenType, ref dupedToken); if (ret == false) { //NativeMethods.CloseHandle(token); NativeMethods.CloseHandle(dupedToken); throw new Exception(Marshal.GetLastWin32Error().ToString()); } // Load Profile PROFILEINFO pri = new PROFILEINFO(); pri.dwSize = Marshal.SizeOf(pri); pri.lpUserName = _userName; pri.dwFlags = 1; if (!NativeMethods.LoadUserProfile(dupedToken, ref pri) && pri.hProfile == IntPtr.Zero) { NativeMethods.CloseHandle(dupedToken); throw new Exception(Marshal.GetLastWin32Error().ToString()); } // Process Information PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); // Startup Information STARTUPINFO si = new STARTUPINFO(); si.cb = Marshal.SizeOf(si); //if this member is NULL, the new process inherits the desktop //and window station of its parent process. If this member is //an empty string, the process does not inherit the desktop and //window station of its parent process; instead, the system //determines if a new desktop and window station need to be created. //If the impersonated user already has a desktop, the system uses the //existing desktop. si.lpDesktop = null; //si.lpDesktop = ""; //si.lpDesktop = @"WinSta0\Default"; //Modify as needed //si.dwFlags = (uint)STARTF.STARTF_USESHOWWINDOW | (uint)STARTF.STARTF_FORCEONFEEDBACK; //si.wShowWindow = (short)ShowWindowCommands.SW_HIDE; IntPtr environmentBlock = IntPtr.Zero; try { ret = NativeMethods.CreateEnvironmentBlock(ref environmentBlock, token, false); if (ret) { ret = NativeMethods.CreateProcessAsUser(dupedToken, commandFilePath, commandArguments, ref sa, ref sa, false, (int)CREATE_PROCESS_FLAGS.CREATE_UNICODE_ENVIRONMENT, environmentBlock, workingDirectory, ref si, out pi); } } finally { if (environmentBlock != IntPtr.Zero) { NativeMethods.DestroyEnvironmentBlock(environmentBlock); } } Process p = null; if (!ret) { throw (new Win32Exception("Creation of the process failed with " + Marshal.GetLastWin32Error())); } else { try { p = Process.GetProcessById((int)pi.dwProcessId); if (waitForExit) { p.WaitForExit(); } } catch { } NativeMethods.CloseHandle(pi.hProcess); NativeMethods.CloseHandle(pi.hThread); } NativeMethods.UnloadUserProfile(token, pri.hProfile); //NativeMethods.CloseHandle(token); ret = NativeMethods.CloseHandle(dupedToken); if (ret == false) { throw (new Exception(Marshal.GetLastWin32Error().ToString())); } return(p); }
// This is called by AppDomain.GetThreadPrincipal() via reflection. private static IPrincipal GetDefaultInstance() => new WindowsPrincipal(WindowsIdentity.GetCurrent());