无法转换'MS.Internal.Controls.AddInHost'System.Windows.C

本文关键字:AddInHost System Windows Controls MS 转换 Internal | 更新日期: 2023-09-27 18:11:01

我已经将usercontrol实例创建为单独的appdomain,并按照addin框架指南将其转换为inativehandleccontract,并且我能够将框架实例的引用传递到主机应用程序域中。当我将inativehandleccontract转换回主机应用程序appdomain中的UIElement时,我无法将UIElement转换为我的自定义接口类型。

谁能告诉我是否有可能将框架元素转换为userControl或将其转换为我的自定义界面?

下面是部分代码:

public INativeHandleContract GetControl(string AssemblyName, string strFullNamespaceName)
    {
        var assembly = Assembly.LoadFrom(m_strAssemblyDirectory + AssemblyName);
        var type1 = typeof(IUPiAssemblyProcedure);
        var type2 = typeof(IUPiCardProcedure);
        var type3 = typeof(IUPiDatabaseFrame);
        var type4 = typeof(IUPiUserFrame);
        var t = from T in assembly.GetTypes() where type1.IsAssignableFrom(T) || type2.IsAssignableFrom(T) || type3.IsAssignableFrom(T) || type4.IsAssignableFrom(T) select T;
        if (t.Count<Type>() == 0) return null;
        var tName = t.First<Type>().FullName;
        return FrameworkElementAdapters.ViewToContractAdapter((FrameworkElement)assembly.CreateInstance(tName));
    }
public void LoadUserControl(INativeHandleContract contract)
    {
        var uControl = FrameworkElementAdapters.ContractToViewAdapter(contract);
        var t = uControl.GetType();
        t.GetMethod("methodName");
        ...
    }

我的目标是调用自定义接口中定义的一些方法,这些方法由我加载的程序集中的一个类型实现。

的问候Tihomir Blagoev

无法转换'MS.Internal.Controls.AddInHost'System.Windows.C

我找到解决方案了!正如这里所描述的,"因为主机应用程序获得一个HwndHost,所以主机应用程序不能将ContractToViewAdapter返回的对象转换为插件实现的类型(例如,UserControl)。"

如果我想访问子域的类型实例,我必须通过代理:

public class Main
{
    private AppDomain ad = null;
    private proxy remoteWorker = null;
    public INativeHandleContract LoadAssembly(string assemblyname, string fullInterfaceName)
    {
        if (ad != null)
        {
            AppDomain.Unload(ad);
        }
        var domSetup = new AppDomainSetup();
        domSetup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
        domSetup.PrivateBinPath = AppDomain.CurrentDomain.BaseDirectory;
        domSetup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
        domSetup.LoaderOptimization = LoaderOptimization.MultiDomainHost;
        var adevidence = AppDomain.CurrentDomain.Evidence;
        ad = AppDomain.CreateDomain(assemblyname, adevidence, domSetup);
        ad.AssemblyResolve += ad_AssemblyResolve;
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
        remoteWorker = (proxy)ad.CreateInstanceAndUnwrap(typeof(proxy).Assembly.FullName, "INATO.UPINAIS.UCLibrary.proxy");
        return remoteWorker.GetControl(assemblyname, fullInterfaceName);
    }
    public void DoTheTrick()
    {
        var uControl = LoadAssembly("assemblyName", "interfaceName");
        panel.Content = FrameworkElementAdapters.ContractToViewAdapter(uControl);
        remoteWorker.RemoteInvoke("methodName", new object[] { });
    }
}
public class proxy : MarshalByRefObject
{
    private object _currentInstance;
    public INativeHandleContract GetControl(string AssemblyName, string strFullNamespaceName)
    {
        var assembly = Assembly.LoadFrom(m_strAssemblyDirectory + AssemblyName);
        var type1 = typeof(IUPiAssemblyProcedure);
        var type2 = typeof(IUPiCardProcedure);
        var type3 = typeof(IUPiDatabaseFrame);
        var type4 = typeof(IUPiUserFrame);
        var t = from T in assembly.GetTypes() where type1.IsAssignableFrom(T) || type2.IsAssignableFrom(T) || type3.IsAssignableFrom(T) || type4.IsAssignableFrom(T) select T;
        if (t.Count<Type>() == 0) return null;
        var tName = t.First<Type>().FullName;
        _currentInstance = assembly.CreateInstance(tName);
        return FrameworkElementAdapters.ViewToContractAdapter((FrameworkElement)_currentInstance);
    }
    public void RemoteInvoke(string methodName, object[] parameters)
    {
        var type = _currentInstance.GetType();
        var mi = type.GetMethod(methodName);
        mi.Invoke(_currentInstance, parameters);
    }
}