有没有一种方法可以在发生电源事件时执行程序?


11

我基本上是在寻找一种在笔记本电脑转换为电池电源时以及类似地恢复为交流电源时执行应用程序的方法。

Windows或第三方应用程序中是否有内置挂钩可让我响应此类事件?

编辑

我研究了TaskScheduler,尝试在“电源”事件上触发任务,但是切换到电池时似乎没有事件记录。


为什么我有不祥的预感,我要去需要编写这个程序..
瑞安Emerle

一个应用程序可以运行,但是您可能只需要一个脚本。
bw

嘿,我参加聚会晚了大约六年,但是我觉得我值得一看……
FoxDeploy 2016年

Answers:


8

我编写了一个应用程序(http://batterysaver.codeplex.com/),它将监听电源模式更改消息并基于XML配置执行操作。

如果其他人可以使用或扩展它,那就太好了。如果有更好的东西,请发布。


作为增强,不是轮询GetSystemPowerStatus,而是创建一个应用程序来接收电源状态更改时Windows发送的WM_POWERBROADCAST消息:msdn.microsoft.com/en-us/library/aa373247%28VS.85%29.aspx
shf301

@ shf301-感谢您的提示;我更新了它以响应电源模式更改事件。
瑞安·埃默尔

@RyanEmerle尼斯应用!
摩押人2012年

@RyanEmerle同意非常好的应用程序!
Cosco Tech

如果要在电源事件中更改电池配置文件,应在配置中添加什么?
simongcc

4

不知道您可以为此运行一个简单的命令,但是脚本应该可以做到这一点。

尝试在PowerShellWSH中拦截Win32_PowerManagementEvent事件。该tomshardware文章包含一些vbscript代码,但我认为您将需要一个事件类型10(电源状态更改)的案例。StackOverflow在“我如何知道Windows何时进入/退出睡眠或休眠模式”方面有一些想法,尽管您必须将其概念扩展到处理电源状态更改,而不是睡眠/休眠。您可能还会在代码中找到关于以下问题的一些想法:一个人如何使用ManagementEventWatcher来跟踪挂起/恢复?

编辑:事实上,尝试这样的事情。这是完全被黑客入侵的,因此并不美观。如果检测到直流或交流电源发生变化,请更改Echo语句以执行所需的操作。与运行cscript power.vbs

电源

Dim battery_status, prev_status
prev_status = CheckBattery
Set colMonitoredEvents = GetObject("winmgmts:\\.\root\cimv2")._
    ExecNotificationQuery("Select * from Win32_PowerManagementEvent")
Do
    Set strLatestEvent = colMonitoredEvents.NextEvent
    If strLatestEvent.EventType = 10 Then
        battery_status = CheckBattery
        If battery_status <> prev_status Then
            If battery_status = 1 Then
                Wscript.Echo "DC power"
            ElseIf battery_status = 2 Then
                Wscript.Echo "AC power"
            End If
        End If
    End If
    prev_status = battery_status
Loop

Function CheckBattery
    Dim oWMI, items, item
    Set oWMI = GetObject("winmgmts:\\.\root\cimv2")
    Set items = oWMI.ExecQuery("Select * from Win32_Battery",,48)
    For Each item in items
        If item.BatteryStatus = 1 Then
            CheckBattery = 1
            Exit Function
        ElseIf item.BatteryStatus = 2 then
        CheckBattery = 2
            Exit Function
        End If
    Next
End Function

这个想法是在从一种状态转换到另一种状态时启动/停止应用程序,以节省电池电量。因此,我不想通过运行繁重的脚本(WMI有点繁重)来破坏目标。+1为详细答案。
瑞安·埃默尔

@Ryan-是的,是的。在这种情况下,注册为WM_POWERBROADCAST方法的应用程序更好。
bw

2

我喜欢Bill的方法,但是他没有告诉您如何在PowerShell中注册WMI事件,因此这里是这样做的方法。

如果您希望代码仅在系统电源状态更改时才触发(如此处所述),请使用此代码。

Register-WMIEvent -query "Select * From Win32_PowerManagementEvent" `
 -sourceIdentifier "Power" `
 -action {
     #YourCodeHere
      }

现在,无论电源状态发生变化(无论您插入设备还是拔出设备),这都会触发。因此,您可能还想停下来停顿一下问题:

我上电了吗?

幸运的是,我们可以通过WMI Class做到这一点BatteryStatus,所以这里是完整的构造,我只在电源事件发生变化时(并且仅当我不再使用Power时)才运行操作。

Register-WMIEvent -query "Select * From Win32_PowerManagementEvent" `
  -sourceIdentifier "Power" `
  -action {
      if ([BOOL](Get-WmiObject -Class BatteryStatus -Namespace root\wmi).PowerOnLine ){
         #Device is plugged in now, do this action
         write-host "Power on!"
     }
    else{
        #Device is NOT plugged in now, do this action
        write-host "Now on battery, locking..."
        [NativeMethods]::LockWorkStation()
     }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.