使用COM互操作解决反射中的.NET程序集不匹配问题

时间:2017-12-11 17:59:59

标签: .net com interop system.reflection

我试图在.Net 2.0可执行文件中使用.Net 4.6库。

我使用了this COM approach,它一直有效,直到程序集System.Collections.Immutable被解析。

我收到带有消息&#34的ReflectionTypeLoadException;无法加载文件或程序集System.Collections.Immutable,Version = 1.2.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a'或其中一个依赖项。定位的程序集的清单定义与程序集引用不匹配。 (HRESULT异常:0x80131040)"

.Net 4.6库使用Roslyn和Roslyn程序集引用System.Collections.Immutable,Version = 1.2.1.0。并且在项目中引用了此版本的程序集。但Roslyn程序集(Microsoft.CodeAnalysis.CSharp,版本2.6.0.0)引用System.Reflection.Metadata,Version = 1.4.1.0和元数据程序集引用System.Collections.Immutable,Version = 1.2.0.0

当我在.Net 4.6可执行文件而不是.Net 2.0中使用.Net 4.6库时,一切正常,没有例外。

我尝试设置"特定版本"不可变组件为false,不工作。 还尝试分离.Net 2.0和.Net 4.6文件夹,不工作。 此外,.Net 4.6库dll和Immutable dll位于同一文件夹中。

.Net 2.0可执行文件的app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="Adapter" />
    </assemblyBinding>
  </runtime>
</configuration>

.Net 4.6库的app.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.2.1.0" newVersion="1.2.1.0" />
      </dependentAssembly>
      ......other dependent assemblies....
    </assemblyBinding>
  </runtime>
</configuration>

.Net 2.0可执行代码

static void Main()
{
    Console.WriteLine("CLR version from EXE: {0}", Environment.Version);
    Console.WriteLine("Is64BitProcess: {0}", (IntPtr.Size == 8));

    Type myClassAdapterType = Type.GetTypeFromProgID("Net4ToNet2Adapter.MyClassAdapter");
    object myClassAdapterInstance = Activator.CreateInstance(myClassAdapterType);
    IEnchanterAdapter myClassAdapter = (IEnchanterAdapter)myClassAdapterInstance;
    myClassAdapter.DoNet4Action();
}

.Net 4.6库代码

[ComVisible(true)]
[Guid("E36BBF07-591E-4959-97AE-D439CBA392FB")]
public interface IMyClassAdapter
{
    void DoNet4Action();
}

[ComVisible(true)]
[Guid("A6574755-925A-4E41-A01B-B6A0EEF72DF0")]
public class MyClassAdapter : IMyClassAdapter
{
    private MyClass _myClass = new MyClass();

    public MyClassAdapter()
    {
        Console.WriteLine("adapter constructor");
    }

    public void DoNet4Action()
    {
        Console.WriteLine("CLR version from EXE: {0}", Environment.Version);
        Console.WriteLine("Is64BitProcess: {0}", Environment.Is64BitProcess);

        _myClass.DoNet4Action();
    }
}

class MyClass
{
    public void DoNet4Action()
    {
        var workspace = new AdhocWorkspace(); // throws exception here
    }
}

输出

CLR version from EXE: 2.0.50727.8794
Is64BitProcess: True
adapter constructor
CLR version from EXE: 4.0.30319.42000
Is64BitProcess: True

Fusion程序集绑定日志(当项目引用版本1.2.2.0时)(这再次适用于.Net 4.6可执行文件)

        FusionLog   "=== Pre-bind state information ===
LOG: DisplayName = System.Collections.Immutable, Version=1.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\n (Fully-specified)
LOG: Appbase = file:///D:/Develop/Enchanter/UnityWorkspace/bin/Debug/
LOG: Initial PrivatePath = NULL
Calling assembly : Microsoft.CodeAnalysis, Version=2.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: D:\\Develop\\Enchanter\\UnityWorkspace\\bin\\Debug\\UnityWorkspace.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\config\\machine.config.
LOG: Post-policy reference: System.Collections.Immutable, Version=1.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
LOG: Attempting download of new URL file:///D:/Develop/Enchanter/UnityWorkspace/bin/Debug/System.Collections.Immutable.DLL.
LOG: Attempting download of new URL file:///D:/Develop/Enchanter/UnityWorkspace/bin/Debug/System.Collections.Immutable/System.Collections.Immutable.DLL.
LOG: Attempting download of new URL file:///D:/Develop/Enchanter/UnityWorkspace/bin/Debug/Adapter/System.Collections.Immutable.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Build Number
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
"   string

1 个答案:

答案 0 :(得分:0)

应将程序集绑定重定向添加到.Net 2.0可执行文件手动,因为Visual Studio不会自动执行此操作,因为它们之间没有关系COM互操作。

.Net 2.0可执行文件的新app.config是:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="Adapter" />
      <dependentAssembly>
        <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.2.2.0" newVersion="1.2.2.0" />
      </dependentAssembly>
       ......other dependent assemblies....
    </assemblyBinding>
  </runtime>
</configuration>