使用C#封裝RdpClinet

一:描述

本文描述了使用C#來製作一個ActiveX控件,暴露相應的屬性、方法、事件等。

此例中主要是對RdpClient控件的二次封裝,可以通過在IE中打開TestRDP.html進行測試:

實現效果圖如下:

 

二:具體實現

基本的實現可以參考文章:

http://blog.csdn.net/veryhappy/article/details/1604406

 

其他具體的就不多描述了,看代碼吧。

完整代碼請於如下鏈接下載:

http://download.csdn.net/detail/tragicguy/5447715


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using MSTSCLib;

namespace PemRDPControl
{

    [Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IObjectSafety
    {
        // methods 
        void GetInterfacceSafyOptions(
            System.Int32 riid,
            out System.Int32 pdwSupportedOptions,
            out System.Int32 pdwEnabledOptions);
        void SetInterfaceSafetyOptions(
            System.Int32 riid,
            System.Int32 dwOptionsSetMask,
            System.Int32 dwEnabledOptions);
    }

    //the function for ie to call 
    [ComVisible(true)]
    [Guid("89970EFC-0014-4A1C-BA19-A18332E7A0BB")]
  [InterfaceType(ComInterfaceType.InterfaceIsDual)]  
    public interface IPemRDPControl
  {
      [DispId(1)]
      void SetControlSize(int width, int height);
      [DispId(2)]
      void Connect();
      string Server
      {
          get;
          set;
      }

      string UserName
      {
          get;
          set;
      }
      string PassWord
      {
          get;
          set;
      }
      string Domain
      {
          get;
          set;
      }
      int RDPPort
      {
          get;
          set;
      }
      bool ConnectToServerConsole
      {
          get;
          set;
      }
      bool ConnectToAdministerServer
      {
          get;
          set;
      }
      int DesktopWidth
      {
          get;
          set;
      }
      int DesktopHeight
      {
          get;
          set;
      }
      int Width
      {
          get;
          set;
      }
      int Height
      {
          get;
          set;
      }
      bool FullScreen
      {
          get;
          set;
      }
      ExtendedDisconnectReasonCode ExtendedDisconnectReason
      {
          get;
      }

    }

    //the events
    [ComVisible(true)]
    [Guid("60FB4E65-C928-4D2F-B52E-2993165D314D")]
  [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IPemRDPControlEvents
  {
      [DispId(21)]
      void OnConnected();
      [DispId(22)]
      void OnConnecting();
      [DispId(23)]
        void OnDisconnected(int reasoncode);
  }   



    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(IPemRDPControl))]
    [ComSourceInterfaces(typeof(IPemRDPControlEvents))]
    [ComVisible(true)]
    [Guid("845FC80C-753A-4095-96D4-9BA2F6DE8E23")]
    public partial class UserControl1 : UserControl, IObjectSafety, IPemRDPControl
    {
        public delegate void OnConnectedHandler();
        public delegate void OnConnectingHandler();
        public delegate void OnDisconnectedHandler(int reasoncode);
        public event OnConnectedHandler OnConnected;
        public event OnDisconnectedHandler OnDisconnected;
        public event OnConnectingHandler OnConnecting;

        #region Property
        public string Server
        {
            get;
            set;
        }
        public string UserName
        {
            get;
            set;
        }
        public string PassWord
        {
            get;
            set;
        }
        public string Domain
        {
            get;
            set;
        }
        public int RDPPort
        {
            get;
            set;
        }
        public  bool ConnectToServerConsole
        {
            get;
            set;
        }
        public bool ConnectToAdministerServer
        {
            get;
            set;
        }
        public int DesktopWidth
        {
            get;
            set;
        }
        public int DesktopHeight
        {
            get;
            set;
        }
        public int Width
        {
            get;
            set;
        }
        public int Height
        {
            get;
            set;
        }
        public bool FullScreen
        {
            get;
            set;
        }
        #endregion
        public UserControl1()
        {
            InitializeComponent();
            Server = "";
            UserName = "";
            PassWord = "";
            ConnectToServerConsole = true;
            ConnectToAdministerServer = true;
            RDPPort = 3389;
            Domain = "";
            Width = Height = 0;
            DesktopWidth = DesktopHeight = 0;
            FullScreen = false;

        }
        public ExtendedDisconnectReasonCode ExtendedDisconnectReason
        {
            get { return (ExtendedDisconnectReasonCode)0; }
        }
        
        public void Connect()
        {
            ((Control)this).Width = Width;
            ((Control)this).Height = Height;
            axMstscObj.Width = Width;
            axMstscObj.Height = Height;
            axMstscObj.DesktopWidth = DesktopWidth;
            axMstscObj.DesktopHeight = DesktopHeight;
           // axMstscObj.ful.FullScreen = FullScreen;
            axMstscObj.Domain = Domain;
            axMstscObj.Server = Server;
            axMstscObj.UserName = UserName;
            IMsRdpClientAdvancedSettings7 iClientSetting = (IMsRdpClientAdvancedSettings7)axMstscObj.AdvancedSettings;
            iClientSetting.RedirectDrives = false;
            iClientSetting.RedirectPrinters = true;
            iClientSetting.RedirectPorts = false;
            iClientSetting.RedirectSmartCards = true;
            iClientSetting.RDPPort = RDPPort;
            iClientSetting.ClearTextPassword = PassWord;
            iClientSetting.ConnectToServerConsole = ConnectToServerConsole;
            iClientSetting.ConnectToAdministerServer = ConnectToAdministerServer;
            axMstscObj.Connect();
        }
        private void axMstscObj_OnConnected(object sender, EventArgs e)
        {
            //fire event to ie
            OnConnected();
        }

