Windows挂起之前的剩余时间

Time left until Windows suspend

本文关键字:时间 余时间 挂起 Windows      更新时间:2023-10-16

有没有办法查询窗口在进入挂起/睡眠模式之前还有多少时间?

我使用的是vbscript,怀疑可能有WMI的答案,但任何语言,如c/c++、*.NET,甚至java,如果可能的话,都可以满足我的需求。

编辑

我希望能够用一个方法查询Windows,而不是在它即将挂起时被事件提醒。

由于Windows将尝试尽快完成进入S3(睡眠)或S4(休眠),因此没有API可以知道剩余的时间。

Windows将向所有进程发送有关挂起的电源状态更改的通知,并允许应用程序为该事件做好准备。

你可以在这里找到你需要的大部分东西。

基本上,您有20秒的时间来处理第一条消息。您的进程可能会延迟回复消息,处理所有各种电源循环任务,例如关闭文件、保存状态等。

您可能需要调用CallNtPowerInformation API函数,该函数采用以下参数:

NTSTATUS WINAPI CallNtPowerInformation(
  _In_  POWER_INFORMATION_LEVEL InformationLevel,
  _In_  PVOID                   lpInputBuffer,
  _In_  ULONG                   nInputBufferSize,
  _Out_ PVOID                   lpOutputBuffer,
  _In_  ULONG                   nOutputBufferSize
);

InformationLevel参数中,您传递SystemPowerInformation枚举值,该值用SYSTEM_POWER_INFORMATION结构填充lpOutputBuffer

typedef struct _SYSTEM_POWER_INFORMATION {
  ULONG MaxIdlenessAllowed;
  ULONG Idleness;
  ULONG TimeRemaining;
  UCHAR CoolingMode;
} SYSTEM_POWER_INFORMATION, *PSYSTEM_POWER_INFORMATION;

然后得到以秒为单位的TimeRemaining

edit:在VB.NET中测试。编辑:已添加代码。

Queryer.vb

Imports System.Runtime.InteropServices
Public Class Queryer
    Const SystemPowerInformation As Integer = 12
    Const STATUS_SUCCESS As Integer = 0
    Private Structure SYSTEM_POWER_INFORMATION
        Public MaxIdlenessAllowed As UInteger
        Public Idleness As UInteger
        Public TimeRemaining As Integer
        Public CoolingMode As Byte
    End Structure
    <DllImport("PowrProf.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    Public Shared Function CallNtPowerInformation(
            ByVal InformationLevel As Int32,
            ByVal lpInputBuffer As IntPtr,
            ByVal nInputBufferSize As UInt32,
            ByVal lpOutputBuffer As IntPtr,
            ByRef nOutputBufferSize As UInt32) As UInt32
    End Function
    Public Function Query() As Integer
        Dim PowerInformation As SYSTEM_POWER_INFORMATION
        Dim Status As IntPtr = IntPtr.Zero
        Dim ReturnValue As UInteger
        Try
            Status = Marshal.AllocCoTaskMem(Marshal.SizeOf(GetType(SYSTEM_POWER_INFORMATION)))
            ReturnValue = CallNtPowerInformation(SystemPowerInformation, Nothing, 0, Status, Marshal.SizeOf(GetType(SYSTEM_POWER_INFORMATION)))
            PowerInformation = Marshal.PtrToStructure(Status, GetType(SYSTEM_POWER_INFORMATION))
        Catch ex As Exception
            Return 0
        Finally
            Marshal.FreeCoTaskMem(Status)
        End Try
        Return PowerInformation.TimeRemaining
    End Function
End Class

表单:

Public Class Form1

    Public Sub Loader() Handles Me.Load
        Dim rolex As New Timer()
        rolex.Interval = 500
        AddHandler rolex.Tick, AddressOf TimerScattato
        rolex.Start()
    End Sub
    Private Sub TimerScattato()
        Dim secondi As Integer = q.Query()
        Dim iSpan As TimeSpan = TimeSpan.FromSeconds(secondi)
        lblTimeLeft.Text = String.Format("{0,2}:{1,2}:{2,2}", iSpan.Hours, iSpan.Minutes, iSpan.Seconds)

    End Sub
    Private q As New Queryer
End Class