Я пишу приложение, которое может работать как услуга или автономный, но я хочу обнаружить, если приложение выполнялось как услуга или на сессии обычного пользователя.
Я думаю, вы можете запросить токен процесса для членства в интерактивной группе.
Из http://support.microsoft.com/kb/243330 :
SID: S-1-5-4
Название: Интерактивный
Описание: Группа, которая включает всех пользователей, которые вошли в систему в интерактивном режиме. Членство контролируется операционной системой.
Вызовите GetTokenInformation с TokenGroups, чтобы получить группы, связанные с учетной записью, под которой выполняется процесс, затем переберите идентификаторы sid в поисках интерактивного sid.
Я нашел хороший фрагмент кода на http://marc.info/?l=openssl-dev&m=104401851331452&w=2
Я думаю, вы можете основывать свое обнаружение на том факте, что службы работают с SessionID 0, а учетные записи пользователей имеют другие значения (например, 1).
bServiceMode = false;
SessionID=-1;
Size=0;
hToken = NULL;
(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
GetLastError();
if (!GetTokenInformation(hToken, TokenSessionId, &SessionID, sizeof(SessionID), &Size) || !Size)
return FALSE;
if(SessionID==0)
bServiceMode = true;
Другой вариант - использовать System.Environment.UserInteractive http://msdn.microsoft.com/en-us/library/system.environment.userinteractive.aspx
Обновление : чтобы компенсировать публикацию ответа .NET на тему C ++, я предоставляю реализацию C, основанную на реализации .NET.
BOOL IsUserInteractive()
{
BOOL bIsUserInteractive = TRUE;
HWINSTA hWinStation = GetProcessWindowStation();
if (hWinStation != NULL)
{
USEROBJECTFLAGS uof = {0};
if (GetUserObjectInformation(hWinStation, UOI_FLAGS, &uof, sizeof(USEROBJECTFLAGS), NULL) && ((uof.dwFlags & WSF_VISIBLE) == 0))
{
bIsUserInteractive = FALSE;
}
}
return bIsUserInteractive;
}
Процесс в обычном сеансе пользователя всегда имеет оконную станцию с именем WinSta0 .
wchar_t buffer[256] = {0};
DWORD length = 0;
GetUserObjectInformation(GetProcessWindowStation(), UOI_NAME, buffer, 256, &length);
if (!lstricmp(buffer, "WinSta0")) {
// normal user session
} else {
// service session
}