public static bool CreateProcessAsSystem(string ApplicationName, int Session, string Desktop, bool Hidden, WinAPI.PROCESS_PRIORITY Priority, bool Suspended, out WinAPI.ProcessInformation ProcInfo) { ProcInfo = new WinAPI.ProcessInformation(); IntPtr hToken = IntPtr.Zero; var phandle = WinAPI.OpenProcess(WinAPI.ProcessAccess.All, false, (uint)Process.GetCurrentProcess().Id); try { WinAPI.OpenProcessToken(phandle, (int)WinAPI.TokenAccess.All, ref hToken); } catch { return(false); } try { IntPtr hDupToken; WinAPI.DuplicateTokenEx(hToken, WinAPI.TokenAccess.All, IntPtr.Zero, WinAPI.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, WinAPI.TokenType.Primary, out hDupToken); Marshal.Release(hToken); hToken = hDupToken; } catch { return(false); } var sessPtr = new IntPtr(Session); WinAPI.NtSetInformationToken(hToken, WinAPI.TOKEN_INFORMATION_CLASS.TokenSessionId, ref sessPtr, sizeof(int)); var startupInfo = new WinAPI.StartupInfo(); IntPtr environment; WinAPI.CreateEnvironmentBlock(out environment, hToken, false); startupInfo.Desktop = Desktop; //"WinSta0\\Default"; WinAPI.ProcessCreationFlags priorityFlag; if (Priority == WinAPI.PROCESS_PRIORITY.REAL_TIME) { priorityFlag = WinAPI.ProcessCreationFlags.RealtimePriorityClass; } else if (Priority == WinAPI.PROCESS_PRIORITY.HIGH) { priorityFlag = WinAPI.ProcessCreationFlags.HighPriorityClass; } else if (Priority == WinAPI.PROCESS_PRIORITY.IDLE) { priorityFlag = WinAPI.ProcessCreationFlags.IdlePriorityClass; } else { priorityFlag = WinAPI.ProcessCreationFlags.NormalPriorityClass; } try { WinAPI.ClientId clientId; ProcInfo = WinAPI.CreateWin32(hToken, null, ApplicationName, false, WinAPI.ProcessCreationFlags.CreateUnicodeEnvironment | (Hidden ? WinAPI.ProcessCreationFlags.CreateNoWindow : 0x0) | (Suspended ? WinAPI.ProcessCreationFlags.CreateSuspended : 0x0) | priorityFlag, environment, null, startupInfo, out clientId); Marshal.Release(ProcInfo.ProcessHandle); Marshal.Release(ProcInfo.ThreadHandle); } catch { return(false); } finally { WinAPI.RtlDestroyEnvironment(environment); } return(true); }