SERVICE_CONTROL_SESSIONCHANGE
От: x64 Россия  
Дата: 25.06.08 23:09
Оценка: 9 (1)
Привет.
Есть служба, режим запуска = auto. Система настроена на автоматический вход с заданной учётной записью. По получении сигнала SERVICE_CONTROL_SESSIONCHANGE служба должна стартовать GUI-приложение. Всё замечательно работает, за исключением того, что данный сигнал не приходит сразу после старта службы, очевидно, это происходит потому что служба стартует позже, чем создаётся сессия. Нужно либо заставить службу каким-либо образом запускаться раньше входа в систему, либо как-то определять, запускали ли мы GUI в этой сессии или ещё нет; первый вариант, конечно, был бы предпочтительнее, но как это сделать? У кого-нибудь есть идеи, что можно сделать в данном случае?
Спасибо!
Re: SERVICE_CONTROL_SESSIONCHANGE
От: Mr.Cat  
Дата: 25.06.08 23:21
Оценка:
Какая ОС (на 2k вроде этот сигнал не поддерживается)? Сигнал не приходит только при первом логине или никогда вообще (проверьте, подписывались ли Вы на этот сигнал, регистрировали HandlerEx или все-таки Handler)?
Re[2]: SERVICE_CONTROL_SESSIONCHANGE
От: x64 Россия  
Дата: 25.06.08 23:24
Оценка:
MC>Какая ОС (на 2k вроде этот сигнал не поддерживается)? Сигнал не приходит только при первом логине или никогда вообще (проверьте, подписывались ли Вы на этот сигнал, регистрировали HandlerEx или все-таки Handler)?

Проблема проявляется на Windows XP и Windows Vista. На сигнал я подписан, регистрировал именно HandlerEx, не приходит он только при первом входе в систему. При последующих логинах сигнал приходит и всё работает как надо.
Re[3]: SERVICE_CONTROL_SESSIONCHANGE
От: Mr.Cat  
Дата: 25.06.08 23:30
Оценка:
Здравствуйте, x64, Вы писали:

x64>Проблема проявляется на Windows XP и Windows Vista. На сигнал я подписан, регистрировал именно HandlerEx, не приходит он только при первом входе в систему. При последующих логинах сигнал приходит и всё работает как надо.


Хм... Похоже, сервис реально стартует после логина. Глянул в MSDN, там предлагают (правда по другому поводу, но все же) вот что проверить:

To determine whether a service is running as an interactive service, call the GetProcessWindowStation function to retrieve a handle to the window station, and the GetUserObjectInformation function to test whether the window station has the WSF_VISIBLE attribute.


К примеру, можно после старта сервиса подождать несколько секунд и, если не пришел SESSIONCHANGE, проверить состояние стейшена. Если он видимый — стало быть мы пропустили логин и надо показать GUI.

PS (не по теме): А вариант связки неинтерактивного сервиса + отдельного управляющего приложения не рассматриваете? А то MS как-то интерактивные сервисы не очень жалует.
Re[4]: SERVICE_CONTROL_SESSIONCHANGE
От: x64 Россия  
Дата: 25.06.08 23:50
Оценка:
MC>К примеру, можно после старта сервиса подождать несколько секунд и, если не пришел SESSIONCHANGE, проверить состояние стейшена. Если он видимый — стало быть мы пропустили логин и надо показать GUI.

Интересно. Только откуда брать хендл оконной станции? Из процесса службы? А разве службы привязаны к какой-либо оконной станции?

MC>PS (не по теме): А вариант связки неинтерактивного сервиса + отдельного управляющего приложения не рассматриваете? А то MS как-то интерактивные сервисы не очень жалует.


Вы немного не поняли. Сервис у меня не интерактивный, под GUI как раз и подразумевалась внешняя программа, которую запускает сервис. Тут проблем нет, проблема только в том, что при первом логине эта самая программа не запускается, т.к. не приходит сабжевый сигнал.
Re: SERVICE_CONTROL_SESSIONCHANGE
От: Аноним  
Дата: 26.06.08 07:07
Оценка: 9 (1)
WTSGetActiveConsoleSessionId/WTSQueryUserToken
Re[2]: SERVICE_CONTROL_SESSIONCHANGE
От: Were  
Дата: 26.06.08 07:14
Оценка:
Здравствуйте, Аноним, Вы писали:

А>WTSGetActiveConsoleSessionId/WTSQueryUserToken


Тогда уж WTSEnumerateSessions.
Re: SERVICE_CONTROL_SESSIONCHANGE
От: DarkTranquillity  
Дата: 26.06.08 07:21
Оценка:
Здравствуйте, x64, Вы писали:

x64>Привет.

x64>Есть служба, режим запуска = auto. Система настроена на автоматический вход с заданной учётной записью. По получении сигнала SERVICE_CONTROL_SESSIONCHANGE служба должна стартовать GUI-приложение. Всё замечательно работает, за исключением того, что данный сигнал не приходит сразу после старта службы, очевидно, это происходит потому что служба стартует позже, чем создаётся сессия. Нужно либо заставить службу каким-либо образом запускаться раньше входа в систему, либо как-то определять, запускали ли мы GUI в этой сессии или ещё нет; первый вариант, конечно, был бы предпочтительнее, но как это сделать? У кого-нибудь есть идеи, что можно сделать в данном случае?
x64>Спасибо!

Попробуйте поэкспериментироовать с группой загрузки сервиса.
Это определяется параметром реестра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ВашСервис Group=Группа
Например, устарновите значение Group в Event Log. Параметр типа REG_SZ.
Re[5]: SERVICE_CONTROL_SESSIONCHANGE
От: Mr.Cat  
Дата: 26.06.08 07:26
Оценка:
Здравствуйте, x64, Вы писали:

MC>>К примеру, можно после старта сервиса подождать несколько секунд и, если не пришел SESSIONCHANGE, проверить состояние стейшена. Если он видимый — стало быть мы пропустили логин и надо показать GUI.

x64>Интересно. Только откуда брать хендл оконной станции? Из процесса службы? А разве службы привязаны к какой-либо оконной станции?
Если сервис интерактивный — то он должен быть привязан к "WinSta0", хотя привязан ли он к ней ДО создания первого окна — из MSDN неочевидно. Если будете проверять — отпишитесь, мне тоже интересно.

x64>Вы немного не поняли. Сервис у меня не интерактивный, под GUI как раз и подразумевалась внешняя программа, которую запускает сервис. Тут проблем нет, проблема только в том, что при первом логине эта самая программа не запускается, т.к. не приходит сабжевый сигнал.

Хм... а почему бы тогда сабжевый гуи просто не заткнуть в автозагрузку? И пусть они с сервисом ждут загрузки друг друга.
Re: Решение
От: x64 Россия  
Дата: 26.06.08 12:39
Оценка: 7 (2)
Всё гениальное оказалось, как всегда, просто. Самый дельный совет дали тут
Автор:
Дата: 26.06.08
. Таким образом теперь я в ServiceMain'е просто проверяю наличие активной сессии (WTSGetActiveConsoleSessionId() != 0xFFFFFFFF) и, если сессия уже существует, значит сигнала SERVICE_CONTROL_SESSIONCHANGE уже можно не ждать, и я тут же запускаю GUI. В принципе, наверно можно было бы и поэкспериментировать с группами запуска, но сейчас лень, — работает и ладно. Всем спасибо!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.