Правильное обнаружение терминальных сервисов - PullRequest
1 голос
/ 07 июля 2010

Я пытался определить, запущены ли службы терминалов. Я пытался использовать 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 с пакетом обновления 3 (SP3) вызов VerifyVersionInfo возвращает нулевое значение, поэтому, я полагаю, ошибок при печати нет.

Как мне справиться с этим поведением? Это хорошо, чтобы относиться к этому, как будто нет терминальных служб? Есть ли лучшие методы?

Это ошибка в ОС?

Обновление:

В Windows Server 2008 R1 поведение аналогичное (не удается). Может быть и во многих других системах.

Ответы [ 3 ]

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

Ну, я нашел почти работающее решение (не работает только на сервере 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 не изменяет код последней ошибки. Код ошибки 0x000000cb, который возвращает мне GetLastError, является просто мусором.

0 голосов
/ 03 декабря 2010

Поздний ответ, но лучше поздно, чем никогда, код ниже - 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;
0 голосов
/ 10 июля 2010

Terminal Services - это NT-сервис, как и любой другой, с внутренним именем TermServices, и если у вас есть разрешение .privilege для доступа к диспетчеру сервисов, вы можете опросить там, чтобы проверить, работает ли он:

OpenSCManager OpenService QueryServiceStatus

...