2012-05-14 55 views

回答

3

它獲取開始顯示登錄屏幕的過程好像是叫LogonUI.exe。使用Windows Management Instrumentation (WMI) infrastructure您可以偵聽啓動和關閉的進程。您需要參考System.Management組件。

var interval = new TimeSpan(0, 0, 1); 
const string isWin32Process = "TargetInstance isa \"Win32_Process\""; 

// Listen for started processes. 
WqlEventQuery startQuery 
    = new WqlEventQuery("__InstanceCreationEvent", interval, isWin32Process); 
_startWatcher = new ManagementEventWatcher(startQuery); 
_startWatcher.Start(); 
_startWatcher.EventArrived += OnStartEventArrived; 

// Listen for closed processes. 
WqlEventQuery stopQuery 
    = new WqlEventQuery("__InstanceDeletionEvent", interval, isWin32Process); 
_stopWatcher = new ManagementEventWatcher(stopQuery); 
_stopWatcher.Start(); 
_stopWatcher.EventArrived += OnStopEventArrived; 

處理這些事件,您可以獲取有關啓動或關閉過程的信息。這樣,您可以驗證LogonUI.exe何時關閉,並隨後觸發所需的操作。

void OnStopEventArrived(object sender, EventArrivedEventArgs e) 
{ 
    var o = (ManagementBaseObject)e.NewEvent[ "TargetInstance" ]; 
    string name = (string)o[ "Name" ]; 

    ... 
} 
4

棘手的是,這不是會話更改,而只是桌面更改。特別是,Ctrl + Alt + Del切換到與Winlogon相關的安全桌面。

我不認爲你真的假設來檢測這種事情(畢竟,有一個「安全桌面」的整點),但你可以使用Active輔助功能鉤子。致電SetWinEventHook functionEVENT_SYSTEM_DESKTOPSWITCH event安裝事件掛接並查看您收到的通知。

要得到它去,你需要做到以下幾點:

  • 確保你爲了接收事件通知抽你的客戶端線程上的消息循環。這對於標準的WPF應用程序來說應該不成問題。
  • 請確保您指定WINEVENT_OUTOFCONTEXT標誌,因爲您正在使用託管代碼。您不希望系統嘗試將包含回調函數的DLL注入到每個進程中。相反,這將導致回調函數從隊列異步調用;從託管代碼的土地更安全。
  • 一點P/Invoke魔法。爲了讓你開始…

    const uint WINEVENT_OUTOFCONTEXT = 0x0; 
    const uint EVENT_SYSTEM_DESKTOPSWITCH = 0x0020; 
    
    [DllImport("user32.dll")] 
    static extern IntPtr SetWinEventHook(uint eventMin, 
                uint eventMax, 
                IntPtr hmodWinEventProc, 
                WinEventDelegate lpfnWinEventProc, 
                uint idProcess, 
                uint idThread, 
                uint dwFlags); 
    
    delegate void WinEventDelegate(IntPtr hWinEventHook, 
               uint event, 
               IntPtr hwnd, 
               int idObject, 
               int idChild, 
               uint dwEventThread, 
               uint dwmsEventTime); 
    
    [DllImport("user32.dll")] 
    static extern bool UnhookWinEvent(IntPtr hWinEventHook); 
    
+0

很好,這似乎是一種可能的解決方案。目前我正在探索是否可以跟蹤LogonUI.exe。如果我在那裏撞牆,我會嘗試一下。 –

+0

我結束了[非常快速的非P/Invoke實現](http://stackoverflow.com/a/10607062/590790)。除非你看到任何問題,否則我會保留那一個作爲接受的答案。到目前爲止,它對我來說工作得很好。儘管如此,這個答案非常感謝! –

+1

@Steven不,WMI沒什麼問題。它通常是鉤子的替代品,有時候更方便編碼,尤其是在大多數基礎設施已經存在的.NET語言中(即,它們已經隱藏了BCL中的P/Invoke代碼)。唯一值得關注的問題是,它要求所有目標機器都啓用WMI服務,但是如果您正在運行安裝程序或其他軟件,則可以確保在當時正確配置它們。 –

相關問題