Windows暂停前的剩余时间

时间:2015-12-21 14:06:59

标签: c++ c windows wmi

有没有办法查询窗口在进入暂停/休眠模式之前还剩多少时间?

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

修改

我希望能够使用某种方法查询Windows,而不是在它即将暂停时被事件警告。

2 个答案:

答案 0 :(得分:7)

由于Windows将尝试尽快完成进入S3(睡眠)或S4(休眠)的过程,因此无法知道还剩多少时间。

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

您可以找到您需要的大部分内容here

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

答案 1 :(得分:4)

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

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

InformationLevel游侠中,您传递的SystemPowerInformation枚举值填充了lpOutputBuffer SYSTEM_POWER_INFORMATION结构:

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

然后得到TimeRemaining,以秒表示。

编辑:在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