如何将引用的库打包到一个新的库中

本文关键字:一个 引用 | 更新日期: 2023-09-27 18:16:50

创建新库MyAPI.dll时,我引用了许多其他(非标准)库,如RestSharp.dll, Newtonsoft.dll, MyUtilities.dll等。我的库在我的开发环境中工作良好,因为我已经下载了所有其他库,并且它们位于我的项目的bin文件夹中,但是一旦我试图发布该库并在新位置使用它,它就会失败,因为无法找到引用的库。

如何设置我的MyAPI.csproj项目,以便这些dll/库被打包到我发布的.dll文件中,并且MyAPI.dll的未来用户不必担心下载和引用这些依赖项?

本以为这很简单,但是今天我的google-fu很弱。将这些外部引用设置为CopyLocal = False将它们从/bin/目录中删除,给人一种错觉,即它们被打包到MyAPU.dll中,但实际上Visual Studio只是将它们添加到我的全局程序集缓存(GAC)中,这对API的未来用户没有帮助。

有两个选项(据我所知):

  1. ILMerge
  2. 嵌入式资源和程序集。解决(见Jeffrey Richter)

首先你可以使用ILMerge,这是一个命令行程序,可以合并多个。net程序集,创建一个输出文件。它不能合并WPF项目。可以添加到构建后事件中,使合并自动进行。

第二种是将库作为嵌入式资源添加到项目中,然后注册到程序集。当需要从资源中解析事件和加载程序集时。Jeffrey Richter关于这种方法的文章。

第二个方法有很大的缺点,它不能将多个库合并为一个(它只能用于将库添加到可执行文件中),至少在没有其他工具的c#中是这样。要向库中添加库,必须使用另一个工具,在第二页Jeffrey的文章评论中提到过:(模块初始化器注入)。将库嵌入到其他库的问题是你不能(至少在c#中)注册到汇编。在需要嵌入库之前解析事件,所以你需要使用模块初始化器注入来注入注册到模块的初始化器。还可以将其设置为构建事件,使用工具将其写入页面。这听起来可能很复杂,但是一旦你设置好了就很简单了。

如何将引用的库打包到一个新的库中

有一个免费的nuget包"Costura "。它将依赖项程序集作为资源打包到程序集中。该解决方案适用于WPF和其他托管程序集。

如果依赖项程序集不在执行文件夹中,则自动采用打包的程序集。它还自动配置您的msbuild目标,以便在构建期间打包依赖项。您不必在程序集中添加代码。它还允许您配置在xml文件中打包或不打包哪些程序集。

它使用两种方法的组合:

  • Jeffrey Richter建议使用嵌入式资源作为合并程序集的方法。
  • Einar Egilsson使用cecil创建模块初始化式的建议。

您可以在这里找到文档:https://github.com/Fody/Costura/blob/master/README.md

它不是免费的(有一个试用版),但是我的一个朋友告诉我一个叫做。net Reactor的程序,它有能力将一个exe和依赖的DLL打包成一个可执行文件,非常值得一看。

我想说下一个最直接的选择是ClickOnce,这里有一个很好的教程。