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

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


当前回答

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

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

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

其他回答

.NET Core 3.0原生支持编译为单个.exe

该特性是通过在项目文件(.csproj)中使用以下属性启用的:

    <PropertyGroup>
        <PublishSingleFile>true</PublishSingleFile>
    </PropertyGroup>

这无需任何外部工具即可完成。

详见我对这个问题的回答。

在Visual Studio中右键单击项目,选择项目属性->资源->添加资源->添加现有文件… 并将下面的代码包含到你的App.xaml.cs或等效程序中。

public App()
{
    AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}

System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    string dllName = args.Name.Contains(',') ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll","");

    dllName = dllName.Replace(".", "_");

    if (dllName.EndsWith("_resources")) return null;

    System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());

    byte[] bytes = (byte[])rm.GetObject(dllName);

    return System.Reflection.Assembly.Load(bytes);
}

以下是我的博客原文: http://codeblog.larsholm.net/2011/06/embed-dlls-easily-in-a-net-assembly/

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

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

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

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

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

在c#中创建本地/托管程序集是可能的,但并不那么容易。如果你使用c++的话,事情就简单多了,因为Visual c++编译器可以像创建其他程序集一样轻松地创建混合程序集。

除非你对生成混合程序集有严格的要求,否则我同意MusiGenesis的观点,这真的不值得用c#来麻烦。如果您需要这样做,也许可以考虑转移到c++ /CLI。