我是这样写的:
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;
}
}
结果不行 ,哪位指点一下 一定要可行的,因为我花了好长时间,还是不行。真的很感谢。
40 个解决方案
#1
我为了测试因为没有阻止关机我的电脑都关了10几次,最后我想到办法就是 我装虚拟机和装系统 为了达到这个效果还是不行的。我弄了好半天 ,高手快帮个忙,谢谢
#2
我把我做的 和最想要的效果说一下 这个情况好多的。
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;
}
}
关机时候询问用户一下,请不要写在关闭窗体时候询问 ,有些用户是直接关机的,所以只能这样做,为什么不能达到效果 ,虚拟机也在关机时候询问 要的和那是一样的,我在线等待高手的解答。
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;
}
}
关机时候询问用户一下,请不要写在关闭窗体时候询问 ,有些用户是直接关机的,所以只能这样做,为什么不能达到效果 ,虚拟机也在关机时候询问 要的和那是一样的,我在线等待高手的解答。
#3
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;
}
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;
}
#4
好像楼上这样就可以了,我以前貌似也是这样写的。
#5
做个记号
#6
没那么麻烦,直接Closing中阻止掉就可以了。
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.WindowsShutDown)
{
e.Cancel = true;
}
}
#7
估计是对的吧,屏蔽关闭消息吧
#8
你们说的我都试了 不行的 在这之前我都试了 刚刚又试了一次 还是不行 电脑还是直接的关机 ,请问你们的电脑是XP3的系统不?我的是XP3 怎么就不可以 很郁闷。
#9
#10
还是不行
#12
我要是是防止关机 不是去关机
#13
OS才不管你弹出的框呢!
#14
关注下
#15
你楼上给贴的代码就是调用系统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尚未关闭之时启动卡死进程。。。看看行不行。
另外 上面的方法可以强制杀死几乎所有顽固进程(列出来供参考)。
#16
C# 到底能不能? 我想应该能 大概还是没有找到好方法
#17
#18
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);
}
}
}
楼主试试上面的!
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);
}
}
}
楼主试试上面的!
#19
我也运行过了试试,好像没反应,我是Win7的
#20
不能用EXE的方式。要用DLL注入。
#21
要是我拨插头呢,怎么阻止我,哈哈~
#22
#23
+10
#24
我最开始就是这样的做 不行的
#25
你没有看见或者看懂我的意思 我们做业务不是做黑客
#26
hook ExitWindowsEx
#27
以前做过, 做windows 7 LogoTest认证的时候需要实现此功能
#28
做黑客的话,也不能拔你的插头啊。。。
呵呵,帮楼主顶一下,和lz一样期待答案。。。
#29
我承认我看错了!
#30
坐等
#31
删除掉windows/system32文件夹里面的ShutDown.exe
哇哈哈哈哈~~~~
哇哈哈哈哈~~~~
#32
#33
#34
给你发了邮件,可以了没?
#35
用HOOK获取关机的“动作”
在发消息阻止关机
在发消息阻止关机
#36
昨天有事情 没有去公司 不好意思,很感谢你的热心,
#37
既然我们交流了 ,你想过这个问题没有 这样阻止不完善, 这样系统关机执行 只是到我们窗口才停止关机
应该满足 一点击关机按钮 就提示 是否真的关机 ,虚拟机都是这样的啊 ,值得思考。
应该满足 一点击关机按钮 就提示 是否真的关机 ,虚拟机都是这样的啊 ,值得思考。
#38
用钩子不怎么会 高手指点一下 一定要用全局钩子,请不要用线程钩子。
#39
楼主还没解决吗?
楼主的程序没问题,有问题的是系统。
打开注册表:
HKEY_CURRENT_USER\Control Panel\Desktop
AutoEndTasks 改为0;
HungAppTimeout 改为5000;
WaitToKillAppTimeout 改为20000;
这些都是默认值,可能你装的是别人做的系统给改掉了。特别是第一个,改成1系统关机不会给你的程序发消息。
楼主的程序没问题,有问题的是系统。
打开注册表:
HKEY_CURRENT_USER\Control Panel\Desktop
AutoEndTasks 改为0;
HungAppTimeout 改为5000;
WaitToKillAppTimeout 改为20000;
这些都是默认值,可能你装的是别人做的系统给改掉了。特别是第一个,改成1系统关机不会给你的程序发消息。
#40
我有试过上述的方式,在XP下可以拦截。。。 在win7下,无效。。。 哪位高人能指点迷津。。。 小弟当感激不尽。。。 O(∩_∩)O~ 我QQ:632926748
#1
我为了测试因为没有阻止关机我的电脑都关了10几次,最后我想到办法就是 我装虚拟机和装系统 为了达到这个效果还是不行的。我弄了好半天 ,高手快帮个忙,谢谢
#2
我把我做的 和最想要的效果说一下 这个情况好多的。
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;
}
}
关机时候询问用户一下,请不要写在关闭窗体时候询问 ,有些用户是直接关机的,所以只能这样做,为什么不能达到效果 ,虚拟机也在关机时候询问 要的和那是一样的,我在线等待高手的解答。
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;
}
}
关机时候询问用户一下,请不要写在关闭窗体时候询问 ,有些用户是直接关机的,所以只能这样做,为什么不能达到效果 ,虚拟机也在关机时候询问 要的和那是一样的,我在线等待高手的解答。
#3
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;
}
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;
}
#4
好像楼上这样就可以了,我以前貌似也是这样写的。
#5
做个记号
#6
没那么麻烦,直接Closing中阻止掉就可以了。
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.WindowsShutDown)
{
e.Cancel = true;
}
}
#7
估计是对的吧,屏蔽关闭消息吧
#8
你们说的我都试了 不行的 在这之前我都试了 刚刚又试了一次 还是不行 电脑还是直接的关机 ,请问你们的电脑是XP3的系统不?我的是XP3 怎么就不可以 很郁闷。
#9
#10
还是不行
#11
#12
我要是是防止关机 不是去关机
#13
OS才不管你弹出的框呢!
#14
关注下
#15
你楼上给贴的代码就是调用系统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尚未关闭之时启动卡死进程。。。看看行不行。
另外 上面的方法可以强制杀死几乎所有顽固进程(列出来供参考)。
#16
C# 到底能不能? 我想应该能 大概还是没有找到好方法
#17
#18
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);
}
}
}
楼主试试上面的!
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);
}
}
}
楼主试试上面的!
#19
我也运行过了试试,好像没反应,我是Win7的
#20
不能用EXE的方式。要用DLL注入。
#21
要是我拨插头呢,怎么阻止我,哈哈~
#22
#23
+10
#24
我最开始就是这样的做 不行的
#25
你没有看见或者看懂我的意思 我们做业务不是做黑客
#26
hook ExitWindowsEx
#27
以前做过, 做windows 7 LogoTest认证的时候需要实现此功能
#28
做黑客的话,也不能拔你的插头啊。。。
呵呵,帮楼主顶一下,和lz一样期待答案。。。
#29
我承认我看错了!
#30
坐等
#31
删除掉windows/system32文件夹里面的ShutDown.exe
哇哈哈哈哈~~~~
哇哈哈哈哈~~~~
#32
#33
#34
给你发了邮件,可以了没?
#35
用HOOK获取关机的“动作”
在发消息阻止关机
在发消息阻止关机
#36
昨天有事情 没有去公司 不好意思,很感谢你的热心,
#37
既然我们交流了 ,你想过这个问题没有 这样阻止不完善, 这样系统关机执行 只是到我们窗口才停止关机
应该满足 一点击关机按钮 就提示 是否真的关机 ,虚拟机都是这样的啊 ,值得思考。
应该满足 一点击关机按钮 就提示 是否真的关机 ,虚拟机都是这样的啊 ,值得思考。
#38
用钩子不怎么会 高手指点一下 一定要用全局钩子,请不要用线程钩子。
#39
楼主还没解决吗?
楼主的程序没问题,有问题的是系统。
打开注册表:
HKEY_CURRENT_USER\Control Panel\Desktop
AutoEndTasks 改为0;
HungAppTimeout 改为5000;
WaitToKillAppTimeout 改为20000;
这些都是默认值,可能你装的是别人做的系统给改掉了。特别是第一个,改成1系统关机不会给你的程序发消息。
楼主的程序没问题,有问题的是系统。
打开注册表:
HKEY_CURRENT_USER\Control Panel\Desktop
AutoEndTasks 改为0;
HungAppTimeout 改为5000;
WaitToKillAppTimeout 改为20000;
这些都是默认值,可能你装的是别人做的系统给改掉了。特别是第一个,改成1系统关机不会给你的程序发消息。
#40
我有试过上述的方式,在XP下可以拦截。。。 在win7下,无效。。。 哪位高人能指点迷津。。。 小弟当感激不尽。。。 O(∩_∩)O~ 我QQ:632926748