扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
/// <summary>
/// Exits windows (and tries to enable any required access rights, if necesarry).
/// </summary>
/// <param name="how">One of the RestartOptions values that specifies how to exit windows.</param>
/// <param name="force">True if the exit has to be forced, false otherwise.</param>
/// <exception cref="PrivilegeException">There was an error while requesting a required privilege.</exception>
/// <exception cref="PlatformNotSupportedException">The requested exit method is not supported on this platform.</exception>
public static void ExitWindows(RestartOptions how , bool force ) {
switch(how) {
case RestartOptions.Suspend:
SuspendSystem(false, force);
break;
case RestartOptions.Hibernate:
SuspendSystem(true, force);
break;
default:
ExitWindows((int)how, force);
break;
}
}
/// <summary>
/// Exits windows (and tries to enable any required access rights, if necesarry).
/// </summary>
/// <param name="how">One of the RestartOptions values that specifies how to exit windows.</param>
/// <param name="force">True if the exit has to be forced, false otherwise.</param>
/// <remarks>This method cannot hibernate or suspend the system.</remarks>
/// <exception cref="PrivilegeException">There was an error while requesting a required privilege.</exception>
protected static void ExitWindows(int how , bool force ) {
EnableToken("SeShutdownPrivilege");
if (force )
how = how | EWX_FORCE;
if (ExitWindowsEx(how, 0) == 0)
throw new PrivilegeException(FormatError(Marshal.GetLastWin32Error()));
}
/// <summary>
/// Tries to enable the specified privilege.
/// </summary>
/// <param name="privilege">The privilege to enable.</param>
/// <exception cref="PrivilegeException">There was an error while requesting a required privilege.</exception>
protected static void EnableToken(string privilege ) {
if (!CheckEntryPoint("advapi32.dll", "AdjustTokenPrivileges"))
return;
IntPtr tokenHandle = IntPtr.Zero;
LUID privilegeLUID = new LUID();
TOKEN_PRIVILEGES newPrivileges = new TOKEN_PRIVILEGES();
TOKEN_PRIVILEGES tokenPrivileges ;
if (OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref tokenHandle) == 0)
throw new PrivilegeException(FormatError(Marshal.GetLastWin32Error()));
if (LookupPrivilegeValue("", privilege, ref privilegeLUID) == 0)
throw new PrivilegeException(FormatError(Marshal.GetLastWin32Error()));
tokenPrivileges.PrivilegeCount = 1;
tokenPrivileges.Privileges.Attributes = SE_PRIVILEGE_ENABLED;
tokenPrivileges.Privileges.pLuid = privilegeLUID;
int size = 4;
if (AdjustTokenPrivileges(tokenHandle, 0, ref tokenPrivileges, 4 + (12 * tokenPrivileges.PrivilegeCount), ref newPrivileges, ref size) == 0)
throw new PrivilegeException(FormatError(Marshal.GetLastWin32Error()));
}
/// <summary>
/// Suspends or hibernates the system.
/// </summary>
/// <param name="hibernate">True if the system has to hibernate, false if the system has to be suspended.</param>
/// <param name="force">True if the exit has to be forced, false otherwise.</param>
/// <exception cref="PlatformNotSupportedException">The requested exit method is not supported on this platform.</exception>
protected static void SuspendSystem(bool hibernate , bool force ){
if (!CheckEntryPoint("powrprof.dll", "SetSuspendState"))
throw new PlatformNotSupportedException("The SetSuspendState method is not supported on this system!");
SetSuspendState((int)(hibernate ? 1 : 0), (int)(force ? 1 : 0), 0);
}
/// <summary>
/// Checks whether a specified method exists on the local computer.
/// </summary>
/// <param name="library">The library that holds the method.</param>
/// <param name="method">The entry point of the requested method.</param>
/// <returns>True if the specified method is present, false otherwise.</returns>
protected static bool CheckEntryPoint(string library , string method ) {
IntPtr libPtr = LoadLibrary(library);
if (!libPtr.Equals(IntPtr.Zero)) {
if (!GetProcAddress(libPtr, method).Equals(IntPtr.Zero)) {
FreeLibrary(libPtr);
return true;
}
FreeLibrary(libPtr);
}
return false;
}
/// <summary>
/// Formats an error number into an error message.
/// </summary>
/// <param name="number">The error number to convert.</param>
/// <returns>A string representation of the specified error number.</returns>
protected static string FormatError(int number ) {
StringBuilder buffer =new StringBuilder(255);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, IntPtr.Zero, number, 0, buffer, buffer.Capacity, 0);
return buffer.ToString();
}
}
/// <summary>
/// The exception that is thrown when an error occures when requesting a specific privilege.
/// </summary>
public class PrivilegeException : Exception {
/// <summary>
/// Initializes a new instance of the PrivilegeException class.
/// </summary>
public PrivilegeException () : base() {}
/// <summary>
/// Initializes a new instance of the PrivilegeException class with a specified error message.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public PrivilegeException (string message ) :base(message) {}
}
}
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者