是否可以将一个预先存在的DLL嵌入到一个编译好的c#可执行文件中(这样你就只有一个文件可以分发)?如果这是可能的,人们会怎么去做呢?

通常情况下,我不介意把dll放在外面,让安装程序处理所有事情,但工作中有几个人问过我这个问题,老实说,我不知道。


当前回答

另一个可以很好地处理这个问题的产品是SmartAssembly,网址是SmartAssembly.com。该产品除了将所有依赖项合并到单个DLL中之外,还(可选地)混淆代码,删除额外的元数据以减少生成的文件大小,并且还可以实际优化IL以提高运行时性能。

它还向您的软件(如果需要的话)添加了某种全局异常处理/报告功能,这可能很有用。我相信它还有一个命令行API,因此您可以将其作为构建过程的一部分。

其他回答

您可以将dll作为嵌入式资源添加,然后让程序在启动时将它们解压缩到应用程序目录中(在检查它们是否已经存在之后)。

虽然制作安装文件非常容易,但我认为这样做并不值得。

编辑:这种技术对于. net程序集来说很容易。与非。NET dll,这将是更多的工作(你必须弄清楚在哪里解包文件和注册它们等等)。

如果它们实际上是托管程序集,您可以使用ILMerge。对于本地dll,您将有更多的工作要做。

请参见:如何将c++ windows dll合并到c#应用程序exe中?

在上面扩展@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>

这听起来可能很简单,但WinRar提供了将一堆文件压缩为自提取可执行文件的选项。 它有很多可配置的选项:最终图标,提取文件到给定的路径,提取后执行的文件,自定义logo/文本在提取期间显示的弹出窗口,根本没有弹出窗口,许可协议文本,等等。 在某些情况下可能有用。

另一个可以很好地处理这个问题的产品是SmartAssembly,网址是SmartAssembly.com。该产品除了将所有依赖项合并到单个DLL中之外,还(可选地)混淆代码,删除额外的元数据以减少生成的文件大小,并且还可以实际优化IL以提高运行时性能。

它还向您的软件(如果需要的话)添加了某种全局异常处理/报告功能,这可能很有用。我相信它还有一个命令行API,因此您可以将其作为构建过程的一部分。