Что нового

Как получить информацию об изменении схемы питания компьютера.

A

at

Гость
Версия AutoIt: 3.3.6.1

Здравствуйте. Вопрос такого рода.

Когда отключается электричество, ноутбук переходит в режим питания от батареи. Тоже самое происходит и со стационарным ПК, работающим через ИБП.
Нужен скрипт, который будет информировать меня об изменении схемы питания.
 

VladUs

Скриптер
Сообщения
621
Репутация
181
Попробуйте так

Код:
local $objAsyncContext

$objWMIService = ObjGet("winmgmts:" & "!\\" & @ComputerName & "\root\cimv2")
$Sink = ObjCreate( "WbemScripting.SWbemSink")

ObjEvent($Sink , "SINK_")
$objContext = ObjCreate("WbemScripting.SWbemNamedValueSet")
$objWMIservice.ExecNotificationQueryAsync ($Sink, "SELECT * FROM Win32_PowerManagementEvent",Default, Default, Default, $objContext)

While 1
    Sleep(1000)
Wend

Func SINK_OnObjectReady($objObject, $objAsyncContext)
 If $objObject.EventType = 10 Then
     MsgBox(64,"Info", "Состояние электропитания изменено")
 EndIf
EndFunc
 
Автор
A

at

Гость
К сожалению не работает на стационарном ПК.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
VladUs
возможно, стоит засунуть SINK_OnObjectReady в AdlibRegister? иначе, я не вижу, где она вызывается
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Kaster [?]
возможно, стоит засунуть SINK_OnObjectReady в AdlibRegister?
Я, честно говоря, не понимаю, как этот код работает, но у меня он работает без проблем. Проверял на ноутбуке с Windows XPx86 SP3 - тупо отключал и подключал блок питания - и каждый раз получал MsgBox.
 

VladUs

Скриптер
Сообщения
621
Репутация
181
madmasles [?]
Я, честно говоря, не понимаю, как этот код работает

С комментариями:
Код:
local $objAsyncContext

; Подключаемся к пространству имен
$objWMIService = ObjGet("winmgmts:" & "!\\" & @ComputerName & "\root\cimv2")

; Создаем объект, получающий события в асинхронном режиме
$Sink = ObjCreate( "WbemScripting.SWbemSink") 

; Далее происходит регистрация на событие, где указывается, что обрабатывать данный объект($Sink ) 
; будет функция, имя которой  начинается с префикса "SINK_". В данном случае это и есть функция SINK_OnObjectReady. 
ObjEvent($Sink , "SINK_") 

;Создаем объект, для определения источника асинхронного вызова
$objContext = ObjCreate("WbemScripting.SWbemNamedValueSet")

; Делаем запрос к WMI на получение событий в асинхронном режиме
; где :
; $Sink - объект запроса
; "SELECT * FROM Win32_PowerManagementEvent" - строка запроса обращающаяся к классу "Win32_PowerManagementEvent"
; "SELECT * FROM Win32_PowerManagementEvent" - буквально можно перевести - "ВЫБОРКА * ИЗ Win32_PowerManagementEvent"
$objWMIservice.ExecNotificationQueryAsync ($Sink, "SELECT * FROM Win32_PowerManagementEvent",Default, Default, Default, $objContext)

While 1
    Sleep(1000)
Wend

; Функция обработчик  "SINK_OnObjectReady()"
; При получении события вызывается функция SINK_OnObjectReady() (Имя обработчика должно начинаться с префикса "SINK_")
; Параметры:
; $objObject - В данный параметр(переменную) передается  объект события $Sink с описанием произошедшего события
; $objAsyncContext - В данный параметр(переменную) передается источник события

Func SINK_OnObjectReady($objObject, $objAsyncContext)
 If $objObject.EventType = 10 Then
     MsgBox(64,"Info", "Состояние электропитания изменено")
 EndIf
EndFunc

