将DLL合并到EXE中?

74
我有两个DLL文件,希望将其包含在我的EXE文件中,以便更容易地分发它。我已经在各处读了一些如何做到这一点的文章,甚至在这里这里找到了一个好的线索,但对于我来说太过复杂,我需要一份真正基础的说明来完成此操作。
我使用Microsoft Visual C# Express 2010,请原谅我的“低水平”问题,但我感觉自己比其他人低一两个级别 :- / 如果有人可以指出如何通过分步指南将这些DDL文件合并到我的EXE中,那就太棒了!
14个回答

98

适用于.NET Framework 4.5

ILMerge.exe /target:winexe /targetplatform:"v4,C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0" /out:finish.exe insert1.exe insert2.dll

ILMerge

  1. 打开CMD并切换到你的目录。例如: cd C:\test
  2. 复制上述代码。
  3. /out:finish.exefinish.exe 替换成你想要的任何文件名。
  4. /out:finish.exe 后面,你必须给出要合并的文件。

1
太好了,成功了。问题出在目录路径末尾多了一个“\”。 - Momro
7
我按照你上面提到的指示进行操作,但仍未合并。请帮帮我。在命令提示符中输入以下内容:ILMerge.exe /target:winexe /targetplatform:"v4,C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0" /out:finish.exe myExe.exe mfc100u.dll mfc110u.dll msvcp110.dll 出现错误:An exception occurred during merging: ILMerge.Merge: Could not load assembly from the location 'C:\test\my folder\mfc 100u.dll'. Skipping and processing rest of arguments. 有任何想法出了问题吗? - AB Bolim
3
有时你需要1)使用 Program Files(x86) 2)输入ILMerge的完整路径。对于控制台应用程序,请使用 /target:exe - SWdV
Windows默认自带.NET框架,位于C:\Windows\Microsoft.NET\Framework。因此,您也可以使用/targetplatform:"v2,C:\Windows\Microsoft.NET\Framework\v2.0.50727"/targetplatform:"v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319" - Gray Programmerz

41

使用Costura.Fody

您只需要安装NuGet,然后进行构建。最终的可执行文件将是独立的


1
这是一个非常有趣的项目。但它似乎是Fody的插件...所以您可以通过提供一些关于Mono.CecilFody的信息来改进这个答案(因为它们都是依赖项,而且确实是最相关的基础前提)。但是,是的,这个插件本身似乎使得以可配置的方式嵌入和分发dll变得更加“容易”。 - Brett Caswell
7
这是巫术。难以置信的简单。Install-Package Costura.Fody,然后就大功告成了!你的构建将生成一个庞大的exe文件。 - Cristian Diaconescu
1
不太起作用,但我支持在某些情况下可能会发生。(无法构建并且出现错误) - Antonios Tsimourtos
哇 - 我苦苦挣扎了3天,试图让iLMerge与多个第三方dll一起工作,这些dll有多个其他引用我必须指向,即使我已经添加了所有依赖项,它仍然无法工作,并且在检查日志时,它会改变一些命名空间名称,说它们是重复的。(它们在第三方程序集内部)这正如@CristianDiaconescu所说的那样容易。 - cmartin

25

下载ilmergeilmergre gui。使文件合并变得非常容易。 我已经使用过它们,效果很好。


18

将DLL文件作为资源引用,并使用AssemblyResolve事件返回资源DLL。

public partial class App : Application
{
    public App()
    {
        AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
        {

            Assembly thisAssembly = Assembly.GetExecutingAssembly();

            //Get the Name of the AssemblyFile
            var name = args.Name.Substring(0, args.Name.IndexOf(',')) + ".dll";

            //Load form Embedded Resources - This Function is not called if the Assembly is in the Application Folder
            var resources = thisAssembly.GetManifestResourceNames().Where(s => s.EndsWith(name));
            if (resources.Count() > 0)
            {
                var resourceName = resources.First();
                using (Stream stream = thisAssembly.GetManifestResourceStream(resourceName))
                {
                    if (stream == null) return null;
                    var block = new byte[stream.Length];
                    stream.Read(block, 0, block.Length);
                    return Assembly.Load(block);
                }
            }
            return null;
        };
    }
}

1
好的,我完全不明白你在那里写了什么;-) 我应该把这段代码放在哪里? - Momro
1
对于WinForms,请尝试使用以下代码替换上面的代码:AppDomain.CurrentDomain.AssemblyResolve += (sender, arg) => { if (arg.Name.StartsWith("Your_DLL")) return Assembly.Load(Properties.Resources.Your_DLL); return null; }; - Destructor
好的,我使用了你缩短后的版本,但我的IDE告诉我“Assembly”名称在此上下文中不可用 :-/ - Momro
添加 using System.Reflection; - Destructor
在您的解决方案资源管理器中,有一个名为“引用”的节点。这是您添加dll以在程序中使用的位置。所有已引用的dll都列在其中。选择您的dll并将“复制本地”更改为false。 - Destructor
显示剩余5条评论

