DOBON.NET DOBON.NETプログラミング掲示板過去ログ

WTSQuerySessionInfomationの使い方について

環境/言語:[VB.NET2003,WindowsServer2003]
分類:[.NET]

2005/09/02(Fri) 15:24:25 編集(投稿者)
2005/09/02(Fri) 15:24:17 編集(投稿者)

VB.NET2003で開発を行っています。
ターミナルサービスに接続しているクライアントの情報を取得したく
WTSQuerySessionInfomationを使用したいのですが、使い方が分かりません。
WTSQuerySessionInfomationの使い方を教えてください。
よろしくお願いします。
> WTSQuerySessionInfomationを使用したいのですが、使い方が分かりません。

どのような用途で使いたいのかがわからなかったので……概要だけ書きます。

第1引数: WTSOpenServer 関数で開いたハンドル。
第2引数: セッション識別子。現セッションなら WTS_CURRENT_SESSION。
第3引数: 情報の種類。WTS_INFO_CLASS列挙型のいずれかを指定。
第4引数: 第3引数で指定した情報の戻り値。データ型は情報の種類によって異なる。
第5引数: 第4引数に格納されたバイト数の戻り値。
■No12610に返信(魔界の仮面弁士さんの記事)
>>WTSQuerySessionInfomationを使用したいのですが、使い方が分かりません。
>
> どのような用途で使いたいのかがわからなかったので……概要だけ書きます。
>
> 第1引数: WTSOpenServer 関数で開いたハンドル。
> 第2引数: セッション識別子。現セッションなら WTS_CURRENT_SESSION。
> 第3引数: 情報の種類。WTS_INFO_CLASS列挙型のいずれかを指定。
> 第4引数: 第3引数で指定した情報の戻り値。データ型は情報の種類によって異なる。
> 第5引数: 第4引数に格納されたバイト数の戻り値。

返信ありがとうございます。

一応色々調べてみて下記のように書いてみました

  Public Function Get_WTSQuerySessionInformation(ByVal inWTSInfoClass As WTS_INFO_CLASS, ByRef 取得文字列 As String) As Boolean
    Dim l_strRet As String = ""

    Dim hServer As Integer
    Dim blnRet As Boolean
    Dim dwBytesReturned As Integer
    Dim lpBuffer As Integer


    Const WTS_CURRENT_SESSION As Integer = 0

    hServer = WTSOpenServer(0)


    blnRet = WTSQuerySessionInformation(hServer, WTS_CURRENT_SESSION, inWTSInfoClass, lpBuffer, dwBytesReturned)
    If blnRet Then
      l_strRet = GetStringFromPointer(lpBuffer)

      Call WTSFreeMemory(lpBuffer)
    End If

    取得文字列 = l_strRet

    Return blnRet
  End Function

結果は、空文字が返ってきてうまくいきませんでした。
何がいけないのか分かりませんでした。
APIは、Declare宣言(またはDllImport)の書き方によって、呼び出し方も
変わってきますので、呼び出し部分だけでは判断しにくいです。

第三者がコピー & ペーストするだけでテストできるよう、現在の宣言部分も
含めた、「そのまま動作する最低限のソースコード」を公開してもらえると、
どこに問題があるのか検証しやすいです。m(_ _)m

> 結果は、空文字が返ってきてうまくいきませんでした。
こちらでコードを試していないので、どこで問題が起きているのか、
あまり把握できていないのですが……まず、問題の切り分けをしましょう。

1. それぞれのWin32 API関数は、適切な値を返しているのでしょうか?
返していないものがあるとすれば、それはどの関数の呼び出し部分ですか?

2. それぞれの関数呼出し後に、Err.LastDllError の値はどうなっていますか?

3. WTSQuerySessionInfomation は、UnicodeエントリとAnsiエントリとが
 あるかと思いますが、今回はどちらを呼び出しているのでしょうか?
返信ありがとうございます

確かにご指摘の通りあれだけじゃ分からないですね。

一応こんな感じです。

Imports System.Runtime.InteropServices

