How to detect when the user switches to the Log On screen?

大城市里の小女人 提交于 2020-01-13 18:58:07

问题


I need to know when the user switches to the logon screen (as triggered by ctrl-alt-del) in order to circumvent a pesky bug in WPF. I want to work around this bug by reinitializing my GUI after returning from the logon screen. Currently it works, but I have to trigger it manually.

I have found SystemEvents.SessionSwitch, but unfortunately this is only triggered when logging off.

How can I detect when the logon screen is displayed by forming ctrl-alt-del?


回答1:


The tricky thing is that this is not a session change, but rather just a desktop change. In particular, Ctrl+Alt+Del switches to a secured desktop associated with Winlogon.

I don't think you're really supposed to detect this kind of thing (that is, after all, the whole point of having a "secure desktop"), but you could probably do it using an Active Accessibility hook. Call the SetWinEventHook function to install an event hook for the EVENT_SYSTEM_DESKTOPSWITCH event and see what notifications you receive.

To get it going, you'll need to do the following:

  • Ensure that you're pumping a message loop on your client thread in order to receive event notifications. This shouldn't be a problem for a standard WPF application.
  • Make sure that you specify the WINEVENT_OUTOFCONTEXT flag, considering that you're working from managed code. You don't want the system to attempt to inject your DLL that contains the callback function into every process. Instead, this will cause the callback function to be called asynchronously from a queue; much safer from the land of managed code.
  • A little bit of P/Invoke magic. To get you started…

    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);
    



回答2:


The process which gets started to show the logon screen seems to be called LogonUI.exe.

Using the Windows Management Instrumentation (WMI) infrastructure you can listen for processes which start and shut down. You will need to reference the System.Management assembly.

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;

Handling these events, you can get information about the started or closed process. This way you can verify when LogonUI.exe was shut down, and subsequently trigger the required actions.

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

    ...
}


来源:https://stackoverflow.com/questions/10592431/how-to-detect-when-the-user-switches-to-the-log-on-screen

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!