2010-11-15 40 views
8

Ich bin auf der Suche nach einer API/Funktion, die ich aufrufen kann, um festzustellen, ob Software auf Citrix, Terminal Services oder einem eigenständigen PC ausgeführt wird. Optimal wäre es so etwas wie dies funktioniert:API zum Ermitteln, ob App auf Citrix oder Terminaldienste ausgeführt wird

Select Case APIWhatSystem.Type.ToString 
    Case "Citrix" 
     bCitrix = True 
    Case "TS" 
     bTerminalServices = True 
    Case "PC" 
     bPC = True 
End Select 

Ich würde lieber etwas, das von einem API-Aufruf arbeitete als auf dem Blick auf etwas in der Registrierung im Gegensatz wir immer mehr Kunden mit, die die Registrierung sind Sperren .

Danke.

+2

Ich habe dies gefunden ... SystemInformation.TerminalServerSession, die booleschen Wert zurückgibt, so dass die TS-Frage beantwortet. Ich bin mir nicht sicher, ob es bool für Citrix zurückgibt. Immer noch untersuchen. –

+0

Ich fand es für Citrix und Windows 2008 Server TS ThinApp wahr. –

Antwort

6

Gemäß: http://forums.citrix.com/message.jspa?messageID=1363711 können Sie die Umgebungsvariable SESSIONNAME überprüfen.

Eine andere einfachere Möglichkeit ist das Lesen der Systemumgebungsvariablen "SESSIONNAME". Wenn es existiert und mit "ICA" beginnt, dann laufen Sie innerhalb einer Citrix Sitzung. Wenn es mit "RDP" beginnt, dann laufen Sie innerhalb einer RDP-Sitzung.

Getestet habe ich es mit meinem PC und lokal erhalte ich:

C:\>echo %SESSIONNAME% 
Console 

Während der Ferne habe ich

C:\>echo %SESSIONNAME% 
RDP-tcp1 

So scheint es, wie es ein einfacher Weg sein könnte zu gehen, es anders klingt wie nach Registrierungswerten zu suchen oder wenn bestimmte dlls existieren, ist die nächstbeste Sache.

3

Nach @ Joshs Antwort, würde der Code wie folgt aussehen:

Select Case Environment.GetEnvironmentVariable("SessionName").ToUpper.SubString(0,3)) 
    Case "ICA" 
     bCitrix = True 
    Case "RDP" 
     bTerminalServer = True 
    Case "CON" 
     bPC = True 
End Select 

Ich habe nicht voll es noch nicht getestet, aber es sieht aus wie es das tun, was ich will. PCs und Terminalserver meldet korrekt.

Wenn jemand eine Möglichkeit hat, dies auf einer Citrix-Box zu testen, wäre es sehr zu empfehlen!

+0

Funktioniert für mich. Auf meinem Citrix Server '? Environ (" SessionName ") gibt' ICA-tcp # 56' zurück. – mischab1

+3

Beachten Sie, dass diese env.variable im Windows 2008 TS RemoteApp-Modus nicht vorhanden ist – user545829

11

Es gibt eine API-Funktion, mit der Sie bestimmen können, ob eine bestimmte Benutzersitzung auf der Konsole angezeigt wird (lokal) oder über eines der Remoting-Protokolle Citrix ICA (heute HDX) oder Microsoft RDP.

Rufen Sie WTSQuerySessionInformation mit 3. Parameter auf WTSClientProtocolType. Die Funktion gibt:

  • 0 für Konsolensitzungen
  • 1 für ICA-Sitzungen
  • 2 für RDP-Sitzungen

Interessanter der Rückgabewert von 1 ist nicht als WTS_PROTOCOL_TYPE_ICA auf MSDN (zweite Verbindung dokumentiert oben) nicht mehr, sondern als "Dieser Wert wird für ältere Zwecke beibehalten.".

Update:

XenDesktop Sitzungen können nicht mit WTSQuerySessionInformation nachgewiesen werden (es gibt 0 zurück, was bedeutet, Console).Wenn Sie eine universelle Lösung wünschen:

  • Anruf WTSQuerySessionInformation. Wenn das 1 oder 2 (ICA oder RDP) zurückgibt, sind Sie fertig.
  • Wenn WTSQuerySessionInformation 0 zurück (Konsole), dynamisch laden wfapi.dll und erhält die Adresse WFGetActiveProtocol
  • Anruf WFGetActiveProtocol mit einem Parameter von WF_CURRENT_SESSION, die definiert ist als ((DWORD) -1)
  • Der Rückgabewert von WFGetActiveProtocol ist der Sitzungstyp. Es sollte entweder 0 (Konsole) oder 1 (ICA)

sein ich den Prozess im Detail beschrieben wurden here zusammen mit einem C++ Code Probe und einer Arbeits kompilierten Werkzeug, das der aktuellen Sitzung des remoting Protokolltyp zurückgibt.

+0