10

下载

ILMerge

调用

ilmerge /target:winexe /out:c:\output.exe c:\input.exe C:\input.dll

如果您有一个.NET Framework 4.5应用程序,那么请将以下内容添加到它中:/target:winexe /target platform:"v4,C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0" :) - Yuki Kutsuya
这会导致以下错误消息: 合并期间发生异常: 不允许未解决的程序集引用:System.Core。- 我创建了一个批处理文件,内容如下:ilmerge /target:winexe my_exe.exe my_dll.dll /out:merged.exe - Momro
@Momro 请尝试使用目标平台参数 ;)。 - Yuki Kutsuya
1
好的,我有这个命令: ilmerge /target:winexe /target:platform:"v4,c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\" /out:merged.exe my_exe.exe my_dll.dll,但提示说我必须至少指定一个输入文件和一个输出文件。我也尝试将输出参数与输入参数交换,但没有结果。 - Momro

9
  1. Install ILMerge as the other threads tell you to

  2. Then go to the installation folder, by default C:\Program Files (x86)\Microsoft\ILMerge

  3. Drag your Dll's and Exes to that folder

  4. Shift-Rightclick in that folder and choose open command prompt

  5. Write

    ilmerge myExe.exe Dll1.dll /out:merged.exe
    

    Note that you should write your exe first.

这里有你合并后的exe文件。如果你只需要一次合并,那么这可能不是最好的方法,但是对于一次性使用来说,这是最简单的方法。我建议将Ildmerge添加到你的环境变量中。


1
我刚按照您上面提到的指示进行操作。 我还将ilmerge添加到了我的系统路径中。 但仍未合并。请帮忙解决。在命令提示符中: > ilmerge myExe.exe mfc100u.dll mfc110u.dll /out: final.exe错误:“合并过程中出现异常: ILMerge.Merge:无法从位置'C:\ test \ my folder \ mfc找到装配。 100u.dll'。跳过并处理其余参数。”有任何想法出了什么问题吗? - AB Bolim
看起来你的dll文件名包含空格?尝试在它周围加上引号。 - Henrik Karlsson
谢谢回复。但是只有在我上面的评论中,mfc100u.dll 有空格。我想合并多个 dll 文件。我也尝试过 ILMerge GUI。但仍然面临同样的问题。请帮帮我。 - AB Bolim
无法让其他用户的上述示例正常工作,但这个可以完美运行。谢谢。 - rerat

6
static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
    /* PUT THIS LINE IN YOUR CLASS PROGRAM MAIN() */           
        AppDomain.CurrentDomain.AssemblyResolve += (sender, arg) => { if (arg.Name.StartsWith("YOURDLL")) return Assembly.Load(Properties.Resources.YOURDLL); return null; }; 
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

首先将DLL文件添加到您的项目资源中。添加一个名为“Resources”的文件夹。


6

2019年更新(仅供参考):

.NET Core 3.0开始,这个功能是支持的 开箱即用的。要利用单文件可执行文件发布功能,只需将以下行添加到项目配置文件中:

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

现在,dotnet publish应该能够生成单个 .exe 文件而无需使用任何外部工具。

有关此功能的更多文档,请参见https://github.com/dotnet/designs/blob/master/accepted/single-file/design.md


1
不错,这个可以工作,但你只需要指定 RuntimeIdentifierRuntimeIdentifiers,文件就会减少约 65.4 MB。 - Daniel

2
你也可以使用具有 GUI 接口的 Codeplex 上的 ilmergertool

2

这里是官方文档。在步骤2中也会自动下载。

以下是一种非常简单的方法,我已经成功地使用.NET框架4.6.1构建了我的应用程序。

  1. Install ILMerge nuget package either via gui or commandline:

    Install-Package ilmerge
    
  2. Verify you have downloaded it. Now Install (not sure the command for this, but just go to your nuget packages): enter image description here Note: You probably only need to install it for one of your solutions if you have multiple

  3. Navigate to your solution folder and in the packages folder you should see 'ILMerge' with an executable:

    \FindMyiPhone-master\FindMyiPhone-master\packages\ILMerge.2.14.1208\tools
    

    enter image description here

  4. Now here is the executable which you could copy over to your \bin\Debug (or whereever your app is built) and then in commandline/powershell do something like below:

    ILMerge.exe myExecutable.exe myDll1.dll myDll2.dll myDlln.dll myNEWExecutable.exe
    
现在您将拥有一个新的可执行文件,其中包含了所有您的库!

对我来说,这是更新ILMerge的最佳方式,感谢@benscabbia。 - it3xl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接