Определить, если dll загружен в сервис - PullRequest
0 голосов
/ 29 июня 2010

Есть ли windows api, чтобы определить, работает ли моя dll в системной службе или в обычном пользовательском процессе?

Ранее я просматривал текущее имя пользователя и игнорировал "SYSTEM", "LOCAL SERVICE" и "NETWORK SERVICE". Но теперь я вижу, как GetUsername возвращает machine_name $ в тех случаях, когда svchost запускается в определенных ситуациях до того, как кто-либо войдет в систему. Кроме того, я не могу найти документацию для machine_name $ result из GetUsername в Vista, кто-нибудь видел такое поведение?

Ответы [ 5 ]

3 голосов
/ 30 июня 2010

Вы можете просмотреть токен процесса, чтобы узнать, активен ли известный токен SID NT Authority \ Service в токене.Если это так, то вы работаете в службе.Вы можете использовать CheckTokenMembership, чтобы проверить, работает ли ваш процесс с определенным активным SID в токене.

2 голосов
/ 09 ноября 2012

Для Windows Vista и выше можно проверить текущий сеанс как службы, загруженные в session0, и пользовательские процессы, загруженные в session1 и выше.Я не проверял, но что-то вроде этого должно работать:

if (Win32MajorVersion < 6) return PROCESSTYPE_CANNOTDETECT;

DWORD SessionId;
if ( ProcessIdToSessionId( GetCurrentProcessId(), &SessionId ) 
  && (0 == SessionId) )
{
    return PROCESSTYPE_SERVICE_OR_DRIVER;
}
else
{
    return PROCESSTYPE_USERAPP;
}
2 голосов
/ 30 июня 2010

Это учетная запись пользователя, использованная для настройки службы. Может быть что угодно, это зависит от системного администратора, чтобы выбрать эти учетные записи. Что, конечно, означает, что вы можете не надежно использовать его для определения того, работает ли ваш код в службе.

Вы должны позволить службе, использующей вашу DLL, сообщить вам, что это служба, о которой она всегда знает. Автоматическое определение сложно, GetProcessWindowStation () должен быть лидером. Вызовите GetUserObjectInformation для возвращенного дескриптора с флагом UOI_FLAGS и проверьте, получите ли вы USEROBJECTFLAGS.dwFlags = WSF_VISIBLE. Я предполагаю, что могут быть некоторые вырожденные случаи с RDP, но вы можете посмотреть, есть ли у пользователя шансы увидеть вывод процесса.

0 голосов
/ 01 июля 2010

Вы можете попробовать вызвать функцию StartServiceCtrlDispatcher (см. http://msdn.microsoft.com/en-us/library/ms686324.aspx) и проверить код ошибки. Внутри службы это будет ERROR_SERVICE_ALREADY_RUNNING.

0 голосов
/ 30 июня 2010

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

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

Так что, насколько мне известно, у dll нет хорошего способа определить это самостоятельно. Либо нужна программа хостинга, чтобы рассказать длл. Или же вам нужно пересмотреть свой дизайн. Почему DLL на самом деле нужно это знать? И есть ли альтернативные способы заставить его работать так, чтобы об этом не нужно было знать?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...