Czy istnieje sposób na wykonanie programu w przypadku zdarzeń zasilania?

11

Zasadniczo szukam sposobu na wykonanie aplikacji, gdy mój laptop przejdzie na zasilanie bateryjne i podobnie, gdy wróci do prądu przemiennego.

Czy istnieje wbudowany hak w systemie Windows lub aplikacja innej firmy, która pozwoli mi reagować na takie zdarzenia?

EDYTOWAĆ

Zajrzałem do TaskScheduler próbującego odpalić zadanie po zdarzeniu „power”, ale żadne zdarzenie nie jest rejestrowane po przełączeniu na baterię.

Ryan Emerle
źródło
Dlaczego mam przeczucie, że będę musiał napisać tę aplikację ..
Ryan Emerle
Aplikacja działałaby, ale możesz potrzebować tylko skryptu.
mc
Hej, spóźniłem się na imprezę około sześciu lat, ale myślę, że mam coś wartego zobaczenia ...
FoxDeploy,

Odpowiedzi:

8

Napisałem aplikację ( http://batterysaver.codeplex.com/ ), która będzie nasłuchiwać komunikatu o zmianie trybu zasilania i wykonywać działania w oparciu o konfigurację XML.

Jeśli ktoś może go użyć lub rozszerzyć, to świetnie. Jeśli jest coś lepszego, opublikuj to.

Ryan Emerle
źródło
Jako rozszerzenie, zamiast odpytywania, GetSystemPowerStatus tworzy aplikację do odbierania komunikatów WM_POWERBROADCAST, które Windows wysyła, gdy stan zasilania zmienia się: msdn.microsoft.com/en-us/library/aa373247%28VS.85%29.aspx
shf301
@ shf301 - dziękuję za podpowiedź; Zaktualizowałem go, aby reagował na zdarzenie zmiany trybu zasilania.
Ryan Emerle,
@RyanEmerle Ładna aplikacja!
Moab
@RyanEmerle Uzgodniono bardzo fajną aplikację!
Cosco Tech,
Jeśli chcę zmienić profil baterii podczas zdarzeń zasilania, co powinienem dodać w konfiguracji?
simongcc
4

Nie znam prostej komendy, którą można by wykonać w tym celu, ale skrypty powinny być w stanie to zrobić.

Spróbuj przechwycić zdarzenie Win32_PowerManagementEvent w PowerShell lub WSH . Artykuł tomshardware zawiera kod vbscript, ale myślę, że będziesz potrzebować skrzynki dla eventtype 10 (zmiana powerstate). StackOverflow ma kilka pomysłów na Skąd mogę wiedzieć, kiedy system Windows przechodzi w tryb uśpienia lub hibernacji? , ale musisz rozszerzyć pomysł, aby obsługiwał zmianę stanu zasilania zamiast uśpienia / hibernacji. Możesz również znaleźć kilka pomysłów w kodzie na pytanie W jaki sposób można wykorzystać ManagementEventWatcher do śledzenia zawieszenia / wznowienia?

EDYCJA: W rzeczywistości spróbuj czegoś takiego. Jest to całkowicie zhakowane razem, więc nie jest ładne. Zmień instrukcje Echo, aby zrobić wszystko, co chcesz, jeśli zostanie wykryta zmiana zasilania DC lub AC. Biegnij zcscript 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
bw
źródło
Chodzi o to, aby uruchamiać / zatrzymywać aplikacje podczas przechodzenia z jednego stanu do drugiego w celu oszczędzania energii baterii. Dlatego nie chcę pokonać celu, uruchamiając ciężki skrypt (WMI jest nieco ciężki). +1 za szczegółową odpowiedź tys.
Ryan Emerle,
@ Ryan - cóż, tak. W takim przypadku lepsza jest aplikacja rejestrująca się w podejściu WM_POWERBROADCAST.
mc
2

Uwielbiam podejście Billa, ale on nie mówi ci, jak zarejestrować się na zdarzenie WMI w PowerShell, więc oto jak to zrobić.

Jeśli chcesz, aby kod był wyzwalany tylko po zmianie stanu zasilania systemu, jak opisano tutaj , użyj tego kodu.

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

Teraz uruchomi się za każdym razem, gdy zmieni się stan zasilania, niezależnie od tego, czy podłączysz urządzenie, czy je odłączysz. Możesz więc chcieć zatrzymać się i zatrzymać, aby zadać pytanie:

Czy mam moc, czy nie?

Na szczęście możemy to zrobić za pomocą klasy WMI BatteryStatus, więc oto pełna konstrukcja, której używam, aby WYŁĄCZNIE uruchamiać operację, gdy zmienia się zdarzenie mocy, i tylko wtedy, gdy nie mam już zasilania.

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()
     }
FoxDeploy
źródło