c# 如何截获windows关机或注销消息

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c# 如何截获windows关机或注销消息相关的知识,希望对你有一定的参考价值。

要求关机或注销时弹出一个确认框提示我是否继续,
选择是继续关机,选择否取消关机回到windows.
可是为什么这种方法在我的电脑上不行啊,关机和注销的时候还是和平常一样,我的系统是winxpsp2.
是不是系统设置的问题啊?还有其他方法吗?

Form里有WndProc方法,对它进行重写,可以捕获系统消息。下面的代码放进你程序里试试。
//截取消息,进行处理
protected override void WndProc(ref Message m)

switch(m.Msg)

case 17:
MessageBox.Show("哈哈,你不能关闭计算机!");
m.Result=(IntPtr)0;
break;
case 513:
MessageBox.Show("哈哈,你不能点击左键!");
m.Result=(IntPtr)0;
break;
case 516:
MessageBox.Show("哈哈,你不能点击右键!");
m.Result=(IntPtr)0;
break;
default:
base.WndProc(ref m);
break;


以上方法是截获系统关机时发送给各个进程的关机消息,如果这种方法没用的话,可以用windows系统钩子来进行消息获取,一旦设置了系统钩子,它将先于任何消息捕捉机制而第一个捕捉到消息,用到系统钩子必须从系统DLL导入以下方法。
//装置钩子的函数
[DllImport("user32.dll ", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
//卸下钩子的函数
[DllImport("user32.dll ", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);

//下一个钩挂的函数
[DllImport("user32.dll ", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
具体的用法,可以去网上搜索,网上有很多的。英文叫windows hook。
参考技术A protected override void OnFormClosing(FormClosingEventArgs e)

switch (e.CloseReason)

case CloseReason.ApplicationExitCall:
e.Cancel = true;
MessageBox.Show("拦截关闭要求事件!");
break;
case CloseReason.FormOwnerClosing:
e.Cancel = true;
MessageBox.Show("拦截自身关闭事件!");
break;
case CloseReason.MdiFormClosing:
e.Cancel = true;
MessageBox.Show("拦截MDI窗体关闭事件!");
break;
case CloseReason.None:
break;
case CloseReason.TaskManagerClosing:
e.Cancel = true;
MessageBox.Show("拦截任务管理器关闭事件!");
break;
case CloseReason.UserClosing:
e.Cancel = true;
MessageBox.Show("拦截用户关闭事件!");
break;
case CloseReason.WindowsShutDown:
e.Cancel = true;
MessageBox.Show("拦截关机事件!");
break;
default:
break;


base.OnFormClosing(e);


但是值得一提的时候,关闭和注销的时候有时候会弹出来程序没响应的提示,这时候如果用立刻结束,还是会被关掉的。本回答被提问者采纳
参考技术B 楼上的朋友,楼主的意思是拦截windows的关机消息,不是关机以后发送给各进程的关机消息。

我猜用C#应该是实现不了的,看用远程注射能不能搞定了。可能通过替换掉内存中的关机的那段代码可以搞定。不过我也没什么经验,希望大家不要笑我。

C#实现控制Windows系统关机重启和注销的方法:

shutdown命令的参数:

shutdown.exe -s:关机
shutdown.exe -r:关机并重启
shutdown.exe -l:注销当前用户

shutdown.exe -s -t 时间:设置关机倒计时
shutdown.exe -h:休眠
shutdown.exe -t 时间:设置关机倒计时。默认值是 30 秒。
shutdown.exe -a:取消关机
shutdown.exe -f:强行关闭应用程序而没有警告
shutdown.exe -m \\计算机名:控制远程计算机
shutdown.exe -i:显示“远程关机”图形用户界面,但必须是Shutdown的第一个参数
shutdown.exe -c "消息内容":输入关机对话框中的消息内容
shutdown.exe -d [u][p]:xx:yy :列出系统关闭的原因代码:u 是用户代码 ,p 是一个计划的关闭代码 ,xx 是一个主要原因代码(小于 256 的正整数) ,yy 是一个次要原因代码(小于 65536 的正整数)

比如你的电脑要在12:00关机,可以选择“开始→运行”,输入“at 12:00 Shutdown -s",这样,到了12点电脑就会出现“系统关机”对话框,默认有30秒钟的倒计时并提示你保存工作。
如果你想以倒计时的方式关机,可以输入 “Shutdown.exe -s -t 3600",这里表示60分钟后自动关机,“3600"代表60分钟。
一键关机:
1、首先在桌面的空白处单击鼠标右键,新建一个“快捷方式”。
2、在创建快捷方式的“命令行”中输入以下的指令:
“shutdown –s –t 0 ”。(在windows98按此输入“C:windowsRUNDLL32.EXE user,ExitWindows”。)
3、按着鼠标选择“下一步”,在快捷方式的名称栏中输入“一键关机”或其他自己喜欢的名称。
4、之后,你就会在桌面见到一个名为“一键关机”的快捷方式图标,在该图标上单击鼠标右键,选择“属性”,再进入“快捷方式”页,然后在“快速键一栏内随便按选一个功能键(如F1-F12)。建议大家最好选一个平时不常用的功能键,最后按确定退出即可。

Windows系统通过一个名为shutdown.exe的程序来完成关机操作(位置Windows\\System32下),一般情况下Windows系统的关机都可以由关机程序 shutdown.exe来实现的,关机的时候调用shutdown.exe。由此可知要阻止强行关机就是要取消对shutdown.exe的调用。

使用C#代码实现控制Windows系统关机、重启和注销的方法,使用.NET和C#.NET,我们可以对当前PC执行关机,重启,注销操作,
.NET Framework中,有一个命名空间System.Diagnostics具有所需的类和方法,从当前PC上运行.NET应用程序来执行这些操作 。一般使用System.Diagnostics.Process.Start()方法来启动shutdown.exe程序。
下面是一个winform程序说明,使用按钮来执行关机,重启和注销。

 1         //关机 和 计时关机
 2         private void btnShutDown_Click(object sender, EventArgs e)
 3         {
 4             if (checkBox1.Checked)
 5             {
 6                 if (MessageBox.Show("将要设定计划关机,是否确认操作?", "提示", MessageBoxButtons.OKCancel) == DialogResult.OK)
 7                 {
 8                     decimal decl = numericUpDown1.Value * 3600 + numericUpDown2.Value * 60 + numericUpDown3.Value;
 9                     string str = decl.ToString();
10                     Process.Start("shutdown.exe", "-s -t " + str);//计时关机
11                 }
12             }
13             else
14             {
15                 if (MessageBox.Show("是否确认关机?", "提示", MessageBoxButtons.OKCancel) == DialogResult.OK)
16                 {
17                     Process.Start("shutdown.exe", "-s");//关机
18                     //Process.Start("shutdown.exe", "-s -t xx");
19                 }
20             }
21         }
22         //重启
23         private void butRestar_Click(object sender, EventArgs e)
24         {
25             if (MessageBox.Show("是否确认重启?", "提示", MessageBoxButtons.OKCancel) == DialogResult.OK)
26             {
27                 Process.Start("shutdown.exe", "-r");//重启
28                 Process.Start("shutdown.exe", "-r -t 10");
29             }
30         }
31         //注销
32         private void butLogOff_Click(object sender, EventArgs e)
33         {
34             if (MessageBox.Show("是否确认注销?", "提示", MessageBoxButtons.OKCancel) == DialogResult.OK)
35                 Process.Start("shutdown.exe", "-l");//注销
36         }
37 
38 
39 
40 
41 
42  
View Code

 完整示例

以上是关于c# 如何截获windows关机或注销消息的主要内容,如果未能解决你的问题,请参考以下文章

深入windows的关机消息截获-从XP到Win7的变化

C# 重写WndProc 拦截 发送 系统消息 + windows消息常量值

深入windows的关机消息截获-从XP到Win7的变化(在XP中程序可以阻止关机,但是在Win7中程序无法阻止关机,可Block的时间从1秒调到了5秒)

深入windows的关机消息截获-从XP到Win7的变化(在XP中程序可以阻止关机,但是在Win7中程序无法阻止关机,可Block的时间从1秒调到了5秒) good

如何让Win10在重启关机或注销时自动关闭应用程序

C#实现控制Windows系统关机重启和注销的方法: