关于程序集






4.18/5 (8投票s)
一篇描述程序集的文章
目录
引言
本文档讨论了如何在项目或 GAC(全局程序集缓存)中管理 .NET 程序集。所有由这些程序集构建的 .NET 程序,以及几乎所有您在 .NET 中进行的操作,都会生成某种形式的程序集。每个程序都运行在一个称为 CLR(公共语言运行时)的软件和硬件抽象层上。CLR 无法直接将代码转换为硬件平台(二进制形式)。它必须执行一些特定的检查,如版本信息、安全权限、属性等。满足 CLR 所有这些需求的文件或编程单元称为程序集。此外,程序集主要分为两种类型:私有程序集和共享程序集。
共享程序集
- 全局程序集缓存 (GAC) = GAC 的路径是 [父目录] : [Windows 目录] \assembly。您还可以通过“控制面板”=>“管理工具”=>“Microsoft .NET Framework 3.0 配置”来查看 GAC。“我的电脑”节点下,点击“程序集缓存”。这里是存放程序集的目录。位于 GAC 中的程序集由多个应用程序共享。每个程序集都通过其强名称进行唯一标识。
- 创建共享程序集 = 在 .NET Framework 平台上编写的每个程序都是一个程序集。区别在于我们是否希望将其用作程序集。好的。编写一个没有错误的程序,例如我下面提供的程序……在这里,我创建了一个名为
StrongFile
的程序集,其中包含一个名为Strong
的类,该类有一个名为Greeting
的方法。using System; using System.Collections.Generic; using System.Linq; using System.Text; public class strong { public string Greeting(string name) { return ("Your assembly says Hi : " + name); } static void Main(string[] args) { } }
现在使用 sn.exe 为程序集分配强名称(如果您是 Visual Studio 用户)。对于 Express Edition 用户,您可以通过“属性页”=>“签名”选项卡 => 输入名称来完成,无需密码保护。我们正在创建一个将被外部开发人员共享的程序集,因此分配密码会产生共享冲突,因此不要对程序集进行密码保护,因为我们希望将其用于全局目的。
注意 = Express Edition 用户必须将应用程序的输出类型设置为“类库”,才能获得程序集。因此,点击“属性”=>“应用程序”=>“输出类型”并将其设置为“类库”。
编辑我们项目目录中“属性”文件夹下的 AssemblyInfo.cs 文件,即 StrongFile=>Properties=>AssemblyInfo.cs。在我们之前创建的代码中添加以下几行。
[assembly: AssemblykeyFile("FileKey.snk")]
现在构建项目;这将会在 bin=>Release=>StrongFile.dll 中创建已签名的 StrongFile.dll。将其拖到 GAC。现在我们可以随时使用我们的
StrongFile
程序集了。只需引用它! - 更改我们的程序集版本 = 我们可以通过再次编辑 AssemblyInfo.cs 来简单地更改程序集的版本。
您可以通过转到“项目”=>“项目属性”=>“应用程序”=>“程序集信息”=>“程序集版本”来更改版本。构建项目。不要忘记将新程序集放入 GAC。
注意:您可能会注意到,项目构建后,在 Windows 资源管理器中没有程序集版本更改,但请放心。仍然将此新程序集放入 GAC - 在那里您可以看到
StrongFile
的新版本。请确保只更改程序集版本,而不是AssemblyFileVersion
。为了使更改生效,请更改StrongFile
代码中的某些内容,就像我在这里更改一样。public class strong { public string Greeting(string name) { return ("Your 'NEW' assembly says Hi : " + name); } static void Main(string[] args) { } }
将新程序集放入 GAC 后
私有程序集
传统 DLL 和程序集之间存在细微差别。传统 DLL 可以复制到客户端目录供客户端使用,而其他程序则无法了解它们(这就是为什么某些游戏和软件仍然可以被破解的原因)。程序集也具有此功能。如果只有少数应用程序会使用您的库程序集,您可以将其放在相关的客户端应用程序目录中,而不是放在 GAC 中。这样可以节省您在强命名程序集、编辑 AssemblyInfo.cs 等方面的时间。可以放在应用程序目录中且不需要强名称的程序集称为“私有
程序集”。私有
程序集可以安装/卸载,而不会有破坏应用程序的风险。您可能会注意到,我们共享的程序集 StrongFile
的属性之一是 LocalCopy
设置为 false
,这意味着此程序集无法本地复制到应用程序目录,但私有程序集默认此属性为“true
”,即它们可以本地复制。
与私有程序集相关的另一个重要概念是“延迟签名”……我们将在下一节中进行研究。延迟签名 = 您可能会遇到这种情况:您需要将程序集交给外部人员/开发人员进行进一步修改,但您不能将程序集的私钥给他,那么他该如何工作?这个问题已通过延迟签名技术得到解决。在此过程中,我们可以跳过使用私钥对程序集进行签名,并关闭程序集验证。现在,程序集仅使用公钥进行签名。现在您可以将程序集和公钥交给开发人员,无需私钥。可以这样完成:我们已经创建了“StrongFile
”程序集。
借助 sn.exe ,我们可以从文件中提取公钥
Syntax : sn -p [infile] [outfile]
提取 [infile] 中的密钥对中的公钥,并将其导出到 [outfile]。
sn /p FileKey.snk PublicKey.snk
这将创建包含我们程序集 StrongFile
公钥的文件“PublicKey.snk”。
现在是时候像这样编辑 AssemblyInfo.cs 了

