2011-05-26 58 views
3

我使用Windows API調用GetLastInputInfo來確定系統是否空閒。這幾乎適用於任何情況,除非Windows設置爲繞過用戶名/密碼並自動登錄。如果Windows設置爲「自動登錄」,GetLastInputInfo API不起作用

在這種情況下,查詢GetLastInputInfo將始終返回0.在正常情況下,它會在最後一次輸入發生時返回系統滴答計數。

有誰知道爲什麼?還是有人知道一個替代方法來確定一個Windows會話是否空閒?

編輯

這是代碼是怎麼寫的來檢測當前系統的空閒時間。檢測發生在計時器上,無論計時器運行多長時間,當窗口設置爲「自動登錄」時,GetLastInputInfo將始終返回0。

 long lastInputTicks = 0; 
     long idleTicks = 0; 

     LASTINPUTINFO lastInputInfo = new LASTINPUTINFO(); 
     lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo); 
     lastInputInfo.dwTime = 0; 

     if (GetLastInputInfo(ref lastInputInfo)) { 
      lastInputTicks = lastInputInfo.dwTime; 

      var systemUptime = GetTickCount(); 

      idleTicks = systemUptime - lastInputTicks; 
     } 

     return new TimeSpan(0, 0, (int)(idleTicks/1000)); 

感謝

UPDATE

我確認這僅僅是因爲代碼的服務運行。

澄清:在沒有使用自動登錄的正常情況下,用戶通過控制檯登錄,上述代碼即使作爲服務運行也會返回適當的用戶非活動時間。

但是,如果自動登錄被打開,那麼windows會話似乎不會像典型的控制檯會話那樣運行,因此會跟蹤NOT。這僅適用於代碼從服務運行而不是從「用戶空間」運行的情況 - 如果從用戶空間運行,它在所有情況下運行良好。

這就是說,我真的很想找到一種解決方案,在任何情況下都可以使用服務的

+0

登錄後纔對?有沒有實際的投入?你檢查函數返回值嗎?代碼片段可以避免一些猜測。 – 2011-05-26 23:14:15

+0

@Hans - 是的,輸入可以是恆定的,並且api仍然會始終顯示0.當自動登錄被禁用時(它感覺像Windows但某種類型),它工作正常 – bugfixr 2011-05-26 23:29:32

+0

嗯,這段代碼實際上並沒有做任何事情當它返回FALSE時很有用。很少巧合。 – 2011-05-27 00:02:31

回答

4

GetLastInput()返回FALSE時返回0秒。這顯然是不正確的。你不能在服務中使用這樣的代碼,它沒有辦法檢索用戶輸入。如果GetLastInput()返回FALSE(可能是自動登錄),那麼它將永遠返回FALSE。

讓服務知道用戶會話在Windows中是失敗的原因,服務運行在它自己的會話中,並且不需要用戶登錄。首先使用服務的主要原因是哪一個。而不是以Startup文件夾中的快捷方式開始的程序。這段代碼在XP中可能無意中發生了,但它絕對不會在Vista和Windows 7中運行。有關更多詳細信息,請參見Google「會話0隔離」。

+0

只要不使用自動登錄,它實際上可以在Vista/Windows 7中運行。 – bugfixr 2011-05-27 15:03:16