我最终使用了NuGet 包 Costura.Fody(在此处找到存储库)。它在您的类模块(或程序)中包装依赖项的方式简直就是魔术。使用 Costura.Fody 时,它会查找任何依赖项并自动将它们压缩到您的类库 dll 中,从而生成单个 dll。然后它将使对资源的所有引用指向您的 dll 中的嵌入资源。您需要做的就是添加两个 NuGet 包,它会在您构建项目时完成所有工作。真的很滑!
重要提示:Fody(运行 Costura.Fody 所需的 Costura.Fody 的依赖项)当前版本仅与 Visual Studio 2019(使用 MSBuild 16)兼容。就我而言,我有 Visual Studio 2017(它使用 MSBuild 15)。我不得不使用
Costura.Fody
仍然使用旧 MSBuild 的旧版本。这也要求我降级Fody
。所以我最终使用了适用于 MSBuild 15 的最新版本。Fody 版本 4.2.1 和 Costura.Fody 版本 3.3.3 非常适用于 Visual Studio 2017。
如果需要,它甚至支持提取资源。例如,我希望在SevenZipSharp
图书馆中使用它。它需要一个7zip.dll
要使用的文件的路径。因此,我在FodyWeavers.xml
与您的解决方案位于同一目录中的文件中使用了以下内容。
<?xml version="1.0" encoding="utf-8"?>
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<Costura CreateTemporaryAssemblies='true' IncludeDebugSymbols='false'>
<Unmanaged32Assemblies>
7z
</Unmanaged32Assemblies>
<Unmanaged64Assemblies>
7z
</Unmanaged64Assemblies>
</Costura>
</Weavers>
您还需要在项目中包含 7zip.dll,以便编译 dll,因为它们不像资源那样使用(就像 SevenZipSharp 库一样)。为此,您可以在项目的根目录中添加以下文件夹以及相应的架构文件。然后将它们添加为Build Action: Embedded Resource
.

这将在需要时在运行时提取 7zip.dll 依赖项,因此我可以在使用 SevenZipSharp 库时引用该路径。在这一点上,我还没有找到如何获取对它使用的(C83815D61CE49B2E8D23145A1B95A956 可能是目录本身中所有文件的校验和?)目录的引用,但在我的情况下,这是将其提取到的位置...
%tmp%\Costura\C83815D61CE49B2E8D23145A1B95A956\32\

更新:我找到了一种解决方法来获取该校验和的路径,例如使用程序集信息的目录。我创建了以下函数来尝试设置 7Zip 库路径。它可能对某些人有帮助,所以我把它包括在这里。
private bool SetupSevenZipLibrary()
{
string costuraExtractionPath = null;
try
{
//This will use the embeded resource to try and set a base path to the extraction
//location created by by Costura.Fody
string sevenZipAssembly = typeof(SevenZip.ArchiveFileInfo).Assembly.Location;
if (File.Exists(sevenZipAssembly))
costuraExtractionPath = Path.GetDirectoryName(sevenZipAssembly);
}
catch
{
//Issue trying to grab the extraction path from the Assembly information so try
//to use the first path found in the Costura directory as a last ditch effort
DirectoryInfo di = null;
string costuraTempPath = Path.Combine(
Path.GetTempPath(), //ex: C:\Users\username\AppData\Local\Temp
"Costura" //ex: Costura
);
di = new DirectoryInfo(costuraTempPath);
if (!di.Exists)
return false;
//ex: C:\Users\username\AppData\Local\Temp\Costura\C83815D61CE49B2E8D23145A1B95A956\
costuraExtractionPath = di.GetDirectories().First().FullName;
}
try
{
if (!Directory.Exists(costuraExtractionPath))
throw new Exception();
string sevenZipPath = Path.Combine(
costuraExtractionPath, //ex: C:\Users\username\AppData\Local\Temp\Costura\C83815D61CE49B2E8D23145A1B95A956
Environment.Is64BitProcess ? "64" : "32", //ex: 32
"7z.dll" //ex: 7z.dll
);
if (!File.Exists(sevenZipPath))
throw new Exception();
SevenZipBase.SetLibraryPath(sevenZipPath);
return true;
}
catch { return false; }
}
是使用...
if (!SetupSevenZipLibrary())
throw new Exception("Error setting the path of the 7zip library.");