Glauben Sie, es wäre sicher anzunehmen, wenn diese Funktion eine Zahl größer als 0 zurückgibt, läuft die App nicht auf einem PC? dh. Es muss auf einer Art Server laufen. Ich denke wie 5 Jahre in der Zukunft ... so oder so sollte eine Nicht-Null immer etwas anderes als einen PC anzeigen, oder? –

+0

Ja, ich denke wenn es sicher wäre anzunehmen, dass alles> 0 ist ... NICHT LOKAL. Bitte beachten Sie den Unterschied im Wortlaut. Es kann sehr gut auf einem PC laufen, aber mit dem heutigen heißen Thema "VDI" alias virtuelle Desktops über einige Remoting-Protokolle (think 2008 R2 SP1 - RemoteFX) steigt die Wahrscheinlichkeit stetig, dass PCs bald zu 1-Session-Terminal-Servern werden. –

+0

Wenn die Anwendung unter Citrix XenApp ausgeführt wird, dann wird WTSClientProtocolType zurückkehren 1. Wenn jedoch wird die Anwendung unter Citrix XenDesktop ausgeführt wird, dann wird WTSClientProtocolType 0. kehre ich bin immer noch nach einem Weg suchen, um es zu erkennen, die doesn Sie müssen die Geräte nicht aufzählen und nach bekannten virtuellen Treibern suchen. – DHW

2

Basierend auf Helge Keins überarbeiteter Antwort (oben) dachte ich, ich würde den VBA-Code veröffentlichen, um dies zu ermöglichen, damit zukünftige VBA-Benutzer diese Seite erreichen können. Helge hat bereits den C++ Code auf seiner eigenen Seite. Wenn Sie dies hilfreich finden, bitten wir Sie, Helge Klein zu antworten.

Option Explicit 

Private Const WTS_CURRENT_SERVER_HANDLE = 0& 
Private Const WTS_CURRENT_SESSION As Long = -1 

Private Enum WTS_INFO_CLASS 
    WTSInitialProgram 
    WTSApplicationName 
    WTSWorkingDirectory 
    WTSOEMId 
    WTSSessionId 
    WTSUserName 
    WTSWinStationName 
    WTSDomainName 
    WTSConnectState 
    WTSClientBuildNumber 
    WTSClientName 
    WTSClientDirectory 
    WTSClientProductId 
    WTSClientHardwareId 
    WTSClientAddress 
    WTSClientDisplay 
    WTSClientProtocolType 
    WTSIdleTime 
    WTSLogonTime 
    WTSIncomingBytes 
    WTSOutgoingBytes 
    WTSIncomingFrames 
    WTSOutgoingFrames 
    WTSClientInfo 
    WTSSessionInfo 
    WTSSessionInfoEx 
    WTSConfigInfo 
    WTSValidationInfo 
    WTSSessionAddressV4 
    WTSIsRemoteSession 
End Enum 

Private Declare Function WTSQuerySessionInformation _ 
    Lib "wtsapi32.dll" Alias "WTSQuerySessionInformationA" (_ 
    ByVal hServer As Long, ByVal SessionId As Long, _ 
    ByVal WtsInfoClass As WTS_INFO_CLASS, _ 
    ByRef ppBuffer As LongPtr, _ 
    ByRef pBytesReturned As LongPtr _ 
    ) As Long 

Private Declare Function WFGetActiveProtocol _ 
    Lib "wfapi.dll" (_ 
    ByVal SessionId As Long _ 
    ) As Long 

Private Declare Sub WTSFreeMemory Lib "wtsapi32.dll" (_ 
    ByVal pMemory As Long) 

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (_ 
    Destination As Any, Source As Any, ByVal length As Long) 

Public Function SessionType() As String 
    Dim ResultCode As Long 
    Dim p As LongPtr 
    Dim ppBuffer As LongPtr 
    Dim pBytesReturned As Long 
    Dim ClientProtocolType As Integer 
    ResultCode = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSClientProtocolType, ppBuffer, pBytesReturned) 

    If ResultCode = 0 Then 
     p = ppBuffer 
     CopyMemory ClientProtocolType, ByVal p, pBytesReturned 
     WTSFreeMemory ppBuffer 
    End If 

    Select Case ClientProtocolType 
     Case 0: 
     On Error Resume Next 
     ResultCode = WFGetActiveProtocol(WTS_CURRENT_SESSION) 
     If Err.Number = 53 Then 
      SessionType = "Console" 
     ElseIf Err.Number = 0 Then 
      If ResultCode = 1 Then 
      SessionType = "Citrix" 
      Else 
      SessionType = "Console" 
      End If 
     End If 
     Err.Clear 
     On Error GoTo 0 
     Case 1: 
     SessionType = "Citrix" 
     Case 2: 
     SessionType = "RDP" 
     Case Else 
     SessionType = "Other (" & ClientProtocolType & ")" 
    End Select 
End Function 

Ich habe dies auf XenApp und XenDesktop getestet.