using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;  // 提供DllImport等特性,是P/Invoke的关键
namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public Form1()
        {
            InitializeComponent();
               }        private void Form1_Load(object sender, EventArgs e)
        {
        
                 internal struct TokPriv1Luid
          {
              public int Count;
              public long Luid;
              public int Attr;
          }   
    
          // 以下使用DllImport特性导入了所需的Windows API。          // 导入的方法必须是static extern的,并且没有方法体。调用这些方法就相当于调用Windows API。
         [DllImport("kernel32.dll", ExactSpelling = true)]
          internal static extern IntPtr GetCurrentProcess();          [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
          internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);          [DllImport("advapi32.dll", SetLastError = true)]
          internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);          [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
          internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
          ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);          [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
          internal static extern bool ExitWindowsEx(int flg, int rea);      
          // 以下定义了在调用WinAPI时需要的常数。这些常数通常可以从Platform SDK的包含文件(头文件)中找到          internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
          internal const int TOKEN_QUERY = 0x00000008;
          internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
          internal const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
          internal const int EWX_LOGOFF = 0x00000000;
          internal const int EWX_SHUTDOWN = 0x00000001;
          internal const int EWX_REBOOT = 0x00000002;
          internal const int EWX_FORCE = 0x00000004;
          internal const int EWX_POWEROFF = 0x00000008;
          internal const int EWX_FORCEIFHUNG = 0x00000010;
          // 通过调用WinAPI实现关机,主要代码再最后一行ExitWindowsEx,这调用了同名的WinAPI,正好是关机用的。          private static void DoExitWin(int flg)
          {
              bool ok;
              TokPriv1Luid tp;
              IntPtr hproc = GetCurrentProcess();
              IntPtr htok = IntPtr.Zero;
              ok = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES |TOKEN_QUERY, ref htok);
              tp.Count = 1;
              tp.Luid = 0;
              tp.Attr = SE_PRIVILEGE_ENABLED;
              ok = LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref tp.Luid);
              ok = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
              ok = ExitWindowsEx(flg, 0);
          }        private void button1_Click(object sender, EventArgs e)
        {
        DoExitWin(EWX_SHUTDOWN);
        }
    
   }
}