        private void axMstscObj_OnDisconnected(object sender, AxMSTSCLib.IMsTscAxEvents_OnDisconnectedEvent e)
        {
            //fire event to ie
            OnDisconnected(e.discReason);            
        }

        private void axMstscObj_OnConnecting(object sender, EventArgs e)
        {
            //fire event to ie
            OnConnecting();
        }

        private void axMstscObj_OnLogonError(object sender, AxMSTSCLib.IMsTscAxEvents_OnLogonErrorEvent e)
        {

        }
        #region IPemRDPControl 成員
        public void SetControlSize(int width, int height)
        {
            axMstscObj.Width = width;
            axMstscObj.Height = height;
        }
        #endregion
        #region IObjectSafety 成員
        public void GetInterfacceSafyOptions(Int32 riid, out Int32 pdwSupportedOptions, out Int32 pdwEnabledOptions)
        {
            pdwSupportedOptions = 1;
            pdwEnabledOptions = 2;
        }

        public void SetInterfaceSafetyOptions(Int32 riid, Int32 dwOptionsSetMask, Int32 dwEnabledOptions)
        {
        }
        #endregion 

        private void axMstscObj_OnAuthenticationWarningDismissed(object sender, EventArgs e)
        {
        }

        private void axMstscObj_OnAuthenticationWarningDisplayed(object sender, EventArgs e)
        {
        }

    }
}

網頁調用代碼如下【運行前請先註冊控件】:

<html>
 <head>
  <title>Demo test</title>
   <script language="javascript">
       function TestConnect() {
           try {
               var obj = document.getElementById("MyActive");
               obj.Server = "testserver";
               obj.RDPPort = 3389;
               obj.UserName = "root";

               obj.PassWord = "testpwd";
               obj.ConnectToServerConsole = true;
               obj.ConnectToAdministerServer = true;
               var screenHeight = 1920;
               var screenWidth = 1080;
               obj.Width = screenHeight;
               obj.Height = screenWidth;
               obj.DesktopWidth = screenHeight;
               obj.DesktopHeight = screenWidth;
               obj.Connect();
           }
           catch (e) {
               alert(e.Message);
           }
   }
   </script> 
 </head>
 <body style=" margin-left:0; margin-right: 0; margin-top:0;margin-bottom:0" >
<script for="MyActive" event="OnConnected" language="javascript">
 //alert("OnConnected");
</script>
<script for="MyActive" event="OnConnecting" language="javascript">
 //alert("OnConnecting");
</script>
<script for="MyActive" event="OnDisConnected(reasoncode)" language="javascript">
 alert("OnDisConnected:" + reasoncode);
 //alert(document.getElementById("MyActive").ExtendedDisconnectReason);
</script>
 <!--
<a href='javascript::' οnclick='TestConnect();'>connect</a> <br />
<a href='javascript::' οnclick='document.getElementById("MyActive").SetControlSize(300, 200);'>Set size</a><br />
<a href='javascript::' οnclick='alert(document.getElementById("MyActive").ExtendedDisconnectReason);'>show externalerrorcode</a><br />
 -->
  <object id="MyActive" name="MyActive" classid="clsid:845FC80C-753A-4095-96D4-9BA2F6DE8E23"  VIEWASTEXT ></object>
    <script language="javascript">
        function OpenActiveX()
        {
            try {
	            var obj = document.getElementById("MyActive");
	            if (obj != null) {
	               // obj.mWidth = 1030;
	                // obj.mHeight = 780;
	                TestConnect();
	            }
	            else
	                alert("Load failed.");
	        }
	        catch(Err)
	        {
		        alert(Err.description);
	        }
		}
		OpenActiveX();
    </script>
 </body>
</html>


三:後續建議

請關注上圖中的 “RDPClient安全警告框.jpg”,在我封裝的過程中,使用WINFORM封裝控件,在部分機器上正常,而在WIN8等機器上則會出現:


同樣,我封裝的控件,在IE中也是加載不上來的,可以通過在JS中監控一個事件來驗證:

OnAuthenticationWarningDisplayed, 此事件在警告框彈出前會觸發。

 

後來對比了兩種代碼,發現正常的使用的是類AxMSTSCLib.AxMsTscAxNotSafeForScripting,而我不正常的使用的是AxMSTSCLib.AxMsRdpClient5,這導致了不同的行爲。

【這一塊沒有深究,希望哪位熟悉的給解釋一下兩者的不同】

 

通過“RDPClient安全警告框.jpg”中的提示,搜索到國外較多的資料,裏面有不少方法來設置解決,我這邊試過一些,暫未發現有效的。

另外有一鏈接中提到使用不同的方式來加載控件,即可避開此錯誤。

 

其他參考鏈接:

以下是我查看過的幾個鏈接:

http://blogs.msdn.com/b/rds/archive/2012/10/23/rdp-8-0-update-for-windows-7-sp1-released-to-web.aspx?PageIndex=2

 

http://social.technet.microsoft.com/Forums/en-US/w8itprosecurity/thread/1fd2f8d2-ef44-45a8-8561-7c805dfe9bb6

此文件中提到:

Problem solved for me - I used a different id for the control(MsTscAx.MsTscAx instead of MSRDP.MSRDP)

這個與我在處理控件封裝中解決提示問題的方法一致,如果能應用到加載RDPClient控件的JS腳本中,相信問題也就解決了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章