Is there a way to execute a program on power events?
Solution 1
I wrote an application (http://batterysaver.codeplex.com/) that will listen for a power mode change message and execute actions based on an XML configuration.
If someone else can use it, or extend it, then awesome. If there's something better, then please post it.
Solution 2
I love Bill's approach, but he doesn't tell you how to register for a WMI Event in PowerShell, so here's how to do it.
If you want your code to trigger only when the System Power State changes, as described here, use this code.
Register-WMIEvent -query "Select * From Win32_PowerManagementEvent" `
-sourceIdentifier "Power" `
-action {
#YourCodeHere
}
Now, this will trigger whenever the power state changes, whether you plug the device in, OR unplug it. So you might further want to stop and pause to ask the question:
Am I on power or not?
Fortunately we can do that via the WMI Class BatteryStatus
, so here's the full construct that I use to ONLY run an operation when a power event changes, and then only if I'm no longer on 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()
}
Solution 3
Don't know of a simple command you can run for this, but scripting should be able to do this.
Try intercepting the Win32_PowerManagementEvent event in PowerShell or WSH. The tomshardware article has some vbscript code, but i think you'll need a case for eventtype 10 (powerstate change). StackOverflow has some ideas at How can I know when Windows is going into/out of sleep or Hibernate mode?, though you'll have to extend the idea to handle power state change instead of sleep/hibernate. You might also find some ideas in the code for the question How does one use ManagementEventWatcher to keep track of suspend/resume?
EDIT: In fact, try something like this. This is totally hacked together, so it's not pretty. Change the Echo statements to do whatever you want if change to DC or AC power is detected. Run with cscript power.vbs
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
Related videos on Youtube
Ryan Emerle
Updated on September 17, 2022Comments
-
Ryan Emerle over 1 year
I'm basically looking for a way to execute an application when my laptop transitions to battery power and, similarly, when it returns to AC.
Is there a built-in hook in Windows or a third-party application that will allow me to respond to such events?
EDIT
I've looked into the TaskScheduler trying to fire off a task on a "power" event, but no event seems to be logged when switching to battery.
-
Ryan Emerle about 14 yearsWhy do I have the sinking feeling that I'm going to need to write this app..
-
FoxDeploy over 7 yearsHey man, I was about six years late to the party, but I think I've got something worth seeing...
-
-
Ryan Emerle about 14 yearsThe idea is to start/stop applications when transitioning from one state to another to conserve battery power. Therefore I don't want to defeat the purpose by running a heavy script (WMI is a bit heavy). +1 for the detailed answer tho.
-
shf301 about 14 yearsAs an enhancement, rather than polling GetSystemPowerStatus create an application to receive an WM_POWERBROADCAST messages that Windows sends when the power state changes: msdn.microsoft.com/en-us/library/aa373247%28VS.85%29.aspx
-
Ryan Emerle about 14 years@shf301 - thanks for the tip; I updated it to respond to the power mode change event.
-
b w about 14 years@Ryan - well, yeah. An application registering for WM_POWERBROADCAST approach is better in that case.
-
Cosco Tech about 9 years@RyanEmerle Agreed very nice app!
-
simongcc over 7 yearsIf I want to change battery profile in power events, what should I add in the config?
-
simongcc over 7 yearsI think I can execute
powercfg
to change, but there is parameters, how to pass these parameters in config? -
simongcc over 7 yearsI missed the argument input and got it now, it seems working, thanks a lot for the tools.