CSkin博客

标题: 【Win32Api】怎么使用Win32Api来退出、重新引导Windows等操作 [打印本页]

作者: 轩墨玉生烟    时间: 2016-3-17 17:17
标题: 【Win32Api】怎么使用Win32Api来退出、重新引导Windows等操作
说明:
这是鄙人弄了两天的代码,这段代码可以实现注销、强制注销当前用户,挂起、休眠、重新引导、退出Windows等操作,先不说这么多。

附上代码:
[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) { }
   }
}


案例源码下载:
PowerOperationForWin32Api.zip (63.96 KB, 下载次数: 13, 售价: 1 金钱)



作者: 轩墨玉生烟    时间: 2016-3-17 17:21
自顶一下
作者: kuafaaf    时间: 2016-3-17 17:28
拿个沙发
作者: liqud    时间: 2016-3-18 08:54
支持一下
作者: ingdear    时间: 2016-3-19 10:12
我来支持了,好像有段时间没来了,以后常来。
作者: James_vi    时间: 2016-5-6 23:48
怎么下载不了
作者: 310939468    时间: 2016-5-25 00:39
谢谢分享
作者: hgf520    时间: 2016-6-16 23:35
感谢分享




欢迎光临 CSkin博客 (http://bbs.cskin.net/) Powered by Discuz! X3.2