I'm writing an application that is able to run as a service or standalone but I want to detect if the application was executed as a service or in a normal user session.
views:
108answers:
4I think you can query the process token for membership in the Interactive group.
From http://support.microsoft.com/kb/243330:
SID: S-1-5-4
Name: Interactive
Description: A group that includes all users that have logged on interactively. Membership is controlled by the operating system.
Call GetTokenInformation with TokenGroups to get the groups associated with the account under which the process is running, then iterate over the sids looking for the Interactive sid.
I found a nice chunk of code at http://marc.info/?l=openssl-dev&m=104401851331452&w=2
Another option would be to use System.Environment.UserInteractive http://msdn.microsoft.com/en-us/library/system.environment.userinteractive.aspx
Update: To make up for posting a .NET answer to a C++ topic, I provide a C implementation based on the .NET implementation.
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;
}
Process in normal user session always has a window station called 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
}