Estoy en busca de un API/función que puede llamar para determinar si se está ejecutando el software de Citrix, Terminal de Servicios, o en un puesto de PC. De manera óptima, sería trabajar algo como esto:

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

Yo preferiría algo que funcionaba a partir de una llamada a la API en vez de buscar algo en el registro que vamos a tener más y más los clientes que están cerrando el registro.

Gracias.

He encontrado esto… SystemInformation.TerminalServerSession que devuelve el valor Booleano, por lo que las respuestas que el TS pregunta. No estoy seguro de si devuelve bool para Citrix. Sigue investigando.
He encontrado es cierto para Citrix y Windows 2008 Server de TS ThinApp.

OriginalEl autor John Cruz | 2010-11-15

4 Comentarios

  1. 7

    De acuerdo a: http://forums.citrix.com/message.jspa?messageID=1363711 puede comprobar el SESSIONNAME variable de entorno.

    Otra manera más sencilla es leer la variable de entorno del sistema «SESSIONNAME». Si existe y se inicia con «ICA», a continuación, ejecuta dentro de una sesión de Citrix. Si comienza con «RDP», a continuación, ejecuta dentro de una sesión RDP.

    He probado con mi PC y, a nivel local puedo conseguir:

    C:\>echo %SESSIONNAME%
    Console

    Mientras remotamente tengo

    C:\>echo %SESSIONNAME%
    RDP-tcp1

    Por lo que parece que podría ser un camino fácil para ir, de lo contrario suena como la comprobación de valores del registro o si ciertos archivos dll existe será la mejor cosa siguiente.

    OriginalEl autor Josh Weatherly

  2. 12

    No es una función de la API que permite determinar si una determinada sesión de usuario se muestran en la consola (a nivel local) o a través de uno de los protocolos de comunicación remota Citrix ICA (hoy en día llamado HDX) o Microsoft RDP.

    Llamada WTSQuerySessionInformation con el 3er set de parámetros a WTSClientProtocolType. La función devuelve:

    • 0 para las sesiones de la consola
    • 1 de sesiones ICA
    • 2 para sesiones RDP

    Curiosamente, el valor de retorno de 1 no está documentado como WTS_PROTOCOL_TYPE_ICA en MSDN (segundo enlace de arriba), sino como «Este valor se mantiene por legado fines.».

    Actualización:

    XenDesktop sesiones no puede ser detectado con WTSQuerySessionInformation (devuelve 0, el significado de la Consola). Si desea una solución universal:

    • Llamada WTSQuerySessionInformation. Si devuelve 1 o 2 (ICA y RDP), que se realizan.
    • Si WTSQuerySessionInformation devuelve 0 (Consola), cargar dinámicamente wfapi.dll y obtener la dirección de WFGetActiveProtocol
    • Llamada WFGetActiveProtocol con un parámetro de WF_CURRENT_SESSION, que se define como ((DWORD)-1)
    • El valor de retorno de WFGetActiveProtocol es el tipo de sesión. Debe ser 0 (Consola) o 1 (ICA)

    He descrito en detalle el proceso aquí junto con un código C++ de la muestra y un trabajo compilado herramienta que devuelve el actual período de sesiones de la remoting tipo de protocolo.

    ¿Crees que sería seguro asumir que si la función devuelve CUALQUIER número mayor que 0, la aplicación no se está ejecutando en un PC? es decir. Eso tiene que estar en ejecución en algún tipo de servidor. Estoy pensando en como 5 años en el futuro… de cualquier manera no-cero siempre debe indicar algo distinto de un PC, ¿verdad?
    Sí, yo creo que si sería seguro asumir que cualquier cosa > 0 … NO LOCAL. Por favor, tenga en cuenta la diferencia en la redacción. Puede muy bien ejecutar en un PC, pero hoy, con el tema «VDI» aka escritorios virtuales, servido sobre algunos remoting (protocolo de pensar 2008 R2 SP1 – RemoteFX) la probabilidad aumenta de manera constante de la Pc a convertirse en 1-sesión de servidores de terminal server pronto.
    Si la aplicación se ejecuta en el servidor Citrix XenApp, entonces WTSClientProtocolType devolverá 1. Sin embargo, si la aplicación se está ejecutando bajo Citrix XenDesktop, entonces WTSClientProtocolType devolverá 0. Todavía estoy buscando una manera de detectar que no se trata de enumerar los dispositivos y buscando conocido controladores virtuales.
    XenApp y XenDesktop son fundamentalmente diferentes en la forma en que la interfaz con el sistema operativo. Mientras que XenApp oficialmente le dice al sistema operativo que utiliza un protocolo de comunicación remota XenDesktop redirige a la sesión de consola. La sesión del usuario, por tanto, no es un WTS sesión y WTSQuerySessionInformation no ayuda. Usted debe preguntar a otra pregunta con respecto a XenDesktop.
    Acabo de comprobar en un Windows 7 de 64 bits de la máquina con el XenDesktop 5.6 VDA instalado. Wfapi.dll y Wfapi64.dll se encuentran en el subdirectorio «ICAService» de la VDA directorio de instalación. También debe estar en la ruta, por lo que se puede encontrar en la consola con «donde wfapi.dll».

    OriginalEl autor Helge Klein

  3. 3

    Seguir a @Josh respuesta, el código sería este:

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

    Yo aún no has probado aún, pero parece que va a hacer lo que yo quiero. PCs y Servidores de Terminal server informes correctamente.

    Si alguien tiene una manera de probar esto en un cuadro de Citrix, sería muy apreciada!

    A mí me funciona. En mi servidor citrix ?environ("SessionName") devuelve ICA-tcp#56.
    Aviso, que en Windows 2008 RemoteApp de TS modo de env.variable está ausente

    OriginalEl autor John Cruz

  4. 2

    Basado en Helge Klein revisado de respuesta (arriba) y yo pensé que había puesto el código VBA para hacer que esto suceda para ayudar a los futuros VBA usuarios de golpear a esta página. Helge ya tiene el código de C++ en su propio sitio. Si usted encuentre útil esta información, por favor upvote Helge Klein respuesta.

    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

    He probado esto en XenApp y XenDesktop.

    OriginalEl autor DHW

Dejar respuesta

Please enter your comment!
Please enter your name here