确定程序集是否属于.NET框架

20
如何从程序集名称、程序集类(或其他类似内容)中判断一个程序集是否是.NET框架的一部分(即System.windows.Forms)?
到目前为止,我已经考虑了PublicKeyToken和CodeBase属性,但这些属性并不总是针对整个框架相同。
我想要这些信息的原因是获取我的EXE文件正在使用的需要在客户端机器上的程序集列表,以便我可以将正确的文件打包到安装文件中,而不使用Visual Studio安装系统。问题是,我不想选择任何.NET框架的程序集,并且我希望它是一个自动化的过程,易于在每次主要更新完成后推出。
最终的解决方案是有一个IsFramework属性…… :)

这需要多自动化?很容易分辨出哪些是来自微软的。 - RQDQ
7个回答

11

不,它不是以“System”开头的。您可以检查“WindowsBase”,这是一个框架程序集。

您也不能检查PublicKeyToken,因为还有其他使用“默认”密钥签名的Microsoft程序集,但它们不是.NET Framework(Visual Studio程序集)的一部分。

最好的方法是获取已安装的.NET框架集合,并检查目标程序集是否是它们的RedistList(RedistList\FrameworkList.xml)的一部分。

FrameworkList.xml可以在以下位置找到:

  • .NET 2.0:C:\Windows\Microsoft.NET\Framework64\v2.0.50727\RedistList
  • .NET 3.x:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\vVersionNumber\RedistList
  • .NET 4.x:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\vVersionNumber\RedistList
  • .NET Core:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETCore\vVersionNumber\RedistList

需要的不仅仅是+1。这才是真正权威的答案。 - Joe White

5
为了实现这一点,我使用嵌入在程序集中的产品名称,通过AssemblyProductAttribute实现。
var attribute = assembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false)[0] as AssemblyProductAttribute;
var isFrameworkAssembly = (attribute.Product == "Microsoft® .NET Framework");

我正在使用这种技术,在应用程序的“关于”屏幕下按产品对组件进行分组,对我来说似乎非常有效。


4

我曾经遇到过完全相同的问题。不幸的是,到目前为止给出的所有答案都不足以安全地确定一个程序集是否属于.NET Framework。

微软将名为FXAssembly的类放入每个框架程序集的全局命名空间中,并使用常量字符串指示版本:

.class private abstract auto ansi sealed beforefieldinit FXAssembly
    extends [mscorlib]System.Object
{
    .field assembly static literal string Version = string('2.0.0.0')

}

使用此“标记”来检查程序集是否为框架程序集。同时检查公钥也不会有害。


1
不幸的是,这并不适用于所有框架程序集 :( 例如:System.Data版本2.0.0.0没有该类,即使它是.net Framework 2.0的一部分。检查公钥令牌b77a5c561934e089似乎仍然是最有希望的。 - Michael Stum
1
除了 b77a5c561934e089 之外,还有至少3个:31bf3856ad364e35(例如 PresentationCore.dll),b03f5f7f11d50a3a(例如 System.Drawing.dll)和 89845dcd8080cc91(例如 System.Data.SqlServerCe.dll)。 - VitalyB

3

我认为最可靠且最通用的方法将是使用PublicKeyToken。是的,有不止一个,但它们将是一个有限的列表,并且不会经常更改。

同样地,您也可以有一个程序集名称白名单 - 这个列表也将在框架版本之间是有限的且静态的。


我想知道是否可以查询一些微软服务的公钥令牌,就像他们提供远程符号服务器的方式一样。这样你就不必手动跟踪它了。 - Anthony Mastrean

2
当您安装Visual Studio时,会在各种子文件夹中获得参考程序集,格式为C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\{FrameworkName}\{FrameworkVersion}。最有趣的可能是RedistList\FrameworkList.xml文件,其中包含给定框架版本附带的所有程序集名称列表。
例如:C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\RedistList\FrameworkList.xml似乎包含了所有.NET 4.0的框架程序集。
您可以轻松使用这些文件来建立程序集的静态白名单。

1

如果您知道您的DLL都不会在全局程序集缓存(GAC)中,那么您可以检查每个程序集是否在GAC中。如果是,则不要复制它。如果不是,则需要复制。Assembly类上有一个名为GlobalAssemblyCache的属性。这在某些情况下比其他情况更有效。


1
你可以使用反射来查看程序集的发布者,并将其与程序集的路径协调。如果您找到一个发布者为Microsoft的程序集,并且存在于C:\Windows\Microsoft.NET\Framework下面的某个位置,那么它很可能是运行时的一部分。
想了想,发布者甚至可能不是必需的。该路径下的任何内容都应该是运行时的一部分(除了一个调皮的应用程序在胡闹的情况下)。

问题在于很多东西根据AssemblyName和Assembly存储在GAC中。 - Dave Arkell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接