Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Terminalserver-Betrieb unter 64bit erkennen (https://www.delphipraxis.net/181979-terminalserver-betrieb-unter-64bit-erkennen.html)

mfahs 22. Sep 2014 16:19

Terminalserver-Betrieb unter 64bit erkennen
 
Hallo!

Ich habe mit der "JEDI API 2.3" ein paar Routinen erstellt, mit denen ich seit Jahren ganz prima herausfinden kann, ob eine Anwendung auf einem Terminalserver gestartet wird und wie in diesem Fall der Name der tatsächlichen Workstation (also der am TS angemeldeten Maschine!) lautet. Das läuft - wie schon erwähnt - seit Jahren einwandfrei.

Nun hat mich vor einiger Zeit der Teufel geritten und ich hatte das "Bedürfnis", eine reine 64-Bit-Anwendung mit Delphi XE6 zu erstellen.
Von einigen anderen Dingen abgesehen (die ich alle entsprechend anpassen kann), ist es mir bisher nicht gelungen, die oben erwähnten Funktionen auch unter 64bit zum Laufen zu bringen.

Wie gesagt: Ich muss herausfinden können, ob eine Anwendung überhaupt auf einem TS gestartet wird und - wenn das der Fall ist - wie der Rechner heißt, der am TS angemeldet ist. Der Name des TS selbst ist mir völlig egal, es geht um den Arbeitsplatz, an dem der Anwender sitzt!

Hat jemand eine Idee, mit welchen Tricks und/oder Hilfsmitteln das unter 64bit rauszubekommen ist?

Besten Dank schon mal für die vielen tollen Ideen :-)

Martin

WilliWinzig 22. Sep 2014 17:41

AW: Terminalserver-Betrieb unter 64bit erkennen
 
Die Antwort lautet:

Delphi-Quellcode:
uses System.SysUtils;
.....

function isTSClient: Boolean;
var cClient : String;
begin

cClient:= Trim(GetEnvironmentVariable('CLIENTNAME'));

Result:= Length(cClient) > 0;
end;
Die Funktion liefert allerdings auch bei RDP-Zugriff auf normalen PC's "TRUE" zurück
da Clientname immer bei RDP-Verbindungen gesetzt wird.

MfG

jensw_2000 22. Sep 2014 20:10

AW: Terminalserver-Betrieb unter 64bit erkennen
 
Alternativ kannst Du anstatt der "CLIENTNAME" die Umgebungsvariable "SESSIONNAME" abfragen.

Der Verhalten ist dort wie folgt:
SESSIONNAME=Console
(User arbeitet lokal oder die RDP Session ist als Console gestartet (mit mstsc -admin). Für die Admin Session braucht man wenigstens lokale Admin Rechte auf dem Zielserver und es ist nur eine Consolen Session zur Zeit pro Server möglich.

SESSIONNAME=RDP-Tcp#nnn (nnn = Sessionnummer)
(User arbeitet per RDP Client auf einem Terminalserver.)

SESSIONNAME=ICA-Tcp#nnn (nnn = Sessionnummer)
(User arbeitet per Citrix ICA / XenApp Client auf einem Citrix Terminalserver.)

mfahs 22. Sep 2014 21:47

AW: Terminalserver-Betrieb unter 64bit erkennen
 
Besten Dank für die Tipps. Das sieht tatsächlich ganz gut aus!
Dann werde ich meine Routinen mal umstellen.

Danke!

Martin

Remko 20. Feb 2015 16:44

AW: Terminalserver-Betrieb unter 64bit erkennen
 
In my opinion reading the environment variable is the wrong way as there's no guarantee that the variable will be set.
The "proper" way is to call the GetSystemMetrics API with the SM_REMOTESESSION parameter.

Zitat:

This system metric is used in a Terminal Services environment. If the calling process is associated with a Terminal Services client session, the return value is nonzero. If the calling process is associated with the Terminal Services console session, the return value is 0.
Windows Server 2003 and Windows XP: The console session is not necessarily the physical console. For more information, see WTSGetActiveConsoleSessionId.

HolgerX 21. Feb 2015 14:57

AW: Terminalserver-Betrieb unter 64bit erkennen
 
Hallo..

Envoimentvariablen sollten besser nicht genutzt werden.

Wie bereits gesagt, kann da alles liegen, gerade in TherminalServer-Umgebungen wird dort oft durch loginScripte anderes eingetragen.

Hier eine Routine, welche funktioniert, mit Delphi6 - XE6.

Code:
uses
  Windows, wtsapi32;


function ProcessIdToSessionId(dwProcessId: DWORD;var pSessionId: DWORD): BOOL; stdcall; external kernel32 name 'ProcessIdToSessionId';


function GetPCSystemName : WideString;
var
  lpBuf : PWideChar;
  nSi : DWORD;
begin
  Result := '';
  nSi := (1024 + 2) * SizeOf(WideChar);
  GetMem(lpBuf, nSi);
  try
    if GetComputerNameW(lpBuf, nSi) then Result := lpBuf;
  finally
    FreeMem(lpBuf);
  end;
end;

function GetPCClientName : WideString;
var
  nProcessID, nSessionID : DWORD;
  nByteCount : DWORD;
  acNameBuff : Pointer;
  tmpName   : WideString;
begin
  // Lokaler HostName
  Result := GetPCSystemName;
  nProcessID := GetCurrentProcessId;
  nSessionID := 0;
  //PROCESS_QUERY_INFORMATION wird benötigt für ProcessIdToSessionID         "SeDebugPrivilege"
  // SessionID von aktueller ProcessID
  if ProcessIdToSessionID( nProcessID, nSessionID) then begin
    // Wenn in einer Session..
    if nSessionID > 0 then begin
      // Session ClientName
      if WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, nSessionId, WTSClientName, acNameBuff, nByteCount) then begin
        try
          tmpName := PWideChar(acNameBuff);
          // Da bei Vista kein Name vorhanden ist, auf Leerstring prüfen!
          if tmpName <> '' then
            result := tmpName;
        finally
          WTSFreeMemory(acNameBuff);
        end;
      end;
    end;
  end;
end;

Mit ProcessIdToSessionId Kannst Du ermitteln, ob deine App in einer Therminal-Session läuft und dann kannste mit WTSQuerySessionInformationW den ClientSession-Name auslesen.

Dies funktioniert (getestet) ab WinXP bis zu Win8.1 (64Bit).


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:25 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz