2012-05-14 6 views
3

Мне нужно знать, когда пользователь переключается на экран входа в систему (как вызвано ctrl-alt-del) in order to circumvent a pesky bug in WPF. Я хочу обойти эту ошибку, повторно инициализируя мой графический интерфейс после возврата с экрана входа в систему. В настоящее время он работает, но я должен запускать его вручную.Как определить, когда пользователь переключается на экран входа в систему?

Я нашел SystemEvents.SessionSwitch, но, к сожалению, это только срабатывает при выходе из системы.

Как определить, когда отображается экран входа в систему путем формирования ctrl-alt-del?

ответ

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 function, чтобы установить крючок события для EVENT_SYSTEM_DESKTOPSWITCH event и посмотреть, какие уведомления вы получите.

Чтобы получить это происходит, вам необходимо сделать следующее:

  • Убедитесь, что вы насосное цикл обработки сообщений на клиентском потоке, чтобы получать уведомления о событиях. Это не должно быть проблемой для стандартного приложения WPF.
  • Убедитесь, что вы указываете флаг WINEVENT_OUTOFCONTEXT, учитывая, что вы работаете с управляемым кодом. Вы не хотите, чтобы система пыталась внедрить вашу DLL, содержащую функцию обратного вызова, в каждый процесс. Вместо этого это приведет к тому, что функция обратного вызова будет вызываться асинхронно из очереди; намного безопаснее из земли управляемого кода.
  • Немного P/Invoke magic. Чтобы начать работу & hellip;

    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, где большая часть инфраструктуры уже существует (т. Е. Они скрыли код P/Invoke внутри BCL).Единственная проблема, которая приходит на ум, заключается в том, что она требует, чтобы все целевые машины включали службу WMI, но если вы используете установщик или что-то еще, вы можете убедиться, что они настроены соответствующим образом в то время. –

Смежные вопросы