; У класса Win32_PowerManagementEvent имеется свойство "EventType". Которое может принимать несколько значений 
; 4 - Ввод в спящий режим
; 7 - Выход из спящего режима
; 10 - Изменение состояния электропитания 
; 11 - OEM - событие (Даже не знаю, что это такое)

; В Функции-обработчике SINK_OnObjectReady()  мы указываем, что
; если произошло событие с типом = 10 (Изменение состояния электропитания),
; Сообщить об этом пользователю


Честно говоря, я этот код не проверял, не начем было проверить т.к не имею ноутбука, и ИБП. Но теоритически он должен работать
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
madmasles
понял. для ObjEvent важен префикс, а не название. поэтому и вызывается.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
С помощью подсказки Yashied`а:
Код:
#include <APIConstants.au3>;входит в комплект WinAPIEx

HotKeySet('{Esc}', '_Exit')

GUICreate('Test')
GUIRegisterMsg($WM_POWERBROADCAST, 'WM_POWERBROADCAST')

While 1
	Sleep(50)
WEnd

Func WM_POWERBROADCAST($hWnd, $Msg, $wParam, $lParam)
	Local Const $PBT_APMPOWERSTATUSCHANGE = 0xA
	If $wParam = $PBT_APMPOWERSTATUSCHANGE Then
		_Message()
	EndIf
EndFunc   ;==>WM_POWERBROADCAST

Func _Message()
	ToolTip('Состояние электропитания изменилось' & @LF & @MDAY & '.' & @MON & '.' & @YEAR & ' ' & _
			@HOUR & ':' & @MIN & ':' & @SEC, 0, 0, 'WM_POWERBROADCAST', 2)
EndFunc   ;==>_Message

Func _Exit()
	Exit
EndFunc   ;==>_Exit
Возможностей в функции WM_POWERBROADCAST() гораздо больше.
 
Автор
A

at

Гость
Спасибо Всем. Работают оба скрипта. Правда работает только на ноутбуке. На стационарном ПК молчат обе схемы. Почему ?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
at [?]
На стационарном ПК молчат обе схемы
Поэкспериментируйте с константами (WM_POWERBROADCAST)
Код:
;...
Func WM_POWERBROADCAST($hWnd, $Msg, $wParam, $lParam)
    Local Const $PBT_APMPOWERSTATUSCHANGE = 0xA
	ConsoleWrite($wParam & @LF);посмотрите, что покажет на стационарном ПК
    If $wParam = $PBT_APMPOWERSTATUSCHANGE Then
        _Message()
    EndIf
EndFunc
;...
 
Автор
A

at

Гость
Поэкспериментируйте с константами...

Попробовал подставлять эти значения:

PBT_APMRESUMEAUTOMATIC
PBT_APMRESUMESUSPEND
PBT_APMSUSPEND
PBT_POWERSETTINGCHANGE
PBT_APMBATTERYLOW
PBT_APMRESUMECRITICAL

Никакой реакции на переключение на батарею (стационарный ПК).
 
Автор
A

at

Гость
А в консоли что пишет?
Извиняюсь, плохо понял вопрос. Если вы говорите о консольном окне, то оно не появляется. Просматривал службы (ХР SP3), вроде все необходимое включено.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
at [?]
Извиняюсь, плохо понял вопрос
Бог с ней, с консолью. Что покажет ToolTip при включении-выключении питания?
Код:
#include <APIConstants.au3>;входит в комплект WinAPIEx

HotKeySet('{Esc}', '_Exit');выход

GUICreate('Test')
GUIRegisterMsg($WM_POWERBROADCAST, 'WM_POWERBROADCAST')

While 1
    Sleep(50)
WEnd

Func WM_POWERBROADCAST($hWnd, $Msg, $wParam, $lParam)
    Local Const $PBT_APMPOWERSTATUSCHANGE = 0xA
	ToolTip('$wParam: ' & $wParam, 0, 0)
EndFunc   ;==>WM_POWERBROADCAST

Func _Exit()
    Exit
EndFunc   ;==>_Exit
 
Верх