rdp(remote desktop protocol)是一個多通道的協議,包括客戶端視音傳輸、文件傳輸和通訊端口轉向等等功能,通過壓縮處理的數據網絡傳輸也是相當快。我們在windows操作系統下面,經常用到的mstsc.exe,也提供了com組件調用的接口。
可以建立一個winform的project,通過【工具箱】->【Choose Items】將com控件添加進來。
↑ 可以看到選項卡下面列了多個版本的組件,這里要提醒一下,它們是有版本功能的區別的,他們的clsid都是不一樣的,而且代表著不同操作系統版本。這里的向下兼容是對操作系統版本而言,換句話說高一級的版本com控件不一定能在低一級操作系統環境正常運行。
下面從工具箱拖拉過程對于winform應該沒有啥異議的地方,我們來看一下wpf如何添加組件,同上的操作,工具箱中com控件的狀態是不可用的,通過project的【add reference】列,找到了一項。
↑ terminal service,有種眼熟的感覺,linux下面常用的就是terminal終端,加進來發現少了一個AxInterop.MSTSCLib.dll。解決辦法很簡單,在wpf project里面加一個winform窗口,讓后從工具箱把控件拉過去,project就自動加上這兩個接口操作文件。
下面在代碼里里敲入一句xaml。
1 <WindowsFormsHost Visibility="{Binding HostVisible}" x:Name="host" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
我們再加一個cs,來繼承一下這個activex控件。WndProc句柄操作在對象初始化的時候會調用到,以及在rdp的connect等過程也會執行到,看注釋是為了解決鼠標焦點異常的問題。
1 public class MyRDP : AxMSTSCLib.AxMsRdpClient2NotSafeForScripting 2 { 3 public MyRDP() 4 : base() 5 { 6 } 7 8 protected override void WndProc(ref System.Windows.Forms.Message m) 9 { 10 // Fix for the missing focus issue on the rdp client component 11 if (m.Msg == 0x0021) // WM_MOUSEACTIVATE 12 { 13 if (!this.ContainsFocus) 14 { 15 this.Focus(); 16 } 17 } 18 19 base.WndProc(ref m); 20 } 21 }
好,在viewmodel里面看一下初始化。看了下這個rdp實現了ISupportInitialize接口,目的是為了初始化相關依賴屬性,初始化順序在BeginInit和EndInit之間完成,只要實現了這個接口,設計器自動幫你完成,在做winform的東西,不知道大家注意到form窗體下面的designer.cs。
private void InitData() { this.rdp = new MyRDP(); ((System.ComponentModel.ISupportInitialize)(rdp)).BeginInit(); this.rdp.Name = "rdp"; this.rdp.Enabled = true; this.rdp.Dock = System.Windows.Forms.DockStyle.None; this.rdp.Location = new System.Drawing.Point(0, 0); this.rdp.OnConnecting += new EventHandler(this.RDPClient_OnConnecting); this.rdp.OnConnected += new EventHandler(this.RDPClient_OnConnected); this.rdp.OnDisconnected += new AxMSTSCLib.IMsTscAxEvents_OnDisconnectedEventHandler(this.RDPClient_OnDisconnected); host.Child = this.rdp; ((System.ComponentModel.ISupportInitialize)(rdp)).EndInit(); this.BtnContent = "connect"; this.MaskVisible = System.Windows.Visibility.Visible; this.HostVisible = System.Windows.Visibility.Collapsed; }
下面看一下connect的部分。
1 private void Connect() 2 { 3 this.rdp.Server = this.Address; 4 this.rdp.UserName = this.Name; 5 this.rdp.AdvancedSettings2.RDPPort = 3389; 6 this.rdp.AdvancedSettings2.SmartSizing = true; 7 8 this.rdp.Width = Convert.ToInt32(System.Windows.SystemParameters.PrimaryScreenWidth); 9 this.rdp.Height = Convert.ToInt32(System.Windows.SystemParameters.PrimaryScreenHeight); 10 this.rdp.DesktopWidth = Convert.ToInt32(System.Windows.SystemParameters.PrimaryScreenWidth); 11 this.rdp.DesktopHeight = Convert.ToInt32(System.Windows.SystemParameters.PrimaryScreenHeight); 12 this.rdp.FullScreenTitle = "this is test"; 13 MSTSCLib.IMsTscNonScriptable secured = (MSTSCLib.IMsTscNonScriptable)rdp.GetOcx(); 14 secured.ClearTextPassword = this.Password; 15 16 try 17 { 18 this.rdp.Connect(); 19 } 20 catch 21 { 22 } 23 }
ok,咱們看一下大概的效果。
full screen的代碼很easy。
1 private void ToggleFullScreen() 2 { 3 this.rdp.FullScreen = !this.rdp.FullScreen; 4 }
好了上面rdp組件大概使用過程,另外這里有個叫WindowsFormsHost的控件值得說一下,xaml里面它的作用是承載winform控件,因為它是獨立的hdwnd,所以它是凌駕于xaml控件之上的,比如用scrollviewer根本包不住它,stackoverflow也有人做了相關的擴展。最新4.5 beta framework里面好像對這個空間做了相關擴展,官方文檔也有介紹,具體還沒有正式發布出來。
文章列表