2014-02-26 231 views
0

我有一個C#應用程序,我已經使用多年來腳本遠程桌面連接。它總是建立在AxMsRdpClient3上(注意3,我猜是某種版本號)。我希望能夠使用AxMsRdpClient8(版本8)中的功能,但據我瞭解,這需要安裝遠程桌面版本8。但並非所有用戶都已安裝(甚至可以在Windows XP/Vista上安裝它)。遠程桌面ActiveX控件

因此,作爲盛強建議,我現在在運行時創建的控制和我有一些代碼,看起來像這樣:

try 
{ 
    AxMsRdpClient8 rdp8 = new AxMsRdpClient8(); 
    rdp8.BeginInit(); 
    // set some properties here 
    rdp8.EndInit(); // throws Exception on machines without version 8 installed 
} 
catch (Exception ex) 
{ 
    AxMsRdpClient3 rdp3 = new AxMsRdpClient3(); 
    rdp3.BeginInit(); 
    // set some properties here 
    rdp3.EndInit(); 
} 

正如預期的那樣,rdp8.EndInit()拋出一個異常,在不機器安裝了遠程桌面版本8。問題是,在我們嘗試創建AxMSRDPClient8之後,rdp3.EndInit()在舊機器上也會失敗(類未註冊)。如果我不試圖先創建AxMSRDPClient8,則AxMSRDPClient3將初始化並正常工作。

+0

添加os檢測代碼以避免嘗試擺在首位。 –

+0

我可以檢測操作系統,但操作系統並沒有真正告訴你使用哪個AxMsRdpClient版本。例如,遠程桌面8可供Windows 7下載,但默認情況下不會安裝。另外,如果我檢測到操作系統,我的代碼將無法在下一版本的Windows上運行,其中類似上面的內容會繼續工作。上述概念對於activeX控件無效嗎?爲什麼一個有效的ActiveX控件會因爲之前有一個無效控件而失敗? – Jason

+0

每個CLSID都與更高版本的系統兼容。例如,Windows Vista上可編寫腳本控件的CLSID可用於更高版本的系統,如Windows 7. –

回答

2

each version of RDP activeX has a different clsid。您需要檢測操作系統版本並創建an activex at runtime with the class id corresponding to the lowest OS version you plan to support

如果您的代碼依賴於後期綁定,請更好地重寫您的代碼以使用IMsRdpClient *和IMsRdpClientNonScriptable *。例如MsRdpClient8NotSafeForScripting支持以下接口:

  • 高達IMsRdpClient *
  • 版本8高達IMsRdpClientNonScriptable的版本5
  • IMsTscNonScriptable
  • IMsRdpPreferredRedirectionInfo
  • IMsRdpExtendedSettings

MsRdpClient3NotSafeForScripting支撐

  • 版本IMsRdpClient *
  • IMsRdpClientNonScriptable
  • IMsTscNonScriptable 2。

如果要檢測您的activex是否支持特定的接口版本,只需將該ActiveX的實例 轉換爲接口即可。當一個強制轉換失敗時,您知道該接口不受支持。

protected void CreateRdpActiveX() 
{ 
    try 
    { 
     string clsid=GetRdpActiveXClsIdByOSVersion(); 
     Type type = Type.GetTypeFromCLSID(clsid, true); 
     this.axRdp = new AxHost (type.GUID.ToString()); 
     ((ISupportInitialize)(axRdp)).BeginInit(); 
     SuspendLayout(); 
     this.panel1.Controls.Add(axRdp);  
     ((ISupportInitialize)(axRdp)).EndInit(); 
     ResumeLayout(false); 
     var msRdpClient8 = axRdp.GetOcx() as IMsRdpClient8; 
     if(msRdpClient8!=null) 
     { 
      var advancedSettings9 =msRdpClient8.AdvancedSettings9 as IMsRdpClientAdvancedSettings8; 
      if(advancedSettings9!=null) 
       advancedSettings9.BandwidthDetection=true; 

     } 
    } 
    catch (System.Exception ex) 
    { 
     System.Console.WriteLine(ex.Message); 
    } 
} 
+0

您能否提供接口版本檢測的示例? –

+0

我終於嘗試了這個建議。第一個問題是Type.GetTypeFromCLSID採用GUID,而不是String。我假設我只是傳遞一個新的GUID(clsid)而不是clsid。我無法解決的問題是AxHost是一個抽象類,不能在第7行創建。你知道解決方法嗎? – Jason

+0

我做了一個AxHost的具體子類,似乎讓我過去不能創建AxHost,現在我可以編譯我的類並通過它運行而不會出錯。我的新問題是我在AxMsRdpClient對象上有一些事件處理程序。我如何將這些事件處理程序(OnConnected等)附加到對象,現在它是AxHost而不是AxMsRdpClient對象? – Jason