您的位置:首页 > 编程语言 > C#

C# 快速关机代码

2010-03-17 14:22 155 查看
今天用到这个,网上找个不错的,保存下来。

注意:这个方法是快速关机,不会保存你的任何未保存信息。

// 这
个结构体将会传递给API。使用StructLayout
  

        [StructLayout(LayoutKind.Sequential, Pack = 1)]  

        internal
 
struct
 TokPriv1Luid  

        {  

            public
 
int
 Count;  

            public
 
long
 Luid;  

            public
 
int
 Attr;  

        }  

  

        // 导入的方法必须是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_SHUTDOWN = 0x00000001;  

        //internal const int EWX_LOGOFF = 0x00000000;
  

        //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);  

        }  

  

/// <summary>
  

        /// 关机按钮
  

        /// </summary>
  

        /// <param name="sender"></param>
  

        /// <param name="e"></param>
  

        private
 
void
 btnShutDown_Click(
object
 sender, EventArgs e)  

        {  

            DialogResult dr = MessageBox.Show(@"确定要关机吗?请保存信息后按'是',不关机按'否'"

"提示信息"
, MessageBoxButtons.YesNo, MessageBoxIcon.Information);  

            if
 (dr == DialogResult.Yes)  

            {  

                CommonClass.DoExitWin(CommonClass.EWX_SHUTDOWN);   

            }   

        }  

// 这个结构体将会传递给API。使用StructLayout
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}
// 导入的方法必须是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_SHUTDOWN = 0x00000001;
//internal const int EWX_LOGOFF = 0x00000000;
//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);
}
/// <summary>
/// 关机按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnShutDown_Click(object sender, EventArgs e)
{
DialogResult dr =
MessageBox.Show(@"确定要关机吗?请保存信息后按'是',不关机按'否'", "提示信息",
MessageBoxButtons.YesNo, MessageBoxIcon.Information);
if (dr == DialogResult.Yes)
{
CommonClass.DoExitWin(CommonClass.EWX_SHUTDOWN);
}
}


转载自:http://hi.baidu.com/youzhch/blog/item/215a1e4a5ee56f2009f7efd9.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: