Здравствуйте Alex Fedotov, Вы писали:
AF>Здравствуйте -lexa-, Вы писали:
AF>А если в этот момент нет интерактивного пользователя? А если их несколько, подключенных через через Terminal services? Уж сколько раз твердили миру, не дело показывать UI из сервера...
На счет интерактивного пользователя — он точно есть в этот момент. Просто в силу уже реализованного до меня один и тот же сервис используется как DCOM сервер и сервис в обычном понимании. Той части которая работает с GUI юзер в Logon не нужен — достаточно LocalSytem а для корректной работы DCOM в Log on Local System использоваться не может ... если не включать на компе сервере NULL сессии что может пагубно как я понял отразиться на безопасности...
AF>1. Зарегистрируй сервис как интерактивный (SERVICE_INTERACTIVE_PROCESS)
данное возможно по моим данным только при работе с Logon LocalSystem т.е. данный флаг при регистрации образно говоря выставляет соответствующую галочку в свойствах сервиса
AF>2. Скачай http://www.alexfedotov.com/samples/svcui.zip и посмотри как устроена функция ThreadInteract. Вызов MessageBox замени на свой диалог.
Пример скачал... код метода ThreadInteract очень похож на мой неработающий и на тот что я находил в MSDN....
В Вашем коде на сколько я понял полностью отсутствует код связанный с инперсонализацией... поэтому вероятно данный пример не работает с юзерами в Log on отличными от LocalHost.
Меня же интересовали именно механизмы инперсонализации....
Тем не менее я перекопировал Ваш метод в cpp класса моего сервиса. Класс создан визардом VC как ATL COM App Wisard-> реализация сервера как service
вызов метода ThreadInteract поместил в CServiceModule::Run()
после SetServiceStatus(SERVICE_RUNNING);
на сколько я понимаю место вызов аналогично Вашему
тем не менее не отрабатывает ThreadInteract при SetThreadDesktop(hdesk) с кодом ошибки 170 — Требуемый ресурс занят....
Не могли бы Вы выссказать свое мнение и на сей счет.... Спасибо
void CServiceModule::Run()
{
_Module.dwThreadID = GetCurrentThreadId();
HRESULT hr = CoInitialize(NULL);
_ASSERTE(SUCCEEDED(hr));
CSecurityDescriptor sd;
sd.InitializeFromThreadToken();
hr = CoInitializeSecurity(sd, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
_ASSERTE(SUCCEEDED(hr));
hr = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE);
_ASSERTE(SUCCEEDED(hr));
LogEvent(_T("Service started"));
if (m_bService)
{
SetServiceStatus(SERVICE_RUNNING);
ThreadInteract();
}
MSG msg;
while (GetMessage(&msg, 0, 0, 0))
DispatchMessage(&msg);
_Module.RevokeClassObjects();
CoUninitialize();
}
поместил в