无法捕获睡眠/挂起消息 (winXP)
我的应用程序需要阻止睡眠/休眠模式。 我已准备好代码,但在成功捕获 WM_POWERBROADCAST 消息后,PBT_APMQUERYSUSPEND 和 PBT_APMQUERYSTANDBY 均未成功捕获。 有趣的是,我的应用程序正在捕获 PBT_APMRESUMECRITICAL 和 PBT_APMRESUMEAUTOMATIC 消息。
底线问题:是否有任何原因导致我的应用程序无法捕获待机/挂起消息,但成功捕获恢复消息?
此问答 [stackoverflow .com] 有帮助,顺便说一句,但同样,这些消息似乎没有进入我的应用程序。
我的代码(为简洁起见,删除了事件日志记录代码):
protected override void WndProc(ref System.Windows.Forms.Message m)
{
// Power status event triggered
if (m.Msg == (int)NativeMethods.WindowMessage.WM_POWERBROADCAST)
{
// Machine is trying to enter suspended state
if (m.WParam.ToInt32() == (int)NativeMethods.WindowMessage.PBT_APMQUERYSUSPEND ||
m.WParam.ToInt32() == (int)NativeMethods.WindowMessage.PBT_APMQUERYSTANDBY)
{
// Have perms to deny this message?
if((m.LParam.ToInt32() & 0x1) != 0)
{
// If so, deny broadcast message
m.Result = new IntPtr((int)NativeMethods.WindowMessage.BROADCAST_QUERY_DENY);
}
}
return; // ?!
}
base.WndProc(ref m);
}
My app needs to block sleep/hibernate mode. I have the code in place, but after successfully catching the WM_POWERBROADCAST message, neither PBT_APMQUERYSUSPEND nor PBT_APMQUERYSTANDBY are being caught successfully. Interestingly, the PBT_APMRESUMECRITICAL and PBT_APMRESUMEAUTOMATIC messages are being caught by my app.
Bottom line question: is there any reason why my app would fail to catch the standby/suspend messages, but succeed in catching the resume messages?
This Q&A [stackoverflow.com] helped, btw, but again, the messages don't seem to be making it to my app.
My code (w/ event logging code removed for brevity):
protected override void WndProc(ref System.Windows.Forms.Message m)
{
// Power status event triggered
if (m.Msg == (int)NativeMethods.WindowMessage.WM_POWERBROADCAST)
{
// Machine is trying to enter suspended state
if (m.WParam.ToInt32() == (int)NativeMethods.WindowMessage.PBT_APMQUERYSUSPEND ||
m.WParam.ToInt32() == (int)NativeMethods.WindowMessage.PBT_APMQUERYSTANDBY)
{
// Have perms to deny this message?
if((m.LParam.ToInt32() & 0x1) != 0)
{
// If so, deny broadcast message
m.Result = new IntPtr((int)NativeMethods.WindowMessage.BROADCAST_QUERY_DENY);
}
}
return; // ?!
}
base.WndProc(ref m);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
尝试订阅 PowerModeChanged 事件:
如何检查计算机何时进入睡眠或唤醒状态?
Try to subscribe the PowerModeChanged event:
How do I check when the computer is being put to sleep or wakes up?
您运行的是 Vista 还是 Windows Server 2008? 此页面说
这可能是您没有看到它的原因吗?
Are you running on Vista or Windows Server 2008? This page says
Could that be why you're not seeing it?
我在我的(开发)机器上的测试应用程序中尝试了相同的代码 在不同的(测试)机器(也是winXP)上。 在我的机器上,它继续失败,这意味着机器进入睡眠状态。 但在另一台机器上,它可以工作! 起初我以为这是调试与发布模式的问题,但事实并非如此。
我的开发机器似乎有些不同,尽管我不知道它可能是什么。
谜团解开了……有点。
I tried this same code in a test app on my (dev) machine & on a different (test) machine (also winXP). On my machine, it continues to fail, meaning the machine goes into sleep. But on the other machine, it works! At first I thought this was a debug vs release mode issue, but that's not the case.
It seems that something is different about my dev machine, though I have no idea what it could be.
Mystery solved... sorta.
在 Vista 中,调用 SetThreadExecutionState 来通知 WPM 系统不空闲。
在 Windows XP/2000 中:
应用程序可以返回 BROADCAST_QUERY_DENY 以拒绝 PBT_APMQUERYSUSPEND 或 PBT_APMQUERYSUSPENDFAILED 请求。
微软软件定义网络:
Windows XP 及更早版本:系统广播 PBT_APMQUERYSUSPEND 事件以请求暂停系统操作的权限。 系统期望每个应用程序和驱动程序确定所请求的事件是否应该发生,如果发生则返回 TRUE,否则返回 BROADCAST_QUERY_DENY。 应用程序不应拒绝此请求。 如果应用程序拒绝此请求,系统将广播 PBT_APMQUERYSUSPENDFAILED 事件。 此事件通知应用程序和驱动程序继续照常运行。
另外,我认为 Win2K 不支持 PBT_APMQUERYSTANDBY 或 PBT_APMSSTANDBY。 您是否尝试过在 Windows 关闭时全局记录广播以查看它们是否正在发送?
In Vista call SetThreadExecutionState to notify WPM that system is not idle.
In Windows XP/2000:
An application can return BROADCAST_QUERY_DENY to deny a PBT_APMQUERYSUSPEND or PBT_APMQUERYSUSPENDFAILED request.
MSDN:
Windows XP and earlier: The system broadcasts a PBT_APMQUERYSUSPEND event to request permission to suspend system operation. The system expects each application and driver to determine whether the requested event should occur and to return TRUE if it occurs, or return BROADCAST_QUERY_DENY otherwise. Applications should not deny this request. If an application denies this request, the system broadcasts a PBT_APMQUERYSUSPENDFAILED event. This event notifies applications and drivers to continue operation as usual.
Also I don't think either PBT_APMQUERYSTANDBY or PBT_APMSTANDBY are supported in Win2K. Have you tried gloablly logging broadcast when Windows shuts down to see if they are being sent?
现在它适用于 XP 和 Vista。 我使用相关代码创建了一个存根 winform 应用程序(显然可以清理,但它传达了要点)。
It works now, for both XP and Vista. I created a stub winform app with the relevant code (could be cleaned up, obviously, but it conveys the point).