将一个项目中的所有源代码未编译消耗到另一个项目中 (PDFSharp)

问题描述

正如标题所说,我想在我自己的项目中使用 PDFSharp 的所有源代码。但是让我解释一下我为什么会出现这种情况,所以如果我可以做其他事情,也许还有其他选择。

目标:将我的项目编译为单个 .exe 文件以供使用。没有安装程序。 问题:它使用了导致我出现问题的 PDFSharp.dll。

我想做的是使用 ILMerge 创建 .exe。我过去曾成功地将其用于其他项目。

我认为的问题是 ILMerge 需要引用 PDFSharp 使用的其他程序集。第一个是 Microsoft.ApplicationInsights。所以为了绕过这个,我通过 Nuget 将 Microsoft.ApplicationInsights 安装到我的项目中。然后从项目中删除了实际引用,但在我的 ILMerge 命令中引用了该库,如下所示:

/lib:"C:\<path to assembly>\Microsoft.ApplicationInsights.2.16.0\lib\net46"

这确实有效。除了,现在它要求另一个图书馆,我收到这个错误

Unresolved assembly reference not allowed: GdPicture.NET.11.

这看起来像是一个付费图书馆,也许下载试用版可以让我克服这个问题。我还没试。我换了档,因为我觉得我可能会尝试参考无穷无尽的组件。

然后我尝试获取 PDFSharp 源代码,我在这里找到了 1.32 版: https://sourceforge.net/projects/pdfsharp/files/pdfsharp/PDFsharp%201.32/

我在我的解决方文件添加了对这个项目的引用,所以现在我有一个包含 2 个项目的解决方案。太好了。

然后我尝试将源文件链接到我的项目中。如何做到这一点在这里https://jeremybytes.blogspot.com/2019/07/linking-files-in-visual-studio.html#:~:text=To%20link%20files%2C%20use%20the,CLICK%20THE%20%22Add%22%20BUTTON。 这似乎有效,但我添加的每个文件都需要另一个文件,该文件引用另一个文件等。这似乎是无止境的。所以这让我产生了将整个源代码用于我的项目的想法,但我还没有看到这样做的好方法。我无法添加对项目的引用,因为它只是引用了编译后的 dll,iLMerge 也无法合并。

我还尝试将 PDFSharp 的 .csproj 文件中的标签更新为“模块”以创建 .netmodule 文件。这会在 obj 目录中创建文件,但会引发错误

\PDFsharp\code\PdfSharp\obj\Release\PdfSharp.netmodule' is not an assembly

感谢任何帮助。谢谢。

更新:我反转了所有内容添加了 PdfSharp 引用 - 回到我所在的位置并将我的项目更改为模块并构建它创建了一个 .netmodule 文件。然后使用程序集链接器从该文件创建一个 .exe。从 VS Dev 提示符使用此命令即可。

al MyModule.netmodule /target:exe /out:MyProgram.exe /main:MyNamespace.MyClass.Main

这创建了 .exe,但是在没有任何其他支持文件的情况下运行时会产生文件未找到错误

System.IO.FileNotFoundException: Could not load file or assembly 'MyModule.netmodule' or one of its dependencies. The system cannot find the file specified. 

哪个有趣,因为模块应该在 exe 中,对吗?

解决方法

我现在有这个工作,所以我只想把我的结果放在这里,因为它已经发布了。

我最初的问题是我错误地认为是 PDFSharp.dll 导致了问题,但实际上是我引用的另一组 3rd Party dll。

我尝试了几个小时让 iLMerge 工作,唯一的成功是它会踢出单个 .exe 文件,但会出现运行时错误。

我遇到的错误:

错误:不允许未解析的程序集引用:Custom.Assembly。

解决方案:如果可能,请参考程序集。如果你有很多,你可以用 /lib:"C:\folderpath" 开关引用一个文件夹。

错误:不允许未解析的程序集引用:ADotNetFramework.dll。

解决方案:您可以引用所需的 .Net Framework 路径,iLMerge 将在其中搜索缺失的引用。示例:/targetplatform:"v4,C:.NETFramework\v4.8"

错误: 程序集“xyz.dll”未正确合并。它仍被列为目标程序集中的外部引用。

解决方案:您可以使用 /closed 开关解决此错误。但是,我认为我什至不应该收到此错误,因为“xyz.dll”是要组合的引用 dll。

另外 - 使用 /log 开关,它对于准确查看 iLMerge 正在做什么和找出您的问题非常有帮助。示例:/log:mylog.txt

这让我看到 iLMerge 在第 3 方程序集中查找重复的命名空间并自动重命名它们。这是我日志中的一个示例:

将程序集“My.Assembly.Name”合并到目标程序集。 重复类型名称:修改类型“f__AnonymousType02' (from assembly 'My.Assembly.Name') to 'My.Assembly.Name.<>f__AnonymousType02”的名称 重复类型名称:修改类型 'f__AnonymousType12' (from assembly 'My.Assembly.Name') to 'My.Assembly.Name.<>f__AnonymousType12' 的名称 重复类型名称:将类型 '' 的名称(从程序集 'My.Assembly.Name')修改为 'My.Assembly.Name。

最后 - 我发现的解决方案是不使用 iLMerge。我找到了这个答案:https://stackoverflow.com/a/40786196/2596309 其中使用了 Costura.Fody 我安装了 nuget 包:

Install-Package Costura.Fody -Version 4.1.0

清理并构建了我的解决方案,它创建了一个我测试过的单个 .exe 文件并且它工作正常。从字面上看,我花了 3 天的时间来解决这个问题,解决方案只花了 3 分钟...