none
リモートコンピュータのRDPセッション情報を取得するには? RRS feed

  • 質問

  • こんにちは、いつもお世話になっています☆
    VC++ 2008 とWin XP w SP3(Win32 SDK)で開発をしています。

    現在、ある特定の端末で複数の端末のRDPのセッション情報(セッションの有無・接続元の端末・ユーザ情報)を取得する方法を探しております。

    50台あるVM(OSは全てXP w SP3)をユーザにリモートで接続して利用してもらう環境において、このVMのリモートのセッション情報を一括管理するアプリケーションを作成したいと考えております。

    ご存じの方がいらっしゃいましたら 、ご教示願えませんでしょうか?
    ヒントになる関数等だけでもかまいません。

    よろしくお願いいたします。

    2010年10月19日 3:00

回答

すべての返信

  • 以前は、ターミナルサービスと言っていたので、そちらの名前で探すとチラチラ出てきます。

    ターミナル サービス API
    http://msdn.microsoft.com/ja-jp/library/cc429370.aspx

    2010年10月19日 3:15
  • >Chukiさん

    早速のご回答ありがとうございます。
    テストプログラムを作成してみました。

    ところが・・・
    Windows 2003 Server の端末へはうまく行くのですが、Windows XPへ接続を確認しようすると、WTSOpenServerで失敗するんです。
    GetLastErrorを使ってみると「アクセスが拒否されました」と出ます。

    どちらの端末にもテストプログラムの実行ユーザはLocal Administratorsに入っているのですが・・・なぜなのでしょう?
    XPだと事前に何か設定をしておく必要があるのでしょうか?

    2010年10月19日 4:08
  • すいません、現在出先であるため確かめることができないのですが、下記の情報がありました。

    下記レジストリ項目に、DWORDとして「AllowRemoteRPC」を追加し、1を入れる必要がある場合があるそうです。

    HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server

    英語の資料になりますが、以下をご覧ください。

    「Big Problem : Access Denied when Using Qwinsta.exe or WTSOpenServer API」
    http://www.codesoil.net/2007/08/16/big-problem-access-denied-when-using-qwinstaexe-or-wtsopenserver-api/

    Windows 7とWindows Server 2008 R2で始めるデスクトップ仮想化【最終回】 - クラウド Watch
    http://cloud.watch.impress.co.jp/epw/docs/series/2008r2lab/20091211_334032.html

    • 回答としてマーク どらちん 2010年10月21日 9:37
    2010年10月19日 10:57
  • >Chukiさん
    ありがとうございます、無事WTSOpenServerできました!!

    接続はできたのですが・・・新たな疑問が・・・
    WTSOpenServer → WTSQuerySessionInformation → WTSCloseServerをさくっと行うテストプログラムを書いてみました。

    該当部分のソースは以下の通りなのですが・・・

     LPTSTR l_Buf1 = NULL;
     DWORD l_Buf1Size, l_Buf2Size;
     LPTSTR l_Buf2 = NULL;
     HANDLE l_hTS;

     l_hTS = WTSOpenServer(L"192.168.12.99");
     if(l_hTS != NULL)
     {
      if(WTSQuerySessionInformation(l_hTS, WTS_CURRENT_SESSION, WTSClientName, &l_Buf1, &l_Buf1Size) != 0)
      {
       if(WTSQuerySessionInformation(l_hTS, WTS_CURRENT_SESSION, WTSUserName, &l_Buf2, &l_Buf2Size) != 0)
       {
        MessageBox(NULL, l_Buf1, l_Buf2, MB_OK);
        WTSFreeMemory(&l_Buf2);
       }
       else
       {
        MessageBox(NULL, l_Buf1, L"取得失敗", MB_OK);
       }
       WTSFreeMemory(&l_Buf1);

      }
      WTSCloseServer(l_hTS);
     }
     else
     {
      LPVOID lpMessageBuffer;
      FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMessageBuffer, 0, NULL);

      MessageBox(NULL, (LPCTSTR)lpMessageBuffer, L"接続失敗", MB_OK);
      LocalFree( lpMessageBuffer );

     }


    デバッグを実行すると、WTSCloseServer のところで必ず「Windowsによってxxxx.exeでブレークポイントが発生しました。 ヒープが壊れていることが原因として考えられます。・・・」とメッセージが表示されてしまうのです。

    この関数を呼び出すタイミングに何か問題があるのでしょうか・・・?

    2010年10月20日 2:03
  • l_Buf2 とか l_Buf1を解放するので

    WTSFreeMemory(l_Buf2); //アンパサンドが要らない

    ですね^^;

     追伸:ためしに、アンパサンドをつけて実行したら、同じ状態になりました。

    • 編集済み ChukiMVP 2010年10月20日 14:45 検証結果報告
    2010年10月20日 14:44
  • とりあえず根拠を示さず回答してしまったのはあんまりなので^^;
    以下から見ても、WTSFreeMemoryは引数にポインタを取り、WTSQuerySessionInformationが引数にポインタのポインタを取ることから上記のことが言えると思います。

    VOID WTSFreeMemory(
     PVOID pMemory
    );
    

    「WTSFreeMemory 関数」
    http://msdn.microsoft.com/ja-jp/library/cc429617.aspx

    BOOL WTSQuerySessionInformation(
     HANDLE hServer,
     DWORD SessionId,
     WTS_INFO_CLASS WTSInfoClass,
     LPTSTR *ppBuffer,
     DWORD *pBytesReturned
    );
    

    WTSQuerySessionInformation 関数
    http://msdn.microsoft.com/ja-jp/library/cc429625.aspx

    2010年10月21日 1:22
  • >Chukiさん

    何とも情けないミス・・・失礼しました!!
    無事、問題なく動作することができました。

    本当にありがとうございました。

    2010年10月21日 9:37