[C#] 纯文本查看 复制代码
using System;
using System.Text;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.Serialization;
using System.Runtime.InteropServices;
namespace PowerOperationForWin32Api
{
/// <summary>
/// TokenPrivileges 结构包含了一个访问令牌的一组权限信息:即该访问令牌具备的权限
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct STokenPrivileges
{
/// <summary>
/// 指定了权限数组的容量
/// </summary>
public int PrivilegeCount;
/// <summary>
/// 指定一组的LuidAttributes 结构,每个结构包含了LUID和权限的属性
/// </summary>
public SLuidAttributes Privileges;
}
/// <summary>
/// LuidAttributes 结构呈现了本地唯一标志和它的属性
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SLuidAttributes
{
/// <summary>
/// 特定的LUID
/// </summary>
public SLocallyUniqueIdentifier PLuid;
/// <summary>
/// 指定了LUID的属性,其值可以是一个32位大小的bit 标志,具体含义根据LUID的定义和使用来看
/// </summary>
public int Attributes;
}
/// <summary>
/// 本地唯一标志是一个64位的数值,它被保证在产生它的系统上唯一!LUID的在机器被重启前都是唯一的
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SLocallyUniqueIdentifier
{
/// <summary>
/// 本地唯一标志的低32位
/// </summary>
public int LowPart;
/// <summary>
/// 本地唯一标志的高32位
/// </summary>
public int HighPart;
}
/// <summary>
/// Windows电源相关操作类
/// </summary>
public class ExitWindows
{
private const int EWX_FORCE = 4;
private const int EWX_LOGOFF = 0;
private const int EWX_REBOOT = 2;
private const int EWX_SHUTDOWN = 1;
private const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
private const int TOKEN_QUERY = 8;
private const int TOKEN_ADJUST_PRIVILEGES = 32;
private const int SE_PRIVILEGE_ENABLED = 2;
private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x1000;
[DllImport("user32.dll", EntryPoint = "ExitWindowsEx", CharSet = CharSet.Ansi)]
private static extern int ExitWindowsEx(int _flags, int _reserved);
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
private static extern bool OpenProcessToken(IntPtr _process, int _access, ref IntPtr _token);
[DllImport("kernel32.dll", ExactSpelling = true)]
private static extern IntPtr GetCurrentProcess();
[DllImport("advapi32.dll", EntryPoint = "LookupPrivilegeValueA", CharSet = CharSet.Ansi)]
private static extern int LookupPrivilegeValue(string _sysname, string _name, ref SLocallyUniqueIdentifier _luid);
[DllImport("advapi32.dll", EntryPoint = "AdjustTokenPrivileges", CharSet = CharSet.Ansi)]
private static extern int AdjustTokenPrivileges(IntPtr _tokenptr, int _disallpriv, ref STokenPrivileges _nstat, int _bufflen, ref STokenPrivileges _prevstat, ref int _retlen);
[DllImport("user32.dll", EntryPoint = "FormatMessageA", CharSet = CharSet.Ansi)]
private extern static int FormatMessage(int dwFlags, IntPtr lpSource, int dwMessageId, int dwLanguageId, StringBuilder lpBuffer, int nSize, int Arguments);
[DllImport("kernel32.dll", EntryPoint = "LoadLibraryA", CharSet = CharSet.Ansi)]
private extern static IntPtr LoadLibrary(string lpLibFileName);
[DllImport("kernel32.dll", EntryPoint = "FreeLibrary", CharSet = CharSet.Ansi)]
private extern static int FreeLibrary(IntPtr hLibModule);
[DllImport("kernel32.dll", EntryPoint = "GetProcAddress", CharSet = CharSet.Ansi)]
private extern static IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
[DllImport("kernel32.dll", EntryPoint = "GetLastError", CharSet = CharSet.Ansi)]
private static extern long GetLastError();
/// <summary>
/// 注销当前用户,但是不退出Windows
/// </summary>
public static long LogOff()
{
GetSystemAuthority(SE_SHUTDOWN_NAME);
ExitWindowsEx(EWX_LOGOFF, 0);
return GetLastError();
}
/// <summary>
/// 重新启动Windows
/// </summary>
public static long ResetBoot()
{
GetSystemAuthority(SE_SHUTDOWN_NAME);
ExitWindowsEx(EWX_REBOOT, 0);
return GetLastError();
}
/// <summary>
/// 强制中断当前用户的所有进程,即强制注销
/// </summary>
public static long InterruptAllUserProcess()
{
GetSystemAuthority(SE_SHUTDOWN_NAME);
ExitWindowsEx(EWX_FORCE, 0);
return GetLastError();
}
/// <summary>
/// 关闭Windows
/// </summary>
public static long Shutdown()
{
GetSystemAuthority(SE_SHUTDOWN_NAME);
ExitWindowsEx(EWX_SHUTDOWN, 0);
return GetLastError();
}
/// <summary>
/// 使Windows强制进入休眠状态
/// </summary>
public static void Hibernate()
{
Application.SetSuspendState(PowerState.Hibernate, false, true);
}
/// <summary>
/// 使Windows进入休眠状态,并告知其他进程使其进入休眠状态
/// </summary>
public static void Hibernate(bool _force)
{
Application.SetSuspendState(PowerState.Hibernate, _force, true);
}
/// <summary>
/// 强制挂起Windows,即睡眠模式
/// </summary>
public static void Suspend()
{
Application.SetSuspendState(PowerState.Suspend, false, false);
}
/// <summary>
/// 挂起Windows,并通知其他进程是否决定该操作
/// </summary>
public static void Suspend(bool _force)
{
Application.SetSuspendState(PowerState.Suspend, _force, false);
}
/// <summary>
/// 获取更高级别的操作系统权限
/// </summary>
public static void GetSystemAuthority(string _privilege)
{
if (!CheckEntryPoint("advapi32.dll", "AdjustTokenPrivileges"))
{
return;
}
IntPtr tokenHandle = IntPtr.Zero;
SLocallyUniqueIdentifier luid = new SLocallyUniqueIdentifier();
STokenPrivileges newPrivileges = new STokenPrivileges();
STokenPrivileges tokenPrivileges;
if (OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref tokenHandle) == false)
{
throw new Win32ApiErrorInformationException(FormatError(Marshal.GetLastWin32Error()));
}
if (LookupPrivilegeValue(null, _privilege, ref luid) == 0)
{
throw new Win32ApiErrorInformationException(FormatError(Marshal.GetLastWin32Error()));
}
tokenPrivileges.PrivilegeCount = 1;
tokenPrivileges.Privileges.Attributes = SE_PRIVILEGE_ENABLED;
tokenPrivileges.Privileges.PLuid = luid;
int size = 4;
if (AdjustTokenPrivileges(tokenHandle, 0, ref tokenPrivileges, 4 + (12 * tokenPrivileges.PrivilegeCount), ref newPrivileges, ref size) == 0)
{
throw new Win32ApiErrorInformationException(FormatError(Marshal.GetLastWin32Error()));
}
}
/// <summary>
/// 检测本地系统上是否存在一个指定的方法入口
/// </summary>
public 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>
/// 将错误号转换为错误消息
/// </summary>
public 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>
/// Win32Api错误信息异常
/// </summary>
[Serializable]
public class Win32ApiErrorInformationException : Exception
{
public Win32ApiErrorInformationException() { }
public Win32ApiErrorInformationException(string message) : base(message) { }
public Win32ApiErrorInformationException(string message, Exception inner) : base(message, inner) { }
protected Win32ApiErrorInformationException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
}