是否可以将一个预先存在的DLL嵌入到一个编译好的c#可执行文件中(这样你就只有一个文件可以分发)?如果这是可能的,人们会怎么去做呢?
通常情况下,我不介意把dll放在外面,让安装程序处理所有事情,但工作中有几个人问过我这个问题,老实说,我不知道。
是否可以将一个预先存在的DLL嵌入到一个编译好的c#可执行文件中(这样你就只有一个文件可以分发)?如果这是可能的,人们会怎么去做呢?
通常情况下,我不介意把dll放在外面,让安装程序处理所有事情,但工作中有几个人问过我这个问题,老实说,我不知道。
当前回答
在上面扩展@Bobby的回答。您可以编辑.csproj,以便在构建时使用IL-Repack自动将所有文件打包到单个程序集中。
使用Install- package ILRepack.MSBuild.Task安装nuget ILRepack.MSBuild.Task包 编辑.csproj的AfterBuild部分
下面是一个简单的示例,它将ExampleAssemblyToMerge.dll合并到项目输出中。
<!-- ILRepack -->
<Target Name="AfterBuild" Condition="'$(Configuration)' == 'Release'">
<ItemGroup>
<InputAssemblies Include="$(OutputPath)\$(AssemblyName).exe" />
<InputAssemblies Include="$(OutputPath)\ExampleAssemblyToMerge.dll" />
</ItemGroup>
<ILRepack
Parallel="true"
Internalize="true"
InputAssemblies="@(InputAssemblies)"
TargetKind="Exe"
OutputFile="$(OutputPath)\$(AssemblyName).exe"
/>
</Target>
其他回答
在c#中创建本地/托管程序集是可能的,但并不那么容易。如果你使用c++的话,事情就简单多了,因为Visual c++编译器可以像创建其他程序集一样轻松地创建混合程序集。
除非你对生成混合程序集有严格的要求,否则我同意MusiGenesis的观点,这真的不值得用c#来麻烦。如果您需要这样做,也许可以考虑转移到c++ /CLI。
我强烈推荐使用Costura。Fody -到目前为止在程序集中嵌入资源的最好和最简单的方法。它可以作为NuGet包使用。
Install-Package Costura.Fody
将其添加到项目后,它将自动将复制到输出目录的所有引用嵌入到主程序集中。你可能想要通过添加一个目标到你的项目来清除嵌入的文件:
Install-CleanReferencesTarget
您还可以指定是否包含pdb、排除某些程序集或动态提取程序集。据我所知,也支持非托管程序集。
更新
目前,一些人正在尝试添加对DNX的支持。
更新2
对于最新的Fody版本,您需要MSBuild 16(因此Visual Studio 2019)。Fody 4.2.1版本将支持MSBuild 15。(参考:Fody只支持MSBuild 16及以上版本。当前版本:15)
.NET Core 3.0原生支持编译为单个.exe
该特性是通过在项目文件(.csproj)中使用以下属性启用的:
<PropertyGroup>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
这无需任何外部工具即可完成。
详见我对这个问题的回答。
如果它们实际上是托管程序集,您可以使用ILMerge。对于本地dll,您将有更多的工作要做。
请参见:如何将c++ windows dll合并到c#应用程序exe中?
是的,可以将. net可执行文件与库合并。有多种可用的工具来完成这项工作:
ILMerge是一个实用程序,可用于将多个. net程序集合并为单个程序集。 Mono mkbundle,将libmono的exe和所有程序集打包到一个二进制包中。 IL-Repack是ILMerge的FLOSS替代品,具有一些附加特性。
此外,这可以与Mono链接器结合使用,它可以删除未使用的代码,从而使生成的程序集更小。
另一种可能是使用。net z,它不仅允许压缩程序集,还可以将dll直接打包到exe中。与上面提到的解决方案的不同之处在于,.NETZ不会合并它们,它们是单独的程序集,但被打包到一个包中。
. netz是一个开源工具,它压缩和打包Microsoft . net Framework可执行文件(EXE, DLL),以使它们更小。