Q:

Remote Desktop ActiveX control

I've got a C# application that I've been using for years to script remote desktop connections.  It's always been built on the AxMsRdpClient3 (note the 3, which I guess is some kind of version number).  There are features in AxMsRdpClient8 (version 8) that I want to be able to use, but as I understand it, this requires Remote Desktop version 8 to be installed.  Not all users have that installed (or even can install it on Windows XP/Vista), though.
So as Sheng Jiang suggested, I am creating the control at runtime now and I have code that looks like this:
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();
}

As expected, rdp8.EndInit() throws an exception on machines that do not have Remote Desktop version 8 installed.  The problem is that after we try to create the AxMSRDPClient8, the rdp3.EndInit() fails as well (class not registered) on older machines.  If I don't attempt to create the AxMSRDPClient8 first, the AxMSRDPClient3 initializes and works correctly.

A:

each version of RDP activeX has a different clsid. You need to detect the OS version and create an activex at runtime with the class id corresponding to the lowest OS version you plan to support. 
If your code depends on late binding, better rewrite your code to work with IMsRdpClient* and IMsRdpClientNonScriptable*. For example MsRdpClient8NotSafeForScripting supports the following interfaces: 

up to version 8 of IMsRdpClient*  
up to version 5 of IMsRdpClientNonScriptable
IMsTscNonScriptable   
IMsRdpPreferredRedirectionInfo
IMsRdpExtendedSettings

MsRdpClient3NotSafeForScripting supports

version 2 of IMsRdpClient* 
IMsRdpClientNonScriptable 
IMsTscNonScriptable.

if you want to detect whether your activex support a particular interface version, just cast the ActiveX's instance 
to the interface. when a cast fails you know the interface is not supported.
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);
    }
}

