正确检测终端服务

时间:2010-07-07 16:39:50

标签: winapi windows-server-2003 terminal-services

我一直在尝试检测终端服务是否正在运行。我尝试使用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 );

效果很好,但是:

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

没有终端服务角色,对VerifyVersionInfo的调用返回非零值,这意味着“当前正在运行的操作系统满足指定的要求”或函​​数失败。

GetLastError返回:

0x000000cb "The system could not find the environment option that was entered."

在Windows XP SP3上,对VerifyVersionInfo的调用返回零值,因此我认为没有输入错误。

我该如何处理这种行为?如果没有终端服务那么对待这个好吗?有没有更好的技术?

这是操作系统中的错误吗?

更新

  

在Windows Server 2008上,R1的行为类似(失败)。可能也在许多其他系统上。

3 个答案:

答案 0 :(得分:0)

终端服务是一种NT服务,就像其他任何内部命名的TermServices一样,如果你有权限.privilege来访问服务管理器,你可以在那里进行轮询以查看它是否正在运行:

OpenSCManager OpenService QueryServiceStatus

答案 1 :(得分:0)

好吧,我找到了几乎可行的解决方案(仅在Win2k服务器上失败)。

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 );

有趣的事实 - 调用VerifyVersionInfo不会修改上一个错误代码。

答案 2 :(得分:-1)

迟到的回复,但最好迟到,下面的代码是Delphi,但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;

或者如果要检查终端服务器服务是否正在运行:

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;