2008-10-15 90 views
9

只有當您還沒有使用計算機一段時間(例如屏幕保護程序,Google桌面索引等)時,各種程序纔可以執行此操作。如何判斷Windows何時無效

他們如何知道它何時處於非活動狀態? Windows中是否有一些函數可以告訴你它已經停用了多久,或者你是否必須使用某種鍵盤/鼠標掛鉤來自己跟蹤活動?

我正在使用C#,但我對任何確定不活動的方法感興趣。

回答

10

編輯:改變了答案,提供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引起的劃傷]

5

Google is your friend

基本上採用this.
使用前別忘了完全準備好了文件。

+0

我是用「非活動」與「空閒」搜索的。 GetLastInputInfo正是我所需要的。謝謝。 – 2008-10-15 01:15:36

+0

請注意,它僅適用於當前會話。可能有用戶處於活動狀態的其他會話。我不確定是否有可能進行跨會話,因爲這可能是安全漏洞。 – shoosh 2008-10-15 01:17:35

+0

我想知道爲什麼這是downvoted?我能想到的唯一原因是它只有鏈接而沒有實際的答案?或者是因爲使用GetLastInputInfo有問題? – 2008-10-15 01:19:04

0

鍵盤和鼠標掛鉤是我覺得最有價值的東西。下面的類可以插入,你只需要弄清楚你想要用關鍵和鼠標更新的信息。

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。