// Source: http://ithoughthecamewithyou.com/post/Reboot-computer-in-C-NET.aspx public static void ExitWindowsEx(EXIT_WINDOWS exitMode) { IntPtr tokenHandle = IntPtr.Zero; try { // Get process token if (!OpenProcessToken(System.Diagnostics.Process.GetCurrentProcess().Handle, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, out tokenHandle)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to open process token handle"); } // Lookup the shutdown privilege TOKEN_PRIVILEGES tokenPrivs = new TOKEN_PRIVILEGES(); tokenPrivs.PrivilegeCount = 1; tokenPrivs.Privileges = new LUID_AND_ATTRIBUTES[1]; tokenPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, out tokenPrivs.Privileges[0].Luid)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to open lookup shutdown privilege"); } // Add the shutdown privilege to the process token if (!AdjustTokenPrivileges(tokenHandle, false, ref tokenPrivs, 0, IntPtr.Zero, IntPtr.Zero)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to adjust process token privileges"); } // Perform the exit operation if (!ExitWindowsEx(exitMode, ShutdownReason.MajorApplication | ShutdownReason.MinorInstallation | ShutdownReason.FlagPlanned)) { throw new Win32Exception(Marshal.GetLastWin32Error(), String.Format("Failed to exit the system ({0})", exitMode)); } } finally { // Close the process token if (tokenHandle != IntPtr.Zero) { CloseHandle(tokenHandle); } } }
private static extern bool ExitWindowsEx(EXIT_WINDOWS uFlags, ShutdownReason dwReason);