只有當您還沒有使用計算機一段時間(例如屏幕保護程序,Google桌面索引等)時,各種程序纔可以執行此操作。如何判斷Windows何時無效
他們如何知道它何時處於非活動狀態? Windows中是否有一些函數可以告訴你它已經停用了多久,或者你是否必須使用某種鍵盤/鼠標掛鉤來自己跟蹤活動?
我正在使用C#,但我對任何確定不活動的方法感興趣。
只有當您還沒有使用計算機一段時間(例如屏幕保護程序,Google桌面索引等)時,各種程序纔可以執行此操作。如何判斷Windows何時無效
他們如何知道它何時處於非活動狀態? Windows中是否有一些函數可以告訴你它已經停用了多久,或者你是否必須使用某種鍵盤/鼠標掛鉤來自己跟蹤活動?
我正在使用C#,但我對任何確定不活動的方法感興趣。
編輯:改變了答案,提供Shy的答案背後的文字和細節(應該被接受)。隨意合併並刪除這一個。
GetLastInputInfo函數 GetLastInputInfo函數檢索上次輸入事件的時間。
與P粘貼在這裏/調用
此函數檢索自上次用戶輸入
[DllImport("user32.dll")]
static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
static int GetLastInputTime()
{
int idleTime = 0;
LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
lastInputInfo.cbSize = Marshal.SizeOf(lastInputInfo);
lastInputInfo.dwTime = 0;
int envTicks = Environment.TickCount;
if(GetLastInputInfo(ref lastInputInfo))
{
int lastInputTick = lastInputInfo.dwTime;
idleTime = envTicks - lastInputTick;
}
return ((idleTime > 0) ? (idleTime/1000) : idleTime);
}
[StructLayout(LayoutKind.Sequential)]
struct LASTINPUTINFO
{
public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO));
[MarshalAs(UnmanagedType.U4)]
public int cbSize;
[MarshalAs(UnmanagedType.U4)]
public UInt32 dwTime;
}
FWIW: 我AnAppADay期間實施的全球鍵盤和鼠標鉤子。看到這個應用程序的來源 - 這是非常接近你想要的。您需要的類位於AnAppADay.Utils命名空間中。
[由於linkrot引起的劃傷]
基本上採用this.
使用前別忘了完全準備好了文件。
鍵盤和鼠標掛鉤是我覺得最有價值的東西。下面的類可以插入,你只需要弄清楚你想要用關鍵和鼠標更新的信息。
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
namespace Example {
public class Hook {
delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
[FlagsAttribute]
public enum WindowMessage {
WM_KEYDOWN = 0x0000000000000100, // &H100
WM_MOUSEMOVE = 0x0000000000000200, // &H200
WM_LBUTTONDOWN = 0x0000000000000201, // &H201
WM_RBUTTONDOWN = 0x0000000000000204, // &H204
WH_KEYBOARD = 2,
WH_MOUSE = 7,
HC_ACTION = 0
}
[DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
private static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
private static extern bool UnhookWindowsHookEx(int idHook);
[DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
//Declare MouseHookProcedure as a HookProc type.
static HookProc MouseHookProcedure;
static HookProc KeyboardHookProcedure;
private static int mhMouseHook = 0;
private static int mhKeyboardHook = 0;
public Hook() {}
public static void Init() {
MouseHookProcedure = new HookProc(MouseHookProc);
KeyboardHookProcedure = new HookProc(KeyboardHookProc);
mhMouseHook = SetWindowsHookEx((int)WindowMessage.WH_MOUSE, MouseHookProcedure, (IntPtr)0, AppDomain.GetCurrentThreadId());
mhKeyboardHook = SetWindowsHookEx((int)WindowMessage.WH_KEYBOARD, KeyboardHookProcedure, (IntPtr)0, AppDomain.GetCurrentThreadId());
}
public static void Terminate() {
UnhookWindowsHookEx(mhMouseHook);
UnhookWindowsHookEx(mhKeyboardHook);
}
private static int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam) {
if (nCode >= 0) {
//do something here to update the last activity point, i.e. a keystroke was detected so reset our idle timer.
}
return CallNextHookEx(mhMouseHook, nCode, wParam, lParam);
}
private static int KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam) {
if (nCode >= 0) {
//do something here to update the last activity point, i.e. a mouse action was detected so reset our idle timer.
}
return CallNextHookEx(mhKeyboardHook, nCode, wParam, lParam);
}
}
}
當然,這隻適用於你正在掛鉤的應用程序。如果您需要跟蹤整個系統的不活動狀態,則需要創建一個可以加載到所有其他窗口的地址空間中的DLL。不幸的是,我還沒有聽說過會允許在這種情況下工作的.net編譯的.dll文件。我們有一個爲此目的而掛鉤的C++ DLL。
我是用「非活動」與「空閒」搜索的。 GetLastInputInfo正是我所需要的。謝謝。 – 2008-10-15 01:15:36
請注意,它僅適用於當前會話。可能有用戶處於活動狀態的其他會話。我不確定是否有可能進行跨會話,因爲這可能是安全漏洞。 – shoosh 2008-10-15 01:17:35
我想知道爲什麼這是downvoted?我能想到的唯一原因是它只有鏈接而沒有實際的答案?或者是因爲使用GetLastInputInfo有問題? – 2008-10-15 01:19:04