Как узнать, что в настоящий момент отображается экран входа в систему?

Я пишу служебное приложение, которое будет работать с local system учетными данными. Мне нужно будет узнать от моей службы, отображается ли экран входа в Windows в любое конкретное время. Есть какой-либо способ сделать это?

PS. Экраны, которые можно вызвать, заблокировав рабочую станцию:

введите описание изображения здесь

Или попытавшись переключить пользователя:

введите описание изображения здесь

Или после Ctrl + Alt + Del:

введите описание изображения здесь

PS. Мне нужно, чтобы это работало в Windows XP и выше.

РЕДАКТИРОВАТЬ: Единственное жизнеспособное решение, которое я придумал, - это проверить, запущен ли LogonUI.exe процесс. Проблема с этим подходом заключается в том, как отличить фактический процесс входа в систему от любого другого процесса с таким именем образа?


person c00000fd    schedule 18.04.2014    source источник
comment
Почему ты хочешь это знать   -  person David Heffernan    schedule 18.04.2014
comment
@DavidHeffernan: Чтобы мой процесс в пользовательском режиме не беспокоился об отображении пользовательских сообщений, поскольку пользователь их не увидит.   -  person c00000fd    schedule 18.04.2014
comment
@ c00000fd: Ваш сервис в любом случае не должен показывать сообщения. Обычное решение - это небольшое приложение, которое общается с вашим сервисом; приложение может легко определить, видно ли оно.   -  person MSalters    schedule 18.04.2014
comment
@MSalters: Вы хотите показать мне, как ваше приложение будет определять, видно ли оно? PS. Кстати, я не говорю, что показываю сообщения от сервиса.   -  person c00000fd    schedule 18.04.2014
comment
Если WM_WTSSESSION_CHANGE не предоставляет вам нужную информацию, я считаю OpenInputDesktop наиболее надежным методом.   -  person Harry Johnston    schedule 19.04.2014
comment
@MSalters: IsWindowVisible имеет дело со стилем WS_VISIBLE и не имеет ничего общего с определением того, доступно ли окно в данный момент для просмотра конечному пользователю.   -  person c00000fd    schedule 19.04.2014


Ответы (3)


Как описано в комментариях, вы пытаетесь определить, должен ли процесс в сеансе интерактивного рабочего стола отображать окно сообщения. Нет смысла делать это, если интерактивный сеанс неактивен.

В этом случае я считаю, что предложенное вами решение неверно. Вместо этого вам следует зарегистрироваться для получения уведомлений об изменении сеанса, позвонив WTSRegisterSessionNotification. Когда вы это сделаете, вам будут отправлены WM_WTSSESSION_CHANGE сообщения, которые позволят вам отслеживать текущее состояние.

Обратите внимание, что вы делаете это в своем настольном приложении, а не в службе. Служба по-прежнему отправляет свои сообщения настольному приложению. Но теперь настольное приложение знает, стоит ли их показывать.

Обновить

Реми предлагает лучший способ в комментариях:

И если используется отдельное приложение, нет причин вообще обнаруживать изменения сеанса, это приложение может просто проверить, является ли назначенная ему в данный момент рабочая станция / рабочий стол интерактивной рабочей станцией / рабочим столом, сравнивая, например, GetThreadDesktop() с OpenInputDesktop().

