这个话题在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;
}
}结果不行 ,哪位指点一下 一定要可行的,因为我花了好长时间,还是不行。真的很感谢。
我是这样写的:
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;
}
}结果不行 ,哪位指点一下 一定要可行的,因为我花了好长时间,还是不行。真的很感谢。
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;
}
}关机时候询问用户一下,请不要写在关闭窗体时候询问 ,有些用户是直接关机的,所以只能这样做,为什么不能达到效果 ,虚拟机也在关机时候询问 要的和那是一样的,我在线等待高手的解答。
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;
}
{
if (e.CloseReason == CloseReason.WindowsShutDown)
{
e.Cancel = true;
}
}
我空间的,绝对楼主就是要这家伙
只举例关闭计算机的函数部分:
//导入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尚未关闭之时启动卡死进程看看行不行。
另外 上面的方法可以强制杀死几乎所有顽固进程(列出来供参考)。
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);
}
}
}
楼主试试上面的!
哇哈哈哈哈~~~~
在发消息阻止关机
楼主的程序没问题,有问题的是系统。
打开注册表:
HKEY_CURRENT_USER\Control Panel\Desktop
AutoEndTasks 改为0;
HungAppTimeout 改为5000;
WaitToKillAppTimeout 改为20000;
这些都是默认值,可能你装的是别人做的系统给改掉了。特别是第一个,改成1系统关机不会给你的程序发消息。