有没有办法在电源事件发生时执行程序?

有没有办法在电源事件发生时执行程序?

我基本上正在寻找一种当我的笔记本电脑转换为电池电源时以及当它返回交流电时执行应用程序的方法。

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

编辑

我研究过 TaskScheduler 尝试在“电源”事件上启动一项任务,但切换到电池时似乎没有记录任何事件。

答案1

我写了一个申请(http://batterysaver.codeplex.com/) 将监听电源模式改变消息并根据 XML 配置执行操作。

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

答案2

我喜欢 Bill 的方法,但他没有告诉你如何在 PowerShell 中注册 WMI 事件,因此这里介绍如何操作。

如果你希望代码仅在系统电源状态改变时触发,如这里所述,使用此代码。

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

现在,无论你插入还是拔出设备,只要电源状态发生变化,都会触发此操作。因此,你可能还想停下来问这个问题:

我有没有电?

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

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()
     }

答案3

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

尝试拦截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

答案4

结合任务计划程序和 Powershell 来执行此操作。

要实现 Powershell 脚本,请查看 Chris85 的回答: https://stackoverflow.com/a/62222256/1040683

然后在 Scheduler 中创建任务: https://www.reddit.com/r/Surface/comments/6coxgp/how_to_run_a_task_when_plugged_into_ac_or_losing/

相关内容