読者です 読者をやめる 読者になる 読者になる

いろいろ備忘録日記

主に .NET と Python絡みのメモを公開しています。

リモートデスクトップ環境を作ってみる (COM, Microsoft Terminal Services Control, IMsRdpClientAdvancedSettings, IMsRdpClientSecuredSettings, AxMsTscAxNotSafeForScripting)

C#


リモートデスクトップ接続を利用している人は多いと思います。
私は結構利用していて、都合上複数のリモートデスクトップを
開いて作業することも多いです。


で、本題なのですがこのリモートデスクトップ、実はコントロールとして
提供されているのです。結構知らない人多いのではないでしょうか?
(私も少し前に知りました・・・w)


参考にした記事はこちら。


で、利用方法なのですが上記のブログを見ていただくとわかりやすいです。
ですが、一応自分の所でもメモメモ。

  1. 参照設定にて[COM]タブの以下のものを選択。
    1. Microsoft Terminal Services Control Type Library
  2. ツールボックスの一番下にMicrosoft Terminal Servieces Controlが表示されるのでそれをドロップ.


だけです。後は接続情報を設定して繋ぐだけ。


以下、接続するまでのサンプルコードです。
MTSコントロールの名前は rdtMainとなっているとします。

rdtMain.Server = サーバー;
rdtMain.UserName = ユーザ名;
// パスワードのみIMsRdpClientAdvancedSettingsにキャストして設定する.
(rdtMain.AdvancedSettings as IMsRdpClientAdvancedSettings).ClearTextPassword = txtPassword.Text;


パスワードのみキャストしなくてはならないので注意です。


これで無事表示できてバンザイなのですが、このままでは実は以下の操作が行えません。

Windowsキーが反応しない。

つまり、リモートデスクトップコントロールの中でWindows+Eとか押下してもエクスプローラーが
起動してくれません。代わりに自分の環境の方のエクスプローラーが起動します。
これは、Full Screenモードでない場合の挙動です。Full Screen状態にすると動作するはずです。


でも、自分用のリモートデスクトップアプリを作成する上で、Full Screenモードにしてしまうと
わざわざ自前でアプリ作成する意味がないので、なんとかしたいところ。


いろいろ探してみた結果以下のようにするとWindowsキーが押下できるようになります。

            //
            // そのままでは、Windows Keyが反応しないので反応するように設定する.
            //
            // その際の設定は、AdvancedSettingsとSecuredSettingsの両方に設定項目が存在する.
            //
            // ■AdvancedSettings: Windows Keyを有効にするオプションが存在.
            // ■SecuredSettings : キーボードフックモードを変更するオプションが存在.
            //                    (設定値1は、Apply key combinations at the remote server.となっている。)
            //
            // 補足)フルスクリーンモードにするオプションはSecuredSettingsに存在する.
            //        もしくは、IMsRdpClientインターフェースにキャストしても出来る.
            //
            int intTrue = Convert.ToInt32(true);
            (rdtMain.AdvancedSettings as IMsRdpClientAdvancedSettings).EnableWindowsKey = intTrue;
            (rdtMain.SecuredSettings as IMsRdpClientSecuredSettings).KeyboardHookMode = intTrue;

EnableWindowsKeyとKeyboardHookModeをいじります。
これで、Full Screenモードでない場合でもWindowsキーが効くようになります。


