Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Обнаружить терминальные сервисы

Delphi , Программа и Интерфейс , Процессы и Сервисы

Обнаружить терминальные сервисы

Оформил: DeeCo
Автор: http://www.swissdelphicenter.ch

{ 
 Question: 

 Do you happen to have a sample piece of code for detecting if Terminal 
 Services is loaded?  I found this piece of C code, but I'm having a hard 
 time translating things... 
}

 function IsRemoteSession: Boolean;
 const
   sm_RemoteSession = $1000; { from WinUser.h }
 begin
   Result := (GetSystemMetrics(sm_RemoteSession) <> 0);
 end;

 { 
  That tells you if your program is running in a terminal client session, 
  which is usually all you ever need to worry about. 
}

 { 
> 
> #include <windows.h> 
> #include <stdio.h> 
> 
> // This code will only work on the Windows 2000 platform 
> 
> BOOL IsTerminalServicesEnabled(void) 
> { 
>      OSVERSIONINFOEX osVersionInfo; 
>      DWORDLONG dwlConditionMask = 0; 
> 
>      ZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX)); 
>      osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); 
>      osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL; 
> 
>      VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND ); 
> 
>      return VerifyVersionInfo( 
>          &osVersionInfo, 
>          VER_SUITENAME, 
>          dwlConditionMask 
>          ); 
> 
}

 type
   OSVERSIONINFOEX = packed record
     dwOSVersionInfoSize: DWORD;
     dwMajorVersion: DWORD;
     dwMinorVersion: DWORD;
     dwBuildNumber: DWORD;
     dwPlatformId: DWORD;
     szCSDVersion: array[0..127] of Char;
     wServicePackMajor: WORD;
     wServicePackMinor: WORD;
     wSuiteMask: WORD;
     wProductType: BYTE;
     wReserved: BYTE;
   end;
   TOSVersionInfoEx = OSVERSIONINFOEX;
   POSVersionInfoEx = ^TOSVersionInfoEx;

 const
   VER_SUITE_TERMINAL = $00000010;
   VER_SUITENAME = $00000040;
   VER_AND = 6;

 function VerSetConditionMask(
   ConditionMask: int64;
   TypeMask: DWORD;
   Condition: Byte
   ): int64; stdcall; external kernel32;

 function VerifyVersionInfo(
   var VersionInformation: OSVERSIONINFOEX;
   dwTypeMask: DWORD;
   dwlConditionMask: int64
   ): BOOL; stdcall; external kernel32 name 'VerifyVersionInfoA';


 function IsTerminalServicesEnabled: Boolean;
 var
   osVersionInfo: OSVERSIONINFOEX;
   dwlConditionMask: int64;
 begin
   FillChar(osVersionInfo, SizeOf(osVersionInfo), 0);
   osVersionInfo.dwOSVersionInfoSize := sizeof(osVersionInfo);
   osVersionInfo.wSuiteMask := VER_SUITE_TERMINAL;
   dwlConditionMask := 0;
   dwlConditionMask :=
     VerSetConditionMask(dwlConditionMask,
     VER_SUITENAME,
     VER_AND);
   Result := VerifyVersionInfo(
     osVersionInfo,
     VER_SUITENAME,
     dwlConditionMask);
 end;

 { 
  But heed the warning in the C sample: the functions used here are not 
  available on Win 9x and NT 4! If you use external declarations as above 
  your program would not even load on such a platform. 
}

Прекрасный код!

Цель - обнаружить, включен ли Terminal Services (Remote Desktop) или нет. Есть два подхода:

  1. Delphi версия:
function IsRemoteSession: Boolean;
const
  sm_RemoteSession = $1000; // из WinUser.h
begin
  Result := (GetSystemMetrics(sm_RemoteSession) <> 0);
end;

Функция использует функцию GetSystemMetrics для проверки, запущен ли клиентский сеанс терминала. Этот подход работает только на системах Windows NT-основанных.

  1. C версия:
#include <windows.h>
#include <stdio.h>

BOOL IsTerminalServicesEnabled(void) {
  OSVERSIONINFOEX osVersionInfo;
  DWORDLONG dwlConditionMask = 0;

  ZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX));
  osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL;

  VER_SET_CONDITION(dwlConditionMask, VER_SUITENAME, VER_AND);

  return VerifyVersionInfo(
     &osVersionInfo,
    VER_SUITENAME,
    dwlConditionMask
   );
}

Функция использует структуру OSVERSIONINFOEX для запроса информации о версии системы и проверки, включен ли Terminal Services. Функция VerifyVersionInfo проверяет информацию о версии на основе маски условия.

Важные примечания:

  • Обе функции имеют ограничения:
    • Delphi-версия работает только на системах Windows NT-основанных.
    • C-версия требует Windows 2000 или позднее, так как она использует структуру OSVERSIONINFOEX и функцию VerifyVersionInfo, которые не доступны на более ранних версиях Windows.
  • Если вы хотите поддерживать старые платформы (Win9x и NT4), вам нужно использовать альтернативные методы.

Теперь давайте подробно рассмотрим код:

Delphi-версия:

  • Функция IsRemoteSession использует функцию GetSystemMetrics из заголовочного файла WinUser.h.
  • Она возвращает булевое значение, указывающее, запущен ли клиентский сеанс терминала или нет.
  • Константа sm_RemoteSession определена как $1000, что соответствует флагу SM_REMOTESESSION.

C-версия:

  • Функция IsTerminalServicesEnabled использует структуру OSVERSIONINFOEX для запроса информации о версии системы.
  • Она настраивает структуру osVersionInfo с помощью полей dwOSVersionInfoSize и wSuiteMask.
  • Макрос VER_SET_CONDITION используется для установки маски условия, которая затем передается функции VerifyVersionInfo.
  • Если информация о версии системы соответствует маске условия (то есть Terminal Services включен), функция возвращает TRUE.

Альтернативный подход:

Если вы хотите обнаружить Terminal Services на старых платформах или использовать другой метод, рассмотрите следующие подходы:

  1. Проверьте, запущен ли сервис Remote Desktop Connection (RDP):
function IsTerminalServicesEnabled: Boolean;
begin
  Result := ServiceIsRunning('RDP');
end;

function ServiceIsRunning(ServiceName: String): Boolean;
var
  hSCManager: THandle;
  hService: THandle;
begin
  hSCManager := OpenSCManager(nil, nil, SC_MANAGER_CONNECT);
  if (hSCManager = 0) then
    Exit(FALSE);

  hService := OpenService(hSCManager, PChar(ServiceName), SERVICE_QUERY_STATUS);
  if (hService = 0) then
    Exit(FALSE);

  Result := QueryServiceStatus(hService, nil).dwState = SERVICE_RUNNING;

  CloseServiceHandle(hService);
  CloseServiceHandle(hSCManager);
end;
  1. Проверьте наличие определенной регистрационной ключи или значения:
function IsTerminalServicesEnabled: Boolean;
var
  RegKey: TRegistry;
begin
  Result := False;

  RegKey := TRegistry.Create(KEY_READ);
  try
    RegKey.RootKey := HKEY_LOCAL_MACHINE;
    if RegKey.OpenKey('SYSTEM\CurrentControlSet\Control\Terminal Server', False) then
      Result := True;
  finally
    RegKey.Free();
  end;
end;

Обратите внимание, что эти альтернативные подходы могут иметь ограничения или требовать дополнительных зависимостей.

Обнаружение терминальных сервисов на Windows позволяет определить, запущена ли программа в сеансе клиентского терминала или нет.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Процессы и Сервисы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 13:28:15/0.0062229633331299/1