Windows有一個內部機制,通過檢查用戶交互性和其他任務(某人正在觀看視頻等)來決定何時顯示屏幕保護程序(或關閉屏幕)。Windows如何決定顯示屏幕保護
是否有一個Win API允許我詢問用戶是否處於活動狀態,或者他們上次何時處於活動狀態?
Windows有一個內部機制,通過檢查用戶交互性和其他任務(某人正在觀看視頻等)來決定何時顯示屏幕保護程序(或關閉屏幕)。Windows如何決定顯示屏幕保護
是否有一個Win API允許我詢問用戶是否處於活動狀態,或者他們上次何時處於活動狀態?
它被稱爲「空閒計時器」。您可以通過訂購CallNtPowerInformation()來獲得它的價值,索取SystemPowerInformation。返回的SYSTEM_POWER_INFORMATION.TimeRemaining字段告訴您空閒計時器剩餘多少時間。 SystemExecutionState請求會告訴您是否有任何線程調用SetThreadExecutionState()來停止計時器,就像顯示視頻的應用程序所做的那樣。
using System;
using System.Runtime.InteropServices;
public static class PowerInfo {
public static int GetIdleTimeRemaining() {
var info = new SYSTEM_POWER_INFORMATION();
int ret = GetSystemPowerInformation(SystemPowerInformation, IntPtr.Zero, 0, out info, Marshal.SizeOf(info));
if (ret != 0) throw new System.ComponentModel.Win32Exception(ret);
return info.TimeRemaining;
}
public static int GetExecutionState() {
int state = 0;
int ret = GetSystemExecutionState(SystemExecutionState, IntPtr.Zero, 0, out state, 4);
if (ret != 0) throw new System.ComponentModel.Win32Exception(ret);
return state;
}
private struct SYSTEM_POWER_INFORMATION {
public int MaxIdlenessAllowed;
public int Idleness;
public int TimeRemaining;
public byte CoolingMode;
}
private const int SystemPowerInformation = 12;
private const int SystemExecutionState = 16;
[DllImport("powrprof.dll", EntryPoint = "CallNtPowerInformation", CharSet = CharSet.Auto)]
private static extern int GetSystemPowerInformation(int level, IntPtr inpbuf, int inpbuflen, out SYSTEM_POWER_INFORMATION info, int outbuflen);
[DllImport("powrprof.dll", EntryPoint = "CallNtPowerInformation", CharSet = CharSet.Auto)]
private static extern int GetSystemExecutionState(int level, IntPtr inpbuf, int inpbuflen, out int state, int outbuflen);
}
您應該看看GetLastInputInfo函數,它返回一個包含上次用戶輸入的滴答計數的結構,一個滴答是1ms。然後,您可以將此值與的值相比較,以獲取自上次用戶輸入以來的經過時間(以毫秒爲單位)。
AP/Invoke的定義此功能,請點擊這裏:http://www.pinvoke.net/default.aspx/user32.GetLastInputInfo
要知道,雖然,該刻度值由GetLastInputInfo
包裹返回到零隻是短期的50天,但Environment.TickCount
包裝只是短期的25天,由於GetLastInputInfo
返回的值是一個無符號整數,並且TickCount被簽名。在大多數情況下,這可能不是什麼大問題,但值得記住的是,偶爾會有一些奇怪的行爲,每月一次。
GetLastInputInfo很棒,但它並不考慮作爲活動報告的應用程序。例如 - 當您在Media Player中觀看電影時,只要電影正在播放,您將無法進入屏幕保護程序,但GetLastInputInfo將不會顯示 – sternr
某些阻止屏幕保護程序的應用程序似乎是通過響應Windows消息('WM_SYSCOMMAND'與'SC_SCREENSAVE'的'wParam'),而不是讓默認處理程序執行它。我想不出從OS以外使用這種機制的好方法。 –
pinvoke網站不提供SYSTEM_POWER_INFORMATION c#實現和我的似乎產生無效值。你能否請你用示例實現更新你的答案? – sternr
感謝那正是我正在尋找 – sternr