WASAPI 阻止 Windows 自动挂起?

发布于 2024-07-14 22:17:48 字数 397 浏览 5 评论 0原文

第一次发帖,请温柔一点;-)

我正在编写一个音频应用程序(用 C++ 编写),它作为 Windows 服务运行,使用 WASAPI 从 jack 线路中获取样本,并对其进行一些处理。

我注意到,当我的应用程序“录制”时,Windows 不会自动挂起或休眠。

我已经注册了电源事件通知,如果我自己按下暂停按钮,我的服务会获取适当的电源事件并正常处理它们。 如果我让系统自行挂起,则永远不会收到电源事件。

如果我删除引用 WASAPI 的代码位,则在手动和自动挂起时都会正常接收电源事件。 因此,似乎使用 WASAPI 会告诉 Windows 忽略自动挂起计时器。

谁能帮助解释这种行为,我能做些什么来阻止它吗? 我不希望我的应用程序成为行为不当并阻止系统挂起的应用程序之一。

First time poster, be gentle ;-)

I'm writing an audio app (in C++) which runs as a Windows service, uses WASAPI to take samples from the line in jack, and does some processing on it.

Something I've noticed is that when my app is "recording", Windows won't automatically suspend or hibernate.

I've registered for power event notifications and, if I push the suspend button myself, my service gets the appropriate power events and handles them ok. If I leave the system to suspend on its own, the power events are never received.

If I remove the bits of code where I reference WASAPI, the power events are received as normal on both manual and automatic suspend. So it seems like there's something about using WASAPI that tells Windows to ignore the automatic suspend timer.

Can anyone help explain this behavior, and is there anything I can do to stop it? I don't want my app to be one of those which misbehaves and prevents systems from suspending..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

孤单情人 2024-07-21 22:17:48

不幸的是,没有任何机制可以执行您想要的操作 - 打开音频流会阻止电源状态转换,就像通过网络打开文件以及许多其他操作中的任何一项一样。

这是音频驱动程序 (portcls.sys) 的功能,而不是 WASAPI,也不是 Vista 的新行为 - 我相信 XP 和 Win2K 具有类似的行为(尽管电源状态转换在 Vista 上比 XP 上可靠得多)和Win2K,因此用户往往更依赖它们)。

在 Windows 7 上,您可以使用“powercfg -requests”来查找系统的任何部分是否阻止计算机进入睡眠状态。 有关详细信息,请访问此处

Unfortuantely there's no mechanism to do what you want - opening an audio stream prevents power state transitions as does opening a file up over the network and any one of a number of other things.

This is a function of the audio driver (portcls.sys) and not WASAPI and is not a new behavior for Vista - I believe that XP and Win2K had similar behaviors (although power state transitions are much more reliable on Vista than they were on XP and Win2K so users tend to depend on them more).

On Windows 7 you can use the "powercfg -requests" to find if any parts of the system are preventing a machine from entering sleep. More information on that can be found here

如果没结果 2024-07-21 22:17:48

非常感谢拉里确认这种行为是设计使然,而不是我做了一些愚蠢的事情。

为了解决此问题,我使用 Win32 CallNtPowerInformation() API 来检索系统空闲计时器:

SYSTEM_POWER_INFORMATION spi = {0};
NTSTATUS status = CallNtPowerInformation(SystemPowerInformation, NULL, 0, 
                                         &spi, sizeof(spi));

if (NT_SUCCESS(status) && (spi.TimeRemaining==0))
{
    // should have gone to sleep
}

spi.TimeRemaining 成员从指定的时间开始倒计时(以秒为单位)控制面板中的用户,例如“1 小时后系统待机”,只要 CPU 使用率(以百分比形式)高于 spi.MaxIdlenessAllowed 就会重置。

如果 spi.TimeRemaining 达到零,系统应该进入睡眠状态,因此我关闭所有 WASAPI 句柄并让它这样做。

Many thanks to Larry for confirming this behaviour is by design and not me doing something silly.

To work around this issue I used the Win32 CallNtPowerInformation() API to retrieve the system idle timer:

SYSTEM_POWER_INFORMATION spi = {0};
NTSTATUS status = CallNtPowerInformation(SystemPowerInformation, NULL, 0, 
                                         &spi, sizeof(spi));

if (NT_SUCCESS(status) && (spi.TimeRemaining==0))
{
    // should have gone to sleep
}

The spi.TimeRemaining member counts down (in seconds) from the time specified by the user in Control Panel e.g. "System standby after 1 hour", and gets reset whenever CPU usage (as a percentage) rises above spi.MaxIdlenessAllowed.

If spi.TimeRemaining ever reaches zero, the system should have gone to sleep, so I close all my WASAPI handles and let it do so.

萌逼全场 2024-07-21 22:17:48

我相信电源管理 API 中有一个函数,它允许应用程序告诉操作系统它不希望系统在一段时间内进入省电模式(我认为这是一个开/关类型的函数)。 如果 WASAPI 中的某些内容正在调用该方法,您可能无能为力。 这对于硬件按钮行为来说是有意义的,因为电源管理服务不会被迫根据电源模式的激活方式来满足应用程序请求。

至于解决方法,我不知道。 我可能尝试的一件事是从电源管理 API 读取省电超时信息,然后在系统接近省电阈值时暂停录制; 我不知道那会有多难。 祝你好运。 :)

I believe there's a function in the power management API which allows an app to tell the OS that it doesn't want the system to go into power save mode during some time (I think it's an on/off type function). If something in WASAPI is calling that method, there may be nothing you can do. This would make sense with the hardware button behavior, since the power management service isn't forced to honor the app request depending on how the power mode is activated.

As for work-around, I don't know. One thing I might try is to read the power save timeout information from the power management API, and then suspend recording if the system is nearing the power save threshold; I have no idea how hard that would be though. Good luck. :)

征﹌骨岁月お 2024-07-21 22:17:48

我可能尝试的一件事是从电源管理 API 读取省电超时信息,然后在系统接近省电阈值时暂停录制;

一个好主意——但我认为很难。 省电超时应该可以使用电源管理 API 读取,但您还需要知道当前用户输入空闲状态,这是无法从 Windows 服务读取的。

One thing I might try is to read the power save timeout information from the power management API, and then suspend recording if the system is nearing the power save threshold;

A good idea - but quite hard I think. The power save timeout should be readable using power management API, but you'd also need to know the current user input idle state, which is not readable from a Windows service.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文