2015-12-21 47 views
13

有沒有辦法查詢窗口多少時間,直到進入掛起/休眠模式?剩下的時間直到Windows暫停

我正在使用vbscript,並懷疑可能有WMI答案,但如果可能的話,像c/C++,* .NET或甚至java這樣的任何語言都可能適合我的需要。

編輯

我希望能夠有一個方法來查詢的Windows,而不是由事件提醒,當它即將中止。

+0

[?你嘗試過什麼(http://mattgemmell.com/what-have-you-tried/ ) – Drop

+4

我一直在尋找一個起點,甚至找不到任何這樣的問題。所以,我沒有代碼。 –

+0

https://msdn.microsoft.com/en-us/library/windows/desktop/aa373217%28v=vs.85%29.aspx –

回答

7

由於Windows會嘗試儘可能快地完成進入S3(睡眠)或S4(休眠),所以沒有API知道剩下多少時間。

Windows將向所有進程發送有關掛起的電源狀態更改的通知,並允許應用程序爲該事件做準備。

你可以找到你需要的大部分here

基本上你有20秒來處理第一條消息。您的過程可能會延遲迴覆信息,以處理所有各種電源循環任務,例如關閉文件,保存狀態等

4

您可能需要調用CallNtPowerInformation API函數,它採用以下PARAMS:

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

在paramer你傳遞的是一個充滿lpOutputBufferSystemPowerInformation枚舉值InformationLevelSYSTEM_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 
+1

從@HansPassant鏈接中提到了一個錯誤 - * TimeRemaining實際上是LONG ,不是ULONG。 (當系統由於睡眠原因,但由於某種原因無法啓動時,TimeRemaining會變爲負數。)* –

+0

我可否看到您的VB.NET測試代碼? –

+0

@EduardoPoço完成。 – vulkanino