我希望有人可以解释我所看到的这种行为。我的问题有 3 个主要部分:
- 明智的设置
- 托管 C++ 程序集
- AC#组装
托管 C++ 程序集定义了一个接口,我们称之为ISetupHelper
. C# 程序集中有一个实现此接口的类(C# 程序集具有对托管 C++ 程序集的引用)。让我们称之为这个类SetupHelper
。
由于 Wise 设置无法调用 C# 程序集的目录,因此我们在两者之间有这个托管的 C++ 程序集。安装程序调用一个方法来创建实现的类的接口ISetupHelper
。我通过将 2 个字符串传递给 C++ 方法、程序集路径(到 C# 程序集)和类型名称来做到这一点。
C++ 方法如下所示:
Assembly^ assembly = Assembly::LoadFrom(assemblyName);
Object^ provider = assembly->CreateInstance(typeName);
WiseServices::SetupHelper = safe_cast<ISetupHelper^>(provider);
多年来,这对我们来说非常有效。现在我们正在尝试添加对 Windows Server 2012/R2 的支持。这些版本的 Windows 分别安装了 4.5 和 4.5.1。
这是发生奇怪问题的地方。如果安装程序是从具有长名称的路径运行的,那么如果您从路径的短版本运行它,它将不起作用。当我说它不起作用时,我的意思是演员阵容失败了。例如:
- 从该目录运行有效:
c:\reallylongname
- 这不起作用:
c:\really~1
我打开了 Fusion 记录器,当转换失败时,它会尝试再次加载 C++ 程序集:
- LOG:IJW 显式绑定。文件路径:C:\reallylongname\ManagedCPP.dll。
- 日志:IJW 程序集绑定返回了不同的路径:C:\REALLY~1\ManagedCPP.dll。使用提供的文件。
如果您在仅安装 .NET 4.0 的 Windows Server 2008 R2 机器上执行完全相同的操作,则从短路径运行就可以正常工作(转换成功)。
似乎 CLR 中的某些内容在加载程序集的方式上发生了变化,特别是在加载与已加载程序集同名的程序集时。