web-dev-qa-db-ja.com

電源イベントでプログラムを実行する方法はありますか?

私は基本的に、ラップトップがバッテリー電源に移行したとき、および同様にACに戻ったときにアプリケーションを実行する方法を探しています。

そのようなイベントに応答できるようにするWindowsまたはサードパーティアプリケーションの組み込みフックはありますか?

[〜#〜]編集[〜#〜]

「電源」イベントでタスクを起動しようとしているTaskSchedulerを調べましたが、バッテリーに切り替えたときにイベントがログに記録されていないようです。

11
Ryan Emerle

電源モード変更メッセージをリッスンし、XML構成に基づいてアクションを実行するアプリケーション( http://batterysaver.codeplex.com/ )を作成しました。

他の誰かがそれを使用したり、拡張したりできるなら、それは素晴らしいことです。もっと良いものがあれば、投稿してください。

8
Ryan Emerle

このために実行できる簡単なコマンドはわかりませんが、スクリプトで実行できるはずです。

Win32_PowerManagementEvent イベントを PowerShell または [〜#〜] wsh [〜#〜] 。 tomshardwareの記事にはいくつかのvbscriptコードが含まれていますが、イベントタイプ10(電源状態の変更)のケースが必要になると思います。 StackOverflowにはいくつかのアイデアがあります Windowsがスリープモードまたは休止状態モードに入る/出るときを知るにはどうすればよいですか? ただし、拡張する必要がありますスリープ/休止状態の代わりに電源状態の変化を処理するというアイデア。質問のコードにいくつかのアイデアが見つかるかもしれません ManagementEventWatcherを使用してサスペンド/レジュームを追跡するにはどうすればよいですか?

編集:実際には、このようなことを試してください。これは完全に一緒にハッキングされているので、きれいではありません。 DCまたはAC電源への変更が検出された場合は、Echoステートメントを変更して必要な処理を実行します。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
4
b w

Billのアプローチは気に入っていますが、PowerShellでWMIイベントに登録する方法を教えてくれないので、その方法を説明します。

システムの電源状態が変化したときにのみコードをトリガーする場合は、 ここで説明 、このコードを使用します。

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

これで、デバイスを接続するかどうかに関係なく、電源状態が変化するたびにこれがトリガーされます。ORプラグを抜いてください。さらに停止して一時停止し、質問をすることをお勧めします。

私は電源が入っているかどうか?

幸い、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()
     }
2
FoxDeploy