解决方案 »

  1.   


    using Microsoft.VisualBasic;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Data;
    using System.Diagnostics;
    using System.Text;
    using System.Runtime.InteropServices;static class cqModule
    {
    //如果在申请一个权限时发生错,将引发本异常
    private class PrivilegeException : Exception
    {
    public PrivilegeException(string message) : base(message)
    {
    }
    } //注销
    public static void LogOff()
    {
    ExitWindows(RestartOptions.LogOff, true);
    // 强制执行 =True ‘安全非强制执行=flase
    } //关闭电源
    public static void PowerOff()
    {
    ExitWindows(RestartOptions.PowerOff, true);
    // 强制执行 =True ‘安全非强制执行=False
    } //重启计算机
    public static void Reboot()
    {
    ExitWindows(RestartOptions.Reboot, true);
    // 强制执行 =True ‘安全非强制执行=False
    } //关闭系统
    public static void ShutDown()
    {
    ExitWindows(RestartOptions.ShutDown, true);
    // 强制执行 =True ‘安全非强制执行=False
    } //待机
    public static void Suspend()
    {
    ExitWindows(RestartOptions.Suspend, true);
    // 强制执行 =True ‘安全非强制执行=False
    } //休眠
    public static void Hibernate()
    {
    ExitWindows(RestartOptions.Hibernate, true);
    // 强制执行 =True ‘安全非强制执行=False
    } private enum RestartOptions
    {
    //枚举类型,指定可以允许的重启操作
    LogOff = 0,
    //注销   '关闭调用ExitWindowsEx()功能的进程安全上下文中所有运行的程序,然后用户退出登录
    PowerOff = 8,
    //关闭电源   ' 关闭操作系统和电源,计算机必须支持软件控制电源
    Reboot = 2,
    //重启计算机'注销 '关闭系统然后重启
    ShutDown = 1,
    //关闭系统 '等待合适的时刻关闭电源:当所有文件的缓存区被写入磁盘,所有运行的进程停止,如果系统支持软件控制电源,就关闭电源
    Suspend = -1,
    //待机
    Hibernate = -2
    //休眠
    } public struct LUID
    {
    //本地唯一标志的低32位
    public int LowPart;
    // 本地唯一标志的高32位
    public int HighPart;
    } public struct LUID_AND_ATTRIBUTES
    {
    //Specifies an LUID value
    public LUID pLuid;
    //指定了LUID的属性,其值可以是一个32位大小的bit 标志,具体含义根据LUID的定义和使用来看
    public int Attributes;
    } public struct TOKEN_PRIVILEGES
    {
    //包含了一个访问令牌的一组权限信息:即该访问令牌具备的权限
    //指定了权限数组的容量
    public int PrivilegeCount;
    // 指定一组的LUID_AND_ATTRIBUTES 结构,每个结构包含了LUID和权限的属性
    public LUID_AND_ATTRIBUTES Privileges;
    } //用来在访问令牌中启用和禁用一个权限
    private const int TOKEN_ADJUST_PRIVILEGES = 0x20;
    //用来查询一个访问令牌
    private const int TOKEN_QUERY = 0x8;
    //权限启用标志
    private const int SE_PRIVILEGE_ENABLED = 0x2;
    //指定了函数需要为请求消息查找系统消息表资源
    private const long FORMAT_MESSAGE_FROM_SYSTEM = 0x1000;
    //强制停止进程。当设置了该标志后,系统不会发送WM_QUERYENDSESSION 和 WM_ENDSSESSION消息,这会使应用程序丢失数据。' 因此,除非紧急,你要慎用该标志
    private const int EWX_FORCE = 0x4;
    [DllImport("kernel32", EntryPoint = "LoadLibraryA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    public static extern IntPtr LoadLibrary(string lpLibFileName);
    [DllImport("kernel32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    public static extern int FreeLibrary(IntPtr hLibModule);
    [DllImport("kernel32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
    [DllImport("Powrprof", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    public static extern int SetSuspendState(int Hibernate, int ForceCritical, int DisableWakeEvent);
    [DllImport("advapi32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    public static extern int OpenProcessToken(IntPtr ProcessHandle, int DesiredAccess, ref IntPtr TokenHandle);
    [DllImport("advapi32.dll", EntryPoint = "LookupPrivilegeValueA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    public static extern int LookupPrivilegeValue(string lpSystemName, string lpName, ref LUID lpLuid);
    [DllImport("advapi32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    public static extern int AdjustTokenPrivileges(IntPtr TokenHandle, int DisableAllPrivileges, ref TOKEN_PRIVILEGES NewState, int BufferLength, ref TOKEN_PRIVILEGES PreviousState, ref int ReturnLength);
    [DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    public static extern int ExitWindowsEx(int uFlags, int dwReserved);
    [DllImport("kernel32", EntryPoint = "FormatMessageA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    public static extern int FormatMessage(int dwFlags, IntPtr lpSource, int dwMessageId, int dwLanguageId, StringBuilder lpBuffer, int nSize, int Arguments); private static void ExitWindows(RestartOptions how, bool force)
    {
    // 退出Windows,如果需要,申请相应权限
    // "how"重启选项,指示如何退出Windows
    // "force"=True表示强制退出
    switch (how) {
    case RestartOptions.Suspend:
    SuspendSystem(false, force);
    break;
    case RestartOptions.Hibernate:
    SuspendSystem(true, force);
    break;
    default:
    ExitWindows(Convert.ToInt32(how), force);
    break;
    }
    } private static void ExitWindows(int how, bool force)
    {
    // 退出Windows,如果需要,申请所有权限
    // "how"重启选项,指示如何退出Windows
    // "force"=True表示强制退出
    EnableToken("SeShutdownPrivilege");
    if (force)
    how = how | EWX_FORCE;
    if ((ExitWindowsEx(how, 0) == 0))
    throw new PrivilegeException(FormatError(Marshal.GetLastWin32Error()));
    } private static void EnableToken(string privilege)
    {
    // 启用指定的权限
    // "privilege"要启用的权限
    if (!CheckEntryPoint("advapi32.dll", "AdjustTokenPrivileges"))
    return;
    IntPtr tokenHandle = IntPtr.Zero;
    LUID privilegeLUID = new LUID();
    TOKEN_PRIVILEGES newPrivileges = new TOKEN_PRIVILEGES();
    TOKEN_PRIVILEGES tokenPrivileges = default(TOKEN_PRIVILEGES);
    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()));
    } private static void SuspendSystem(bool hibernate, bool force)
    {
    //挂起或休眠系统 ,True表示休眠,否则表示挂起系统,True表示强制退出,如果系统不支持,将抛出PlatformNotSupportedException
    if (!CheckEntryPoint("powrprof.dll", "SetSuspendState"))
    throw new PlatformNotSupportedException("The SetSuspendState method is not supported on this system!");
    SetSuspendState(Convert.ToInt32((hibernate ? 1 : 0)), Convert.ToInt32((force ? 1 : 0)), 0);
    } private static bool CheckEntryPoint(string library, string method)
    {
    //   检测本地系统上是否存在一个指定的方法入口,如果存在指定方法,返回True,否则返回False
    IntPtr libPtr = LoadLibrary(library);
    if (!libPtr.Equals(IntPtr.Zero)) {
    if (!GetProcAddress(libPtr, method).Equals(IntPtr.Zero)) {
    FreeLibrary(libPtr);
    return true;
    }
    FreeLibrary(libPtr);
    }
    return false;
    } private static string FormatError(int number)
    {
    // 将错误号转换为错误消息
    // "number"需要转换的错误号
    StringBuilder buffer = new StringBuilder(255);
    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, IntPtr.Zero, number, 0, buffer, buffer.Capacity, 0);
    return buffer.ToString();
    }