8

ソフトウェアがCitrix、ターミナルサービス、またはスタンドアロンPCで実行されているかどうかを判断するために呼び出すことができるAPI/関数を探しています。最適には、次のように機能します。

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

レジストリをロックダウンしている顧客が増えているので、レジストリ内の何かを見るのではなく、API呼び出しから機能するものを好みます。

ありがとう。

4

4 に答える 4

15

特定のユーザー セッションをコンソール (ローカル) に表示するか、リモート プロトコル Citrix ICA (現在は HDX と呼ばれる) または Microsoft RDP のいずれかを介して表示するかを決定できる API 関数があります。

3 番目のパラメーターを WTSClientProtocolType に設定してWTSQuerySessionInformation呼び出します。関数は次を返します。

  • コンソール セッションの場合は 0
  • ICA セッションの場合は 1
  • RDP セッションの場合は 2

興味深いことに、1 の戻り値はWTS_PROTOCOL_TYPE_ICA、MSDN (上記の 2 番目のリンク) では文書化されていませんが、「この値は従来の目的のために保持されます。」 として文書化されています。

アップデート:

XenDesktopセッションは検出できませんWTSQuerySessionInformation(コンソールを意味する 0 を返します)。普遍的なソリューションが必要な場合:

  • コールしWTSQuerySessionInformationます。1 または 2 (ICA または RDP) が返された場合は、完了です。
  • WTSQuerySessionInformation0 (コンソール) を返す場合、動的にロードwfapi.dllしてアドレスを取得します。WFGetActiveProtocol
  • ((DWORD)-1) として定義されるWFGetActiveProtocolのパラメーターを使用して呼び出します。WF_CURRENT_SESSION
  • の戻り値WFGetActiveProtocolはセッション タイプです。0 (コンソール) または 1 (ICA) のいずれかである必要があります。

ここでは、C++ コード サンプルと、現在のセッションのリモート プロトコル タイプを返す実際のコンパイル済みツールと共に、このプロセスについて詳しく説明しました。

于 2010-11-15T21:28:38.603 に答える
9

http://forums.citrix.com/message.jspa?messageID=1363711によると、SESSIONNAME環境変数を確認できます。

もう1つの簡単な方法は、システム環境変数「SESSIONNAME」を読み取ることです。存在し、「ICA」で始まる場合は、Citrixセッション内で実行しています。「RDP」で始まる場合は、RDPセッション内で実行しています。

私は自分のPCでそれをテストし、ローカルで次のようになりました。

C:\>echo %SESSIONNAME%
Console

リモートで私は得た

C:\>echo %SESSIONNAME%
RDP-tcp1

したがって、簡単な方法のようです。そうでない場合は、レジストリ値を確認するか、特定のdllが存在するかどうかを確認するのが次善の策のようです。

于 2010-11-15T16:12:20.253 に答える
2

@Joshの回答に従うと、コードは次のようになります。

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

私はまだそれを完全にテストしていませんが、それは私が望むことをするように見えます。PCとターミナルサーバーは正しくレポートします。

誰かがCitrixボックスでこれをテストする方法を持っているなら、それは大いにありがたいです!

于 2010-11-15T21:19:11.307 に答える
2

Helge Klein の改訂された回答 (上記) に基づいて、VBA コードを投稿して、将来の VBA ユーザーがこのページにアクセスできるようにすることを考えました。Helge は既に彼自身のサイトに C++ コードを持っています。これが役立つと思われる場合は、Helge Klein の回答に賛成票を投じてください。

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

XenApp と XenDesktop でこれをテストしました。

于 2014-08-08T15:27:17.330 に答える