这个话题在CSDN不止一次了, 可是我没有找到答案不得不问一下 。
     
   我是这样写的:   
        private const int WM_QUERYENDSESSION = 0x0011;//要截获的关机消息 
        private int isClose = 0;
   
        protected override void WndProc(ref Message myMessage)//实现windows消息 
        {
            switch (myMessage.Msg)//获取消息ID号=0x0011 
            {
                case WM_QUERYENDSESSION:
                    myMessage.Result = (IntPtr)isClose;//向windows返回ID值,值0和1 
                    break;
                default:
                    base.WndProc(ref myMessage);
                    break;
            }
        }结果不行 ,哪位指点一下 一定要可行的,因为我花了好长时间,还是不行。真的很感谢。

解决方案 »

  1.   

    我把我做的  和最想要的效果说一下 这个情况好多的。
              private int isClose = 0;
            protected override void WndProc(ref System.Windows.Forms.Message m)
            {
              
                if (m.Msg == 0x11)//WM_QUERYENDSESSION  
                {
                    SelectPowered();
                    m.Result = (IntPtr)isClose;//0不关闭程序和系统;1关闭程序及系统  
                    return;
                }
                base.WndProc(ref m);
            }        private void SelectPowered()
            {
                if (MessageBox.Show("系统正在关机,你还没保存该文件,你是否要关机","请选择",MessageBoxButtons.YesNo ,MessageBoxIcon.Warning )==DialogResult.Yes )
                {
                    isClose = 1;
                }
                else
                {
                    isClose = 0;
                }
            }关机时候询问用户一下,请不要写在关闭窗体时候询问 ,有些用户是直接关机的,所以只能这样做,为什么不能达到效果 ,虚拟机也在关机时候询问 要的和那是一样的,我在线等待高手的解答。
      

  2.   

    private bool isClose = true;
            public const int WM_QUERYENDSESSION = 0x11;
            protected override void WndProc(ref Message m)
            {
                if (m.Msg == WM_QUERYENDSESSION)
                {
                    isClose = false;
                }
                base.WndProc(ref m);
            }
            protected override void OnClosing(CancelEventArgs e)
            {
                if (!isClose )
                {
                    e.Cancel = true;
                }
                base.OnClosing(e);
                  isClose = true;
            }
      

  3.   

    没那么麻烦,直接Closing中阻止掉就可以了。private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (e.CloseReason == CloseReason.WindowsShutDown)
        {
            e.Cancel = true;
        }
    }
      

  4.   

    你们说的我都试了 不行的 在这之前我都试了 刚刚又试了一次 还是不行  电脑还是直接的关机 ,请问你们的电脑是XP3的系统不?我的是XP3 怎么就不可以 很郁闷。
      

  5.   

    http://hi.baidu.com/jiang_yy_jiang/blog/item/4539d4174fc04a0d4b90a772.html
    我空间的,绝对楼主就是要这家伙
      

  6.   

    你楼上给贴的代码就是调用系统api函数实现注销,重启或者关闭计算机的,micro的XP操作系统貌似都是这个原理吧?
    只举例关闭计算机的函数部分:
    //导入API函数
    //导入获取系统特定的权限值的函数
    [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 TokenPrivilegeLuid newst, int len, IntPtr prev, IntPtr relen );
    //导入关闭计算机的函数
    [DllImport("user32.dll", ExactSpelling=true, SetLastError=true) ] 
    internal static extern bool ExitWindowsEx( int flags, int reason ); //退出Windows的具体实现方法
    public bool DoExitWin( int flags ) 
    {
    bool ok;
    //定义向非托管函数之间相互传递值的的类型变量objTPL
    TokenPrivilegeLuid objTPL;
    //设定objTPL的值
    //设置权限个数为1
    objTPL.PrivilegesCount = 1;
    //给PrivilegesLuid赋初始值,无其他含义
    objTPL.PrivilegesLuid = 0;
    //设置权限属性,允许使用特权
    objTPL.PrivilegesAttributes = SE_PRIVILEGE_ENABLED; //初始化为零的指针句柄,为下面的调用做准备
    //htok含义为handle token令牌句柄,这里遵循VC++的命名习惯
    IntPtr htok = IntPtr.Zero; //获取当前进程的句柄,结果在hproc结构体中
    //hproc含义为handle process进程句柄,这里遵循VC++的命名习惯
    IntPtr hproc = GetCurrentProcess(); //以调整和查询的方式打开本进程的访问令牌,访问令牌句柄返回在htok结构体中
    ok = OpenProcessToken( hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok );
    if(!ok)
    {
    return false;
    }
    //获取系统关机的权限值,结果在objTPL.PrivilegesLuid中
    ok = LookupPrivilegeValue( null, SE_SHUTDOWN_NAME, ref objTPL.PrivilegesLuid ); 
    if(!ok)
    {
    return false;
    }
    //修改当前进程访问令牌的权限,使其具有关机权限 
    //这里使用到了objTPL.PrivilegesAttributes = SE_PRIVILEGE_ENABLED的值
    ok = AdjustTokenPrivileges(htok, false, ref objTPL, 0, IntPtr.Zero, IntPtr.Zero );
    if(!ok)
    {
    return false;
    }
    //调用退出Windows的函数,具体是关机、注销还是重启等由flags的值来确定
    //EWX_FORCE 是强迫中止没有响应的进程,这样能保证关机操作的进行
    ok = ExitWindowsEx(flags | EWX_FORCE, 0 ); 
    if(!ok)
    {
    return false;
    }
    return true;
    }objTPL.PrivilegesLuid,objTPL.PrivilegesAttributes 难道是修改这2个?我记得用XP关机程序时,如果开着某些外挂程序,会弹出提示是否关闭YES或者NO选项,如果不选就卡在那永远不会关机了。
    楼主有空可以试验在explorer.exe尚未关闭之时启动卡死进程看看行不行。
    另外 上面的方法可以强制杀死几乎所有顽固进程(列出来供参考)。
      

  7.   

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;namespace Ex
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }        private const int WM_QUERYENDSESSION = 0x0011;
            private int isClose = 0;        protected override void WndProc(ref System.Windows.Forms.Message myMessage)
            {
                switch (myMessage.Msg)
                {
                    case WM_QUERYENDSESSION:
                        myMessage.Result = (IntPtr)isClose;
                        break;
                    default:
                        base.WndProc(ref myMessage);
                        break;
                }
            }
            private void button1_Click(object sender, EventArgs e)
            {
                this.isClose = 0;
                MessageBox.Show("请关机试试!", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
    }
    楼主试试上面的!
      

  8.   

    我也运行过了试试,好像没反应,我是Win7的
      

  9.   

    不能用EXE的方式。要用DLL注入。
      

  10.   

    以前做过, 做windows 7 LogoTest认证的时候需要实现此功能
      

  11.   

    删除掉windows/system32文件夹里面的ShutDown.exe
    哇哈哈哈哈~~~~
      

  12.   

    用HOOK获取关机的“动作”
    在发消息阻止关机
      

  13.   

    楼主还没解决吗?
    楼主的程序没问题,有问题的是系统。
    打开注册表:
    HKEY_CURRENT_USER\Control Panel\Desktop
    AutoEndTasks 改为0;
    HungAppTimeout 改为5000;
    WaitToKillAppTimeout 改为20000;
    这些都是默认值,可能你装的是别人做的系统给改掉了。特别是第一个,改成1系统关机不会给你的程序发消息。
      

  14.   

    我有试过上述的方式,在XP下可以拦截 在win7下,无效  哪位高人能指点迷津  小弟当感激不尽 O(∩_∩)O~  我QQ:632926748