person David Heffernan    schedule 18.04.2014
comment
Будут ли отправляться эти уведомления для окна Ctrl + Alt + Del или экрана блокировки (когда пользователь блокирует рабочую станцию)? - person c00000fd; 18.04.2014
comment
Да, они будут. Прочтите документацию к сообщению. В нем перечислены все события. - person David Heffernan; 18.04.2014
comment
Я, должно быть, не вижу этого, но где уведомление Ctrl + Alt + Del? - person c00000fd; 18.04.2014
comment
Точно сказать не могу. Попробуйте и посмотрите, что вам пришлют. - person David Heffernan; 18.04.2014
comment
Службы могут получать SERVICE_CONTROL_SESSIONCHANGE уведомления непосредственно в своих HandlerEx() обратных вызовах. Для этого не нужно отдельное приложение. - person Remy Lebeau; 18.04.2014
comment
@RemyLebeau есть уже отдельное приложение, насколько я понимаю. В конце концов, что еще будет отображать окна на рабочем столе пользователя? - person David Heffernan; 18.04.2014
comment
@DavidHeffernan: служба может отображать сообщения для пользователя с использованием MessageBox(MB_SERVICE_NOTIFICATION) и / или WTSSendMessage(), вообще не задействуя отдельное приложение. И если используется отдельное приложение, нет причин вообще обнаруживать изменения сеанса, это приложение может просто проверить, является ли назначенная ему в данный момент рабочая станция / рабочий стол интерактивной рабочей станцией / рабочим столом, сравнивая, например, GetThreadDesktop() с OpenInputDesktop(). - person Remy Lebeau; 18.04.2014

Все такие экраны представлены на отдельном рабочем столе. Вы можете попробовать перечислить рабочие столы пользователя и сравните их с текущими (я не уверен, что служба в сеансе 0 - Vista и выше - может это сделать; если нет, создайте вспомогательный процесс в пользовательском сеансе). Однако это может дать ложное срабатывание, если рабочий стол UAC включен. Другой угловой случай - ситуация без пользователя (сразу после загрузки до того, как какой-либо пользователь отключился).

person user58697    schedule 18.04.2014
comment
EnumDesktops не будет перечислять их по сеансам, поэтому это не сработает. - person c00000fd; 18.04.2014
comment
@ c00000fd: в какой-то момент вам придется согласиться с тем, что часть вашего кода должна выполняться внутри сеанса пользователя. Вы не всегда можете делать все прямо из процесса обслуживания. Запускать отдельный процесс и использовать IPC неудобно, но иногда необходимо. - person Harry Johnston; 19.04.2014

В окнах есть несколько состояний.

  1. Состояние выхода из системы

Когда Winlogon находится в состоянии выхода из системы, пользователям предлагается идентифицировать себя и предоставить информацию для аутентификации. Если пользователь предоставляет правильную информацию об учетной записи и никакие ограничения не препятствуют этому, пользователь входит в систему, и на рабочем столе приложения запускается программа оболочки (например, Windows Explorer). Winlogon переходит в состояние входа в систему.

  1. Состояние входа в систему

Когда Winlogon находится в состоянии входа в систему, пользователи могут взаимодействовать с оболочкой, активировать дополнительные приложения и выполнять свою работу. Находясь в состоянии входа в систему, пользователи могут либо прекратить всю работу и выйти из системы, либо заблокировать свои рабочие станции (оставив всю работу на месте). Если пользователь решит выйти из системы, Winlogon завершит все процессы, связанные с этим сеансом входа в систему, и рабочая станция станет доступной для другого пользователя. Если вместо этого пользователь решает заблокировать рабочую станцию, Winlogon переходит в состояние блокировки рабочей станции.

  1. Состояние блокировки рабочей станции

Когда Winlogon находится в состоянии блокировки рабочей станции, отображается защищенный рабочий стол до тех пор, пока пользователь не разблокирует рабочую станцию, предоставив ту же идентификационную и аутентификационную информацию, что и пользователь, который первоначально вошел в систему, или пока администратор не выйдет из системы принудительно. Если рабочая станция разблокирована, отображается рабочий стол приложения, и работа может продолжаться.

ссылка: https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa380547(v=vs.85).aspx

p.s. регистрация защищенной последовательности внимания (SAS, CTRL + ALT + Delete) включена в состояние Workstation-Locked

Точно так же в Windows есть несколько типов рабочего стола.

  1. Рабочий стол Winlogon

  2. Рабочий стол приложения (= Рабочий стол по умолчанию)

  3. Заставка рабочего стола

  4. Безопасный рабочий стол

Я рекомендую вам прочитать это: https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa375994(v=vs.85).aspx

Я не знаю, что мои ответы - это то, что вы хотите ... но я надеюсь, что это в какой-то мере поможет.

person ayCho    schedule 08.09.2016