OpenInputDesktop () для определения безопасного / рабочего стола входа - PullRequest
3 голосов
/ 24 ноября 2010

Visual C ++ 2008

Как установить, находится ли интерактивный пользователь на заблокированном рабочем столе (Windows-ключ L) или на экране выключения (Vista или 7), ожидая закрытия программ во время выхода из системы.

HDESK hd = OpenInputDesktop (0, false, READ_CONTROL);

Это прекрасно работает для пользовательского приложения на рабочем столе по умолчанию, но завершается ошибкой с кодом 5 при работе на рабочих столах Locked или Shutdown из-за того, что, как я понимаю, у пользователя нет прав на открытие объекта защищенного рабочего стола.

Вызов этого из службы, работающей под учетной записью SYSTEM, возвращает ошибку 1 (недопустимая функция). Я считаю, что Сервис в любом случае находится в неправильном сеансе (сеанс 0) и не может определить интерактивный рабочий стол для любого другого сеанса.

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

Должен ли я попытаться перечислить все сеансы, оконные станции и рабочие столы?

Даже тогда, как мне определить текущий интерактивный рабочий стол, если я могу только вызвать OpenInputDesktop из службы SYSTEM в сеансе 0?

Ответы [ 2 ]

3 голосов
/ 27 ноября 2010

Я думаю, вы можете попробовать эти методы:

  • Из процесса, запущенного у текущего интерактивного пользователя:Используйте WTSRegisterSessionNotification для регистрации уведомлений об изменении сеанса.После регистрации интерактивный процесс получит уведомления о входе / выходе из системы.Более подробную информацию можно найти здесь:http://msdn.microsoft.com/en-us/library/aa383841.aspxhttp://blogs.msdn.com/b/oldnewthing/archive/2006/01/04/509194.aspx
  • Из службы (запущенной в сеансе 0):
    • Используйте GetProcessWindowStation, чтобы получить текущий дескриптор станции и сохраните его для дальнейшего использования.
    • Используйте WTSGetActiveConsoleSessionId, чтобы получить идентификатор сеанса текущего интерактивного сеанса.
    • Получить название станции, соответствующее текущему идентификатору сеанса, используя WTSQuerySessionInformation с WTSWinStationName информационным классом.
    • Откройте эту станцию, используя OpenWindowStation.Установите для этой станции свой процесс обслуживания, используя SetProcessWindowStation.
    • Теперь вы можете использовать OpenInputDesktop, чтобы проверить, вошел ли пользователь в систему или нет.
    • Закройте станцию ​​открытого интерактивного окна, выполнивзвонит CloseWindowStation.Сбросьте исходную станцию ​​обслуживания окна, позвонив по номеру SetProcessWindowStation с сохраненным ранее дескриптором станции.

PS: В настоящее время "WinSta0" - единственная интерактивная станция в Windows.Таким образом, вы можете пропустить WTSGetActiveConsoleSessionId и WTSQuerySessionInformation звонки.

1 голос
/ 08 апреля 2011

Осторожно: MSDN о WTSQuerySessionInformation с WTSWinStationName:

Примечание. Несмотря на свое имя, указание этого типа не возвращает имя оконной станции.Скорее, он возвращает имя сеанса служб удаленных рабочих столов.Каждый сеанс Службы удаленных рабочих столов связан с интерактивной оконной станцией.В настоящее время, поскольку единственным поддерживаемым именем оконной станции для интерактивной оконной станции является «WinSta0», каждый сеанс связан со своей собственной оконной станцией «WinSta0».Для получения дополнительной информации см. Оконные станции.

...