Public Class WtsApi
Public Enum WTS_INFO_CLASS
WTSInitialProgram
WTSApplicationName
WTSWorkingDirectory
WTSOEMId
WTSSessionId
WTSUserName
WTSWinStationName
WTSDomainName
WTSConnectState
WTSClientBuildNumber
WTSClientName
WTSClientDirectory
WTSClientProductId
WTSClientHardwareId
WTSClientAddress
WTSClientDisplay
WTSClientProtocolType
End Enum

<DllImport("kernel32.dll")> _
Private Shared Function lstrlen(ByVal Ptr As Integer) As Integer

End Function

<DllImport("kernel32.dll")> _
Private Shared Function lstrcpy(ByVal lpString1 As Integer, ByVal lpString2 As Integer) As Integer

End Function


<DllImport("wtsapi32.dll")> _
Private Shared Function WTSOpenServer(ByVal pServerName As Integer) As Integer

End Function

<DllImport("wtsapi32.dll")> _
Private Shared Sub WTSFreeMemory(ByRef pMemory As Integer)

End Sub

<DllImport("wtsapi32.dll")> _
Private Shared Function WTSQuerySessionInformation(ByVal hServer As Integer, ByVal SessionId As Integer _
, ByVal WTSInfoClass As WTS_INFO_CLASS, ByRef ppBuffer As Integer _
, ByRef pBytesReturned As Integer) As Boolean
End Function


Public Function Get_WTSQuerySessionInformation(ByVal inWTSInfoClass As WTS_INFO_CLASS, ByRef 取得文字列 As String) As Boolean
Dim l_strRet As String = ""

Dim hServer As Integer
Dim blnRet As Boolean
Dim dwBytesReturned As Integer
Dim lpBuffer As Integer


Const WTS_CURRENT_SESSION As Integer = 0
Const WTS_CURRENT_SERVER_HANDLE As Integer = 1

hServer = WTSOpenServer(0)


blnRet = WTSQuerySessionInformation(hServer, WTS_CURRENT_SESSION, inWTSInfoClass, lpBuffer, dwBytesReturned)
'blnRet = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, inWTSInfoClass, lpBuffer, dwBytesReturned)
If blnRet Then
l_strRet = GetStringFromPointer(lpBuffer)

Call WTSFreeMemory(lpBuffer)
End If

取得文字列 = l_strRet

Return blnRet
End Function

'*********************************************
'**   ポインタから文字列取得
'*********************************************
Private Function GetStringFromPointer(ByVal inPointer As Integer) As String
Dim l_strRet As String = ""

'文字長取得
Dim l_intLen As Integer = lstrlen(inPointer)
If (l_intLen > 0) Then
Dim bytAry(l_intLen - 1) As Byte

Dim gch As GCHandle = GCHandle.Alloc(bytAry, GCHandleType.Pinned)
Dim address As Integer = gch.AddrOfPinnedObject().ToInt32()

Call lstrcpy(address, inPointer)
gch.Free()

Call Conv_UTF8_to_SJIS(bytAry, l_strRet)
End If

Return l_strRet
End Function


'*********************************************
'**   エンコード変換
'*********************************************
Private Sub Conv_UTF8_to_SJIS(ByVal inByte() As Byte, ByRef otStr As String)
Dim strSJIS As Encoding = Encoding.GetEncoding("Shift-JIS")
Dim strUTF8 As Encoding = Encoding.UTF8

Dim asciiBytes As Byte() = Encoding.Convert(strUTF8, strSJIS, inByte)
Dim chrSJIS(strSJIS.GetCharCount(asciiBytes, 0, asciiBytes.Length - 1)) As Char
strSJIS.GetChars(asciiBytes, 0, asciiBytes.Length, chrSJIS, 0)
otStr = New String(chrSJIS)
End Sub

End Class
■No12609に返信(Michiさんの記事)
> 2005/09/02(Fri) 15:24:25 編集(投稿者)
> 2005/09/02(Fri) 15:24:17 編集(投稿者)
>
> VB.NET2003で開発を行っています。
> ターミナルサービスに接続しているクライアントの情報を取得したく
> WTSQuerySessionInfomationを使用したいのですが、使い方が分かりません。
> WTSQuerySessionInfomationの使い方を教えてください。
> よろしくお願いします。
>
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板