接続情報を設定して、Windowsキーを押下可能にし、接続するまでのサンプルは以下のようになります。

            //
            // 設定オブジェクトを取得.
            //
            var advancedSettings = (rdtMain.AdvancedSettings as IMsRdpClientAdvancedSettings);
            var securedSettings = (rdtMain.SecuredSettings as IMsRdpClientSecuredSettings);

            //
            // リモートデスクトップコントロールの初期化及び接続.
            //
            rdtMain.Server = txtServer.Text;
            rdtMain.UserName = txtUserName.Text;
            // パスワードのみIMsRdpClientAdvancedSettingsにキャストして設定する.
            advancedSettings.ClearTextPassword = txtPassword.Text;

            //
            // そのままでは、Windows Keyが反応しないので反応するように設定する.
            //
            // その際の設定は、AdvancedSettingsとSecuredSettingsの両方に設定項目が存在する.
            //
            // ■AdvancedSettings: Windows Keyを有効にするオプションが存在.
            // ■SecuredSettings : キーボードフックモードを変更するオプションが存在.
            //                    (設定値1は、Apply key combinations at the remote server.となっている。)
            //
            // 補足)フルスクリーンモードにするオプションはSecuredSettingsに存在する.
            //        もしくは、IMsRdpClientインターフェースにキャストしても出来る.
            //
            int intTrue = Convert.ToInt32(true);
            advancedSettings.EnableWindowsKey = intTrue;
            securedSettings.KeyboardHookMode = intTrue;

            //
            // 拡張設定を行う。
            //
            // ■フォントスムージングをON.
            // ■Aero Glassを有効にする.
            // ■拡張グラフィックモードを利用??(分かってないです・・・すみません)
            //
            int perfFlags = (ENABLE_FONT_SMOOTHING | ENABLE_DESKTOP_COMPOSITION | ENABLE_ENHANCED_GRAPHICS);
            advancedSettings.PerformanceFlags = perfFlags;

            //
            // リダイレクト系の設定.
            //
            // ■プリンタ
            //
            advancedSettings.RedirectPrinters = true;

            //
            // リモートデスクトップコントロールのイベントをハンドル.
            //
            rdtMain.OnConnecting += rdtMain_OnConnecting;
            rdtMain.OnConnected += rdtMain_OnConnected;
            rdtMain.OnFatalError += rdtMain_OnFatalError;

            rdtMain.Leave += rdtMain_Leave;

            //
            // 接続.
            //
            rdtMain.Connect();


他にもこのコントロールには各種イベントが揃っているのでいろいろ制御しやすいです。
よく利用しそうなイベントは以下の通り。

  • OnConnecting
  • OnConnected
  • OnDisconnected
  • OnFatalError
  • OnLogonError
  • OnLoginComplete


ついでなので、サンプルアプリをアップしました。
とはいっても、私が実務でも使っているものです。w
バグまだまだあると思いますが自分で使ってる分には問題ないので
放置中w
.NET Framework 3.5が必要です。


余談)C# 4.0のdynamicを利用したら上記のようなコーディングが
   大分楽になるので、楽しみです。


追記)だれかフォントスムージングの設定方法を教えて下さい・・・・。m(_ _)m


11月24日 追記)教えてもらいました。m(_ _)m
以下のようにするとフォントスムージングがかかります。

        /// <summary>
        /// フォントスムージング
        /// </summary>
        public const int ENABLE_FONT_SMOOTHING = 0x00000080;
        /// <summary>
        /// Vista系にてAeroを有効にする為に必要.
        /// </summary>
        public const int ENABLE_DESKTOP_COMPOSITION = 0x00000100;
        /// <summary>
        /// 拡張グラフィックモード?(GPU絡みの事みたい)
        /// </summary>
        public const int ENABLE_ENHANCED_GRAPHICS = 0x00000010;

            //
            // 拡張設定を行う。
            //
            // ■フォントスムージングをON.
            // ■Aero Glassを有効にする.
            // ■拡張グラフィックモードを利用??(分かってないです・・・すみません)
            //
            int perfFlags = (ENABLE_FONT_SMOOTHING | ENABLE_DESKTOP_COMPOSITION | ENABLE_ENHANCED_GRAPHICS);
            (rdtMain.AdvancedSettings as IMsRdpClientAdvancedSettings).PerformanceFlags = perfFlags;


さらに追記)プリンタのリダイレクトの設定を追加しました。