如何识别“参考程序集”?

Tur*_*rbo 5 .net c# dll .net-assembly

许多 .NET 程序集附带一个仅参考版本,该版本去除了实际代码,只有元数据。

例如,我可以在我的机器上的多个位置找到 System.Core.dll,其中两个是:

  • C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System.Core.dll 大小:276 KB
  • C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll 大小:1291 KB

第一个只有元数据,在默认加载上下文中加载它会引发 BadImageFormat 异常。

System.BadImageFormatException:无法加载文件或程序集“System.Core,版本=4.0.0.0,文化=中性,PublicKeyToken=b77a5c561934e089”或其依赖项之一。不应为执行加载引用程序集。它们只能在仅反射加载器上下文中加载

给定程序集的路径,是否可以确定它是否是“参考程序集”?

我可以检查关键字“参考程序集”的路径,但是如果程序集被复制到不同的位置,这很麻烦,并且不起作用。如果有帮助,我可以自由地首先在仅反射上下文中加载程序集。

And*_*kin 5

我在 CoreCLR 中找到了这段代码dotnet/coreclr/.../pefile.inl,它通过我认为的内容标识了一个参考程序集System.Runtime.CompilerServices.ReferenceAssemblyAttribute

if (mdImport->GetCustomAttributeByName(TokenFromRid(1, mdtAssembly),
                                       g_ReferenceAssemblyAttribute,
                                       NULL,
                                       NULL) == S_OK) {
    ThrowHR(COR_E_LOADING_REFERENCE_ASSEMBLY, BFA_REFERENCE_ASSEMBLY);
}
Run Code Online (Sandbox Code Playgroud)

我认为完整的 CLR 也会做同样的事情。

我还没有尝试过,但您可能可以将程序集加载到仅反射上下文中,然后检查它是否具有ReferenceAssemblyAttribute.