ExitWindowsEx in C#

I post you my simple class to shutdown, reboot and logoff Windows using the famous ExitWindowsEx.

Each method is overloaded with another that force the action, in other words, it executes the action without prohibiting Windows to send the WM_QUERYENDSESSION message. In this way the user can’t cancel this action.

Here the code:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

static class ExitWindows {

	private struct LUID {
		public int LowPart;
		public int HighPart;
	}
	private struct LUID_AND_ATTRIBUTES {
		public LUID pLuid;
		public int Attributes;
	}
	private struct TOKEN_PRIVILEGES {
		public int PrivilegeCount;
		public LUID_AND_ATTRIBUTES Privileges;
	}

	[DllImport("advapi32.dll")]
	static extern int OpenProcessToken(IntPtr ProcessHandle,
		int DesiredAccess, out IntPtr TokenHandle);

	[DllImport("advapi32.dll", SetLastError = true)]
	[return: MarshalAs(UnmanagedType.Bool)]
	static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
		[MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
		ref TOKEN_PRIVILEGES NewState,
		UInt32 BufferLength,
		IntPtr PreviousState,
		IntPtr ReturnLength);

	[DllImport("advapi32.dll")]
	static extern int LookupPrivilegeValue(string lpSystemName,
		string lpName, out LUID lpLuid);

	[DllImport("user32.dll", SetLastError = true)]
	static extern int ExitWindowsEx(uint uFlags, uint dwReason);

	const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
	const short SE_PRIVILEGE_ENABLED = 2;
	const short TOKEN_ADJUST_PRIVILEGES = 32;
	const short TOKEN_QUERY = 8;

	const ushort EWX_LOGOFF = 0;
	const ushort EWX_POWEROFF = 0x00000008;
	const ushort EWX_REBOOT = 0x00000002;
	const ushort EWX_RESTARTAPPS = 0x00000040;
	const ushort EWX_SHUTDOWN = 0x00000001;
	const ushort EWX_FORCE = 0x00000004;

	private static void getPrivileges() {
		IntPtr hToken;
		TOKEN_PRIVILEGES tkp;

		OpenProcessToken(Process.GetCurrentProcess().Handle,
			TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out hToken);
		tkp.PrivilegeCount = 1;
		tkp.Privileges.Attributes = SE_PRIVILEGE_ENABLED;
		LookupPrivilegeValue("", SE_SHUTDOWN_NAME,
			out tkp.Privileges.pLuid);
		AdjustTokenPrivileges(hToken, false, ref tkp,
			0U, IntPtr.Zero, IntPtr.Zero);
	}

	public static void Shutdown() { Shutdown(false); }
	public static void Shutdown(bool force) {
		getPrivileges();
		ExitWindowsEx(EWX_SHUTDOWN |
			(uint)(force? EWX_FORCE : 0) | EWX_POWEROFF, 0);
	}

	public static void Reboot() { Reboot(false); }
	public static void Reboot(bool force) {
		getPrivileges();
		ExitWindowsEx(EWX_REBOOT |
			(uint)(force ? EWX_FORCE : 0), 0);
	}

	public static void LogOff() { LogOff(false); }
	public static void LogOff(bool force) {
		getPrivileges();
		ExitWindowsEx(EWX_LOGOFF |
			(uint)(force ? EWX_FORCE : 0), 0);
	}
}

I hope you find this useful!

2 responses to “ExitWindowsEx in C#

  1. Lukas15

    Thank you so much. I could not find a nice and little implementation of ExitWindowsEx anywhere and this one is great!

  2. Nikolai

    Thank you! This is the best example of ExitWindowsEx system call that I have ever seen!

Leave a Reply

Your email address will not be published.