I've been trying to detect whether or not the Terminal Services are running. I tried to use the MSDN Way:
OSVERSIONINFOEX osVersionInfo;
DWORDLONG dwlConditionMask = 0;
memset( &osVersionInfo, 0, sizeof( osVersionInfo ) );
osVersionInfo.dwOSVersionInfoSize = sizeof( osVersionInfo );
osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL;
VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
return VerifyVersionInfo( &osVersionInfo, VER_SUITENAME, dwlConditionMask );
It works well, but on:
OS Name: Microsoft(R) Windows(R) Server 2003, Enterprise Edition
OS Version: 5.2.3790 Service Pack 2 Build 3790
OS Manufacturer: Microsoft Corporation
OS Configuration: Standalone Server
OS Build Type: Multiprocessor Free
without Terminal Services role, the call to VerifyVersionInfo
returns a non-zero value which means "the currently running operating system satisfies the specified requirements" or the function fails.
GetLastError
returns:
0x000000cb "The system could not find the environment option that was entered."
On Windows XP SP3, a call to VerifyVersionInfo
returns a zero value, so there are no typing errors, I suppose.
How do I handle this behavior? Is it good to treat this as if there are no Terminal Services? Are there any better techniques?
Is it a bug in the OS?
Update:
On Windows Server 2008 R1 behavior is similar (fails). May be on many other systems too.
Terminal Services is an NT-service like any other, internally named TermServices
, and if you have the permission.privilege to access the service manager, you could poll there to see if it's running:
Well, I found almost working solution (fails only on Win2k server).
OSVERSIONINFOEX osVersionInfo;
DWORDLONG dwlConditionMask = 0;
memset( &osVersionInfo, 0, sizeof( osVersionInfo ) );
osVersionInfo.dwOSVersionInfoSize = sizeof( osVersionInfo );
osVersionInfo.wSuiteMask = VER_SUITE_SINGLEUSERTS;
VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
return !VerifyVersionInfo( &osVersionInfo, VER_SUITENAME, dwlConditionMask );
Interesting fact - call to VerifyVersionInfo do not modify last error code. Error code 0x000000cb that GetLastError returns to me is just a garbage.
A late reply but better late then never, the code below is Delphi but it wouldn't need much changes for c/c++
function AreWeRunningTerminalServices: Boolean;
var VersionInfo: TOSVersionInfoEx;
dwlConditionMask: Int64;
begin
// Zero Memory and set structure size
ZeroMemory(@VersionInfo, SizeOf(VersionInfo));
VersionInfo.dwOSVersionInfoSize := SizeOf(VersionInfo);
// We are either Terminal Server or Personal Terminal Server
VersionInfo.wSuiteMask := VER_SUITE_TERMINAL or VER_SUITE_SINGLEUSERTS;
dwlConditionMask := VerSetConditionMask(0, VER_SUITENAME, VER_OR);
// Test it
Result := VerifyVersionInfo(VersionInfo, VER_SUITENAME, dwlConditionMask);
end;
or if you want to check it the Terminal Server service is really running:
function IsTerminalServiceRunning: boolean;
var hSCM: HANDLE;
hService: HANDLE;
ServiceStatus: SERVICE_STATUS;
begin
Result := False;
// Open handle to Service Control Manager
hSCM := OpenSCManager(nil, SERVICES_ACTIVE_DATABASE, GENERIC_READ);
if hSCM > 0 then
begin
// Open handle to Terminal Server Service
hService := OpenService(hSCM, 'TermService', GENERIC_READ);
if hService > 0 then
begin
// Check if the service is running
QueryServiceStatus(hService, ServiceStatus);
Result := ServiceStatus.dwCurrentState = SERVICE_RUNNING;
// Close the handle
CloseServiceHandle(hService);
end;
// Close the handle
CloseServiceHandle(hSCM);
end;
end;
User contributions licensed under CC BY-SA 3.0