wordpress   发布时间:2022-04-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了winapi – Windows中的Hook系统电源按钮大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

我有一台运行自定义服务的无头计算机,我希望使用电源按钮启用/禁用,而不是每次都必须远程连接.计算机也会执行其他操作,因此不能选择将其关闭. 可以在Windows XP和Linux下挂钩系统电源按钮吗?这样,我的程序会在Windows启动掉电/睡眠事件之前(在PBT_APMQUERYSUSPEND事件发出之前)获得事件? 这确实是可能的,但它有点hackish,需要两个完全不同的实现,具体取决于Wi
我有一台运行自定义服务的无头计算机,我希望使用电源按钮启用/禁用,而不是每次都必须远程连接.计算机也会执行其他操作,因此不能选择将其关闭.

可以在Windows XP和Linux下挂钩系统电源按钮吗?这样,我的程序会在Windows启动掉电/睡眠事件之前(在PBT_APMQUERYSUSPEND事件发出之前)获得事件?

这确实是可能的,但它有点hackish,需要两个完全不同的实现,具体取决于Windows版本.对于这两种方法,您需要设置电源按钮以使计算机在电源选项中处于睡眠状态.

Windows XP及以下版本:

您需要覆盖程序的主窗口的WndProc函数.在本不支持功能的IDE上,可以使用user32 API中的SetWindowLong完成此操作.在自定义WndProc函数中,侦听WM_POWERBroaDCAST(0x218)消息.如果收到带有PBT_APMQUERYSUSPEND(0x0)的wParam的消息,请调用所需函数,然后返回BroaDCAST_QUERY_DENY(0x424D5144),而不是调用基本WndProc函数.示例代码

//At program start
//GWL_WNDPROC = -4
oldWndProc = SetWindowLong(this.hWnd,GWL_WNDPROC,&MyWndProC)

//In MyWndProc(hWnd,wMsg,wParam,lParam)
//WM_POWERBroaDCAST = 0x218
//PBT_APMQUERYSUSPEND = 0x0
//BroaDCAST_QUERY_DENY = 0x424D5144
if wMsg = WM_POWERBroaDCAST && wParam = PBT_APMQUERYSUSPEND (
    //CALL YOUR FUNCTION HERE!
    return BroaDCAST_QUERY_DENY
)
return CallWindowProc(oldWndProc,hWnd,lParam)

//Before exiTing
SetWindowLong(Me.hWnd,oldWndProC)

Windows Vista& up :(感谢Remy Lebeau让我走上正轨)

你需要像XP一样覆盖WndProc,还要调用kernel32 API中的SetThreadEXECUTIONState来禁用睡眠模式,并在user32 API中调用RegisterPowerSetTingNotification来监听高级电源通知.您将特别收听GUID_SYstem_AWAymODE通知,该通知在系统被要求进入睡眠状态时发送,但无法执行此操作.要轻松地将字符串转换为正确形成的LPCGUID,您可以在rpcrt4.dll API中使用UuidFromStringA.示例代码

typedef struct UUID{
    int d1,d2,d3,d4
} LPCGUID;

//At program start
//GWL_WNDPROC = -4
//ES_CONTinUOUS = 0x80000000
//ES_SYstem_required = 0x1
//ES_AWAymODE_required = 0x40
//GUID_SYstem_AWAymODE = "98a7f580-01f7-48aa-9c0f-44352c29e5C0"
LPCGUID uid;
oldWndProc = SetWindowLong(this.hWnd,&MyWndProC)
SetThreadEXECUTIONState(ES_CONTinUOUS | ES_SYstem_required | ES_AWAymODE_required)
UuidFromStringA(*(GUID_SYstem_AWAymODE),uid)
ps = RegisterPowerSetTingNotification(this.hWnd,uid,0)

//In MyWndProc(hWnd,lParam)
//WM_POWERBroaDCAST = 0x218
//PBT_POWERSETTinGCHANGE = 0x8013
if wMsg = WM_POWERBroaDCAST && wParam = PBT_POWERSETTinGCHANGE (
    //CALL YOUR FUNCTION HERE!
    //You can additionally extract data from the lParam to verify
    //this is the notification you're waiTing for (see below)
)
return CallWindowProc(oldWndProc,oldWndProC)
UnregisterPowerSetTingNotification(ps)

方法具有关闭物理屏幕的副作用(在无头机器上不是问题),也可能锁定会话.确保在睡眠后禁用提示输入密码以避免这种情况.有关RegisterPowerSetTingNotification here的一些其他有用信息,它们显示了如何从WndProc函数中的lParam中提取信息,以防您需要有关通知的其他信息.玩的开心

大佬总结

以上是大佬教程为你收集整理的winapi – Windows中的Hook系统电源按钮全部内容,希望文章能够帮你解决winapi – Windows中的Hook系统电源按钮所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。