Hi there,
Is there a way to detect system Sleep / Standby mode like Enabled = (True / False) over W32 API, WMI or REG settings?
Thanks :)
Printable View
Hi there,
Is there a way to detect system Sleep / Standby mode like Enabled = (True / False) over W32 API, WMI or REG settings?
Thanks :)
Yes, many, depending on the precise level of detail desired (power APIs are absolutely insanely complicated).
There's a few deceptively simple APIs:
But MSDN seems to suggest they return whether the system is capable of those, not whether they're currently enabled.Code:Public Declare Function IsPwrSuspendAllowed Lib "PowrProf.dll" () As Byte
Public Declare Function IsPwrHibernateAllowed Lib "PowrProf.dll" () As Byte
Public Declare Function IsPwrShutdownAllowed Lib "PowrProf.dll" () As Byte
This will probably give better info, but much more complex:
Code:Public Declare Function GetCurrentPowerPolicies Lib "PowrProf.dll" (pGlobalPowerPolicy As GLOBAL_POWER_POLICY, pPowerPolicy As POWER_POLICY) As Byte
Public Enum SYSTEM_POWER_STATE
PowerSystemUnspecified = 0
PowerSystemWorking = 1
PowerSystemSleeping1 = 2
PowerSystemSleeping2 = 3
PowerSystemSleeping3 = 4
PowerSystemHibernate = 5
PowerSystemShutdown = 6
PowerSystemMaximum = 7
End Enum
Public Enum POWER_ACTION
PowerActionNone = 0
PowerActionReserved
PowerActionSleep
PowerActionHibernate
PowerActionShutdown
PowerActionShutdownReset
PowerActionShutdownOff
PowerActionWarmEject
PowerActionDisplayOff
End Enum
Public Enum PowerActionPolicyFlags
POWER_ACTION_QUERY_ALLOWED = &H00000001
POWER_ACTION_UI_ALLOWED = &H00000002
POWER_ACTION_OVERRIDE_APPS = &H00000004
POWER_ACTION_HIBERBOOT = &H00000008
POWER_ACTION_USER_NOTIFY = &H00000010 ' Indicate User-mode of an impending action.
POWER_ACTION_DOZE_TO_HIBERNATE = &H00000020
POWER_ACTION_ACPI_CRITICAL = &H01000000
POWER_ACTION_ACPI_USER_NOTIFY = &H02000000
POWER_ACTION_DIRECTED_DRIPS = &H04000000
POWER_ACTION_PSEUDO_TRANSITION = &H08000000
POWER_ACTION_LIGHTEST_FIRST = &H10000000
POWER_ACTION_LOCK_CONSOLE = &H20000000
POWER_ACTION_DISABLE_WAKES = &H40000000
POWER_ACTION_CRITICAL = &H80000000
End Enum
Public Enum PowerActionPolicyEvents
POWER_LEVEL_USER_NOTIFY_TEXT = &H00000001
POWER_LEVEL_USER_NOTIFY_SOUND = &H00000002
POWER_LEVEL_USER_NOTIFY_EXEC = &H00000004
POWER_USER_NOTIFY_BUTTON = &H00000008
POWER_USER_NOTIFY_SHUTDOWN = &H00000010 ' Application and Services are intimated of shutdown.
POWER_USER_NOTIFY_FORCED_SHUTDOWN = &H00000020 ' Immediate shutdown - Application and Services are not intimated.
POWER_FORCE_TRIGGER_RESET = &H80000000
End Enum
Public Type POWER_ACTION_POLICY
Action As POWER_ACTION
Flags As PowerActionPolicyFlags
EventCode As PowerActionPolicyEvents
End Type
Public Type GLOBAL_MACHINE_POWER_POLICY
Revision As Long
LidOpenWakeAc As SYSTEM_POWER_STATE
LidOpenWakeDc As SYSTEM_POWER_STATE
BroadcastCapacityResolution As Long
End Type
Public Enum PowerGlobalFlags
EnableSysTrayBatteryMeter = &H01
EnableMultiBatteryDisplay = &H02
EnablePasswordLogon = &H04
EnableWakeOnRing = &H08
EnableVideoDimDisplay = &H10
End Enum
Public Type GLOBAL_USER_POWER_POLICY
Revision As Long
PowerButtonAc As POWER_ACTION_POLICY
PowerButtonDc As POWER_ACTION_POLICY
SleepButtonAc As POWER_ACTION_POLICY
SleepButtonDc As POWER_ACTION_POLICY
LidCloseAc As POWER_ACTION_POLICY
LidCloseDc As POWER_ACTION_POLICY
DischargePolicy(0 To (NUM_DISCHARGE_POLICIES - 1)) As SYSTEM_POWER_LEVEL
GlobalFlags As PowerGlobalFlags
End Type
Public Enum PowerSettingAttribFlags
POWER_ATTRIBUTE_HIDE = &H00000001
POWER_ATTRIBUTE_SHOW_AOAC = &H00000002
End Enum
Public Const NEWSCHEME = -1
Public Type GLOBAL_POWER_POLICY
user As GLOBAL_USER_POWER_POLICY
mach As GLOBAL_MACHINE_POWER_POLICY
End Type
Public Type MACHINE_POWER_POLICY
Revision As Long ' 1
' meaning of power action "sleep"
MinSleepAc As SYSTEM_POWER_STATE
MinSleepDc As SYSTEM_POWER_STATE
ReducedLatencySleepAc As SYSTEM_POWER_STATE
ReducedLatencySleepDc As SYSTEM_POWER_STATE
' parameters for dozing
DozeTimeoutAc As Long
DozeTimeoutDc As Long
DozeS4TimeoutAc As Long
DozeS4TimeoutDc As Long
' processor policies
MinThrottleAc As Byte
MinThrottleDc As Byte
pad1(0 To 1) As Byte
OverThrottledAc As POWER_ACTION_POLICY
OverThrottledDc As POWER_ACTION_POLICY
End Type
Public Type USER_POWER_POLICY
Revision As Long ' 1
' "system idle" detection
IdleAc As POWER_ACTION_POLICY
IdleDc As POWER_ACTION_POLICY
IdleTimeoutAc As Long
IdleTimeoutDc As Long
IdleSensitivityAc As Byte
IdleSensitivityDc As Byte
' Throttling Policy
ThrottlePolicyAc As Byte
ThrottlePolicyDc As Byte
' meaning of power action "sleep"
MaxSleepAc As SYSTEM_POWER_STATE
MaxSleepDc As SYSTEM_POWER_STATE
' For future use
Reserved(0 To 1) As Long
' video policies
VideoTimeoutAc As Long
VideoTimeoutDc As Long
' hard disk policies
SpindownTimeoutAc As Long
SpindownTimeoutDc As Long
' processor policies
OptimizeForPowerAc As Byte
OptimizeForPowerDc As Byte
FanThrottleToleranceAc As Byte
FanThrottleToleranceDc As Byte
ForcedThrottleAc As Byte
ForcedThrottleDc As Byte
End Type
Public Type POWER_POLICY
user As USER_POWER_POLICY
mach As MACHINE_POWER_POLICY
End Type
Oh, thank you to getting me to right way ;) , I found something like this:
1. If the computer supports the sleep states (S1, S2, and S3), the function returns TRUE. Otherwise, the function returns FALSE.
2. If the computer supports hibernation (power state S4) and the file Hiberfil.sys is present on the system, the function returns TRUE. Otherwise, the function returns FALSE.Code:Declare Function IsPwrSuspendAllowed Lib "Powrprof.dll" () As Long
I need to work on additional code tunings...Code:Declare Function IsPwrHibernateAllowed Lib "Powrprof.dll" () As Long
Don't change Byte to Long; it's a BOOLEAN in the C++ source, that's a 1-byte type.
Also, playing around with it, the "Put the computer to sleep after" value seems to be .user.IdleTimeoutAc (outlet) / .user.IdleTimeoutDc (battery)
So to check if it's enabled, check if it's non-zero (it's given in milliseconds, 0 is never)
When I want to detect whether a system has just awoken from sleep I have used a stored timer and compared it against current system time, if there is a discrepancy greater than the timer interval I assume the system has been to sleep... At least that is how I did it in .js, it may be applicable to VB6. If anyone knows a better way?
Listen for WM_POWERBROADCAST messages, or for Win8+ PowerRegisterSuspendResumeNotification.
Or if you want to know but weren't running at the time to log it,
Code:Public Enum POWER_INFORMATION_LEVEL
SystemPowerPolicyAc
SystemPowerPolicyDc
VerifySystemPolicyAc
VerifySystemPolicyDc
SystemPowerCapabilities
SystemBatteryState
SystemPowerStateHandler
ProcessorStateHandler
SystemPowerPolicyCurrent
AdministratorPowerPolicy
SystemReserveHiberFile
ProcessorInformation
SystemPowerInformation
ProcessorStateHandler2
LastWakeTime ' Compare with KeQueryInterruptTime()
LastSleepTime ' Compare with KeQueryInterruptTime()
SystemExecutionState
SystemPowerStateNotifyHandler
ProcessorPowerPolicyAc
ProcessorPowerPolicyDc
VerifyProcessorPowerPolicyAc
VerifyProcessorPowerPolicyDc
ProcessorPowerPolicyCurrent
SystemPowerStateLogging
SystemPowerLoggingEntry
SetPowerSettingValue
NotifyUserPowerSetting
PowerInformationLevelUnused0
SystemMonitorHiberBootPowerOff
SystemVideoState
TraceApplicationPowerMessage
TraceApplicationPowerMessageEnd
ProcessorPerfStates
ProcessorIdleStates
ProcessorCap
SystemWakeSource
SystemHiberFileInformation
TraceServicePowerMessage
ProcessorLoad
PowerShutdownNotification
MonitorCapabilities
SessionPowerInit
SessionDisplayState
PowerRequestCreate
PowerRequestAction
GetPowerRequestList
ProcessorInformationEx
NotifyUserModeLegacyPowerEvent
GroupPark
ProcessorIdleDomains
WakeTimerList
SystemHiberFileSize
ProcessorIdleStatesHv
ProcessorPerfStatesHv
ProcessorPerfCapHv
ProcessorSetIdle
LogicalProcessorIdling
UserPresence
PowerSettingNotificationName
GetPowerSettingValue
IdleResiliency
SessionRITState
SessionConnectNotification
SessionPowerCleanup
SessionLockState
SystemHiberbootState
PlatformInformation
PdcInvocation
MonitorInvocation
FirmwareTableInformationRegistered
SetShutdownSelectedTime
SuspendResumeInvocation ' Deprecated
PlmPowerRequestCreate
ScreenOff
CsDeviceNotification
PlatformRole
LastResumePerformance
DisplayBurst
ExitLatencySamplingPercentage
RegisterSpmPowerSettings
PlatformIdleStates
ProcessorIdleVeto ' Deprecated.
PlatformIdleVeto ' Deprecated.
SystemBatteryStatePrecise
ThermalEvent
PowerRequestActionInternal
BatteryDeviceState
PowerInformationInternal
ThermalStandby
SystemHiberFileType
PhysicalPowerButtonPress
QueryPotentialDripsConstraint
EnergyTrackerCreate
EnergyTrackerQuery
UpdateBlackBoxRecorder
SessionAllowExternalDmaDevices
SendSuspendResumeNotification
BlackBoxRecorderDirectAccessBuffer
PowerInformationLevelMaximum
End Enum
Public Declare Function NtPowerInformation Lib "ntdll" (ByVal InformationLevel As POWER_INFORMATION_LEVEL, InputBuffer As Any, ByVal InputBufferLength As Long, OutputBuffer As Any, ByVal OutputBufferLength As Long) As Long
Sub LastSleepWake()
Dim t1 As LongLong, t2 As LongLong
Dim status As Long
status = NtPowerInformation(LastSleepTime, ByVal 0, 0, t1, LenB(t1))
Debug.Print "System last slept " & CStr(t1 / 10000000^) & " seconds ago"
status = NtPowerInformation(LastWakeTime, ByVal 0, 0, t2, LenB(t2))
Debug.Print "System last woke " & CStr(t2 / 10000000^) & " seconds ago"
Debug.Print "System last slept for " & CStr((t2 - t1) / 10000000^) & " seconds"
End Sub
'Or without LongLong
Sub LastSleepWake()
Dim t1 As Currency, t2 As Currency
Dim status As Long
status = NtPowerInformation(LastSleepTime, ByVal 0, 0, t1, LenB(t1))
Debug.Print "System last slept " & CStr((t1 / 10000000@) * 10000) & " seconds ago"
status = NtPowerInformation(LastWakeTime, ByVal 0, 0, t2, LenB(t2))
Debug.Print "System last woke " & CStr((t2 / 10000000@) * 10000) & " seconds ago"
Debug.Print "System last slept for " & CStr(((t2 - t1) / 10000000^) * 10000) & " seconds"
End Sub
I don't know that, but it's working fine, I found the details here http://allapi.mentalis.org/apilist/I...dAllowed.shtml
Now I just need to figure out the rest somehow!
In my experience it really doesn't matter what the return type of an API function is in the documentation. When it comes to VB6, "Long" will always work no matter what.
Well that's just wrong.
You can get away with widening to 4 bytes because of how the _stdcall calling convention works, but it's bad practice.
You *can't* get away with substituting a Long for an 8-byte argument like LongLong.
Figure out what? If you really wanted to know if it's possible to enable it, you're done. If you need know if it is enabled, it's 3 lines of code just checking if that IdleTime is > 0. Or a fancier one if you're worried about it being different for on/off battery and want the current status:
Code:'Declares already provided, and:
Public Type SYSTEM_POWER_STATUS
ACLineStatus As Byte
BatteryFlag As Byte
BatteryLifePercent As Byte
SystemStatusFlag As Byte
BatteryLifeTime As Long
BatteryFullLifeTime As Long
End Type
Public Enum SYSTEM_AC_LINE_STATUS
AC_LINE_OFFLINE = &H0
AC_LINE_ONLINE = &H1
AC_LINE_BACKUP_POWER = &H2
AC_LINE_UNKNOWN = &HFF
End Enum
Public Declare Function GetSystemPowerStatus Lib "kernel32" (lpSystemPowerStatus As SYSTEM_POWER_STATUS) As Long
Function IsSleepEnabled() As Boolean
Dim status As SYSTEM_POWER_STATUS
GetSystemPowerStatus status
Dim p1 As GLOBAL_POWER_POLICY, p2 As POWER_POLICY
GetCurrentPowerPolicies p1, p2
If status.ACLineStatus = AC_LINE_ONLINE Then
IsSleepEnabled = ((p2.user.IdleTimeoutAc > 0)
Else
IsSleepEnabled = ((p2.user.IdleTimeoutDc > 0)
End If
End Function
Oh, thanks, but can't test it, it seems that some declarations/references are missing:
But to don't get to any confusion, I wish to be able to detect Sleep (Standby / Suspend) mode and if it's Enabled, in that case I could put/send the system (Desktop / Laptop) to Sleep mode (not Hibernate).Code:DischargePolicy(0 To (NUM_DISCHARGE_POLICIES - 1)) As SYSTEM_POWER_LEVEL
Putting system into Sleep (Standby / Suspend) mode:
Putting system into Hibernate (Hibernation) mode:Code:Private Declare Function SetSuspendState Lib "Powrprof.dll" (ByVal Hibernate As Long, ByVal ForceCritical As Long, ByVal DisableWakeEvent As Long) As Long
Public Function IsSleepEnabled() As Boolean
On Error Resume Next
' Here would need a new code
Exit Function
End Function
Private Sub sys_Sleep()
On Error Resume Next
Call SetSuspendState(0, 0, 0) ' 0 indicates Sleep (Standby / Suspend) mode
Exit Sub
End Sub
I think that the "Hibernation" part is Okay,...Code:Private Declare Function IsPwrHibernateAllowed Lib "Powrprof.dll" () As Long
Private Declare Function SetSuspendState Lib "Powrprof.dll" (ByVal Hibernate As Long, ByVal ForceCritical As Long, ByVal DisableWakeEvent As Long) As Long
Public Function IsHibernationEnabled() As Boolean
On Error Resume Next
Dim lgRet As Long
lgRet = IsPwrHibernateAllowed
IsHibernationEnabled = CBool(lgRet)
Exit Function
End Function
Private Sub sys_Hibernate()
On Error Resume Next
Call SetSuspendState(1, 0, 0) ' 1 indicates Hibernation mode
Exit Sub
End Sub
But I have some doubts regarding "Sleep (Standby / Suspend), because with the current code I can get/detect only if the system is capable of S1, S2 and S3 mode:
Also thank you for helping me out! ;)Code:Private Declare Function IsPwrSuspendAllowed Lib "Powrprof.dll" () As Long
Private Declare Function SetSuspendState Lib "Powrprof.dll" (ByVal Hibernate As Long, ByVal ForceCritical As Long, ByVal DisableWakeEvent As Long) As Long
Public Function IsSleepEnabled() As Boolean
On Error Resume Next
Dim lgRet As Long
lgRet = IsPwrSuspendAllowed
IsStandbyEnabled = CBool(lgRet)
Exit Function
End Function
Private Sub sys_Sleep()
On Error Resume Next
Call SetSuspendState(0, 0, 0) ' 0 indicates Sleep (Standby / Suspend) mode
Exit Sub
End Sub
I'm trying to wrap my mind around the fact, that OP wants to write Code to check if the computer the code is running on is in one of those sleep-"states"
https://learn.microsoft.com/en-us/wi...leeping-states
Quote:
States S1, S2, S3, and S4 are the sleeping states. A system in one of these states is not performing any computational tasks and appears to be off
Whoever told you that?????
If with "Always On" you mean the "Power-Managment-Schema" in Control-Panel:
That one just prevents the Computer to go to sleep automatically.
Noone is going to prevent the user to click on Start - Power saving mode (or whatever it's called. German Windows here), forcing the Computer into that Sleep-States
EDIT: As for your question, if PM is enabled via Reg:
Check out Reg-Key
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power
Happy hunting
See my Edit above
Looking through that key, i found this one:
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\PDC\Activators\Default\VetoPolicy
with a Key "EA:EnergySaverEngaged" which on my Computer has the Value 0 (which is correct, since my Laptop is on "Always On")
Maybe play around a bit, and check if the value changes
...come on, you can google a single missing constant and enum... sorry I only did 99% of the work for you.
Anyway, the code I posted tells you if it's enabled or not-- the 'Put the computer to sleep after' option or under advanced options, it covers both 'Sleep after' and 'Hibernate after', and yes you know by the fact you're running you're not in sleep mode.Code:Public Const NUM_DISCHARGE_POLICIES = 4
Public Type SYSTEM_POWER_LEVEL
Enable As Byte
Spare(0 To 2) As Byte
BatteryLevel As Long
PowerPolicy As POWER_ACTION_POLICY
MinSystemState As SYSTEM_POWER_STATE
End Type
The IsPwrHibernateAllowed function like the others also only indicates whether it's supported, not whether it'd enabled.
Let me see that one, I found something like this:
with Key and Value:Code:Computer\HKEY_CURRENT_USER\Control Panel\PowerCfg
Here is the description of the returned Value:Code:CurrentPowerPolicy
0
But, for example for me it's returning 0, weird thing is that I have a bunch of stuffs disabled in "Power Management", Hibernation, Monitor, etc... except for the HDD spin up.Code:Power Scheme (Default="0")
"0" = Home/Office Desk
"1" = Portable/Laptop
"2" = Presentation
"3" = Always On
"4" = Minimal Power Management
"5" = Max Battery
@fafalone It worked, need some more live test, but it's working as intended!
Thank you! ;)
You're welcome, glad it works for you :)