再次构建程序集 StrongFile
。
注意 = 如果您通过“属性”=>“签名”选项卡延迟签名程序集,则无需编辑 AssemblyInfo.cs 。
现在我们需要像这样关闭验证过程
sn /Vr StrongFile.dll
然后,您将收到以下消息

现在您可以只将程序集与公钥文件一起发送给开发人员,即 StrongFile.dll 程序集以及 ThePublicKey.snk 。在他完成工作后,您可以像这样重新分配程序集,并使用私钥
sn /R StrongFile.dll FileKey.snk
注意
- 请注意打开/关闭验证,因为已关闭验证的程序集可能会被任何其他程序集替换而不会被检测到。
游戏和许多软件都是这样破解的。恶意用户用原始 DLL 替换了未签名的 DLL。即使是高度工程化的引擎也未能检测到这些更改。
- 所有 sn.exe 选项都区分大小写,必须完全正确键入。
- 如果您使用的是 Visual C# Express Edition,则无法使用“Visual Studio 2008 命令提示符”。在这种情况下,这些实用程序位于 SDK 的 bin 文件夹中 - 完整路径是“C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin”,然后在那里打开您的命令提示符即可使用。
要永久使用这些实用程序,请将
环境变量
更改为 bin 文件夹。 - Visual C# Express Edition 仍然紧凑轻量,但也有其自身的缺点;例如,您将无法使用位于“控制面板”=>“管理工具”中的“配置工具”。此外,这些版本使用的帮助文档较少。
现在我们进入本文的最后一个部分,即清单。
清单
程序集是一个自描述的编程单元。每个程序集的信息存储在哪里,它们之间有什么区别?答案是“清单”。清单标识程序集。它描述、列出它所依赖的其他程序集,程序集公开或使用的所有类型和资源,以及它的安全要求。可以使用 IL 反汇编器 - 中间语言反汇编器 (ildasm.exe) 查看清单。
使用 IL DASM = 转到 Visual Studio 2008 命令提示符并键入 ildasm
- 将出现一个窗口,如下所示:

在这里,我打开了 StrongFileApp.exe 。点击 MANIFEST
,您将看到

您可以看到我们的应用程序引用的所有程序集。如果进一步展开 StrongFileApp
节点,您将清楚地看到应用程序的每个信息都被揭示出来,如命名空间、方法、按钮等。

ILDASM 用于应用程序的调试和测试。
关注点
至此,我们已经涵盖了与程序集相关的所有功能。在我的下一篇文章中,我们将涵盖与程序集相关的其他主题,如程序集操作、探测、代码库等。我希望本文档能帮助 Visual Studio 和 Express Editions 用户。
历史
- 2010 年 5 月 9 日:初始版本