Existe uma maneira de executar um programa em eventos de energia?

9

Estou basicamente procurando uma maneira de executar um aplicativo quando meu laptop transita para a energia da bateria e, da mesma forma, quando ele retorna ao AC.

Existe um gancho embutido no Windows ou em um aplicativo de terceiros que me permita responder a esses eventos?

EDITAR

Eu olhei para o TaskScheduler tentando disparar uma tarefa em um evento "power", mas nenhum evento parece ser registrado ao trocar para a bateria.

    
por Ryan Emerle 17.03.2010 / 19:09

3 respostas

6

Eu escrevi um aplicativo ( link ) que vai ouvir uma mensagem de mudança de modo de energia e executar ações com base em uma configuração XML.

Se alguém mais puder usá-lo ou estendê-lo, então é incrível. Se houver algo melhor, por favor poste.

    
por 17.03.2010 / 22:10
3

Não sabe de um comando simples que você pode executar para isso, mas o script deve ser capaz de fazer isso.

Tente interceptar o Win32_PowerManagementEvent evento em PowerShell ou WSH . O artigo da tomshardware tem algum código vbscript, mas acho que você precisará de um caso para eventtype 10 (powerstate change). O StackOverflow tem algumas ideias em Como posso saber quando o Windows entra / sai do modo de suspensão ou Hibernate? , embora seja necessário estender a ideia para lidar com a mudança de estado de energia em vez de dormir / hibernar. Você também pode encontrar algumas ideias no código para a pergunta Como usar o ManagementEventWatcher para manter o controle de suspensão / retomada?

EDIT: Na verdade, tente algo assim. Isso é totalmente cortado em conjunto, então não é bonito. Altere as instruções Echo para fazer o que quiser, se a mudança para alimentação DC ou AC for detectada. Executar com 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
    
por 17.03.2010 / 20:28
1

Eu adoro a abordagem de Bill, mas ele não diz como se inscrever para um evento WMI no PowerShell, então, aqui está como fazer isso.

Se você quiser que seu código seja acionado somente quando o estado de energia do sistema for alterado, como descrito aqui , use este código.

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

Agora, isso será acionado sempre que o estado de energia mudar, se você conectar o dispositivo ou desconectá-lo. Então você pode querer parar e fazer uma pausa para fazer a pergunta:

Am I on power or not?

Felizmente, podemos fazer isso por meio da classe WMI BatteryStatus , então aqui está a construção completa que uso para SOMENTE executar uma operação quando um evento de energia é alterado e somente se eu não estiver mais no 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()
     }
    
por 15.12.2016 / 21:49