c#如何合并多个dll文件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#如何合并多个dll文件相关的知识,希望对你有一定的参考价值。
我两个文件用IL 的gui,一直报错,使用任何.net版本进行合并都一样
ILMerge可以满足合并dll的需求:下载连接 http://download.microsoft.com/download/1/3/4/1347C99E-9DFB-4252-8F6D-A3129A069F79/ILMerge.msi
安装完成以后,可以将安装目录加入PATH下,
在命令行用如下命令进行merge
ILMerge /ndebug /target:dll /out:D:\output\KCService.dll /log D:\project\xxx-1.dll D:\project\xxx-2.dll
参数说明:
(1) "/out:D:\output\KCService.dll" 为合并后的DLL目录及最终的DLL文件
(2) “D:\project\xxx-1.dll D:\project\xxx-2.dll” 为要合并的源头DLL文件
如果要发布exe文件则可以将dll文件打入exe文件中
ILMerge /ndebug /target:winexe /out:D:\output\runKCService.exe /log D:\project\kcservice.exe D:\project\xxx-1.dll D:\project\xxx-2.dll 参考技术A 不可以的 DLL文件即动态链接库文件,是一种可执行文件,它允许程序共享执行特殊任务所必需的代码和其他资源。Windows提供的DLL文件中包含了允许基于Windows的程序在Windows环境下操作的许多函数和资源。 VC++、C++ Builder、Delphi都可以编写DLL文件。Visual Basic 5.0以上版本也可以编写一种特殊的DLL,即ActiveX DLL。 CS一般是C#生成的原文件 参考技术B 使用 DirectoryInfo类获取文件夹下所有拓展名是*.dll的文件名。
使用Assembly通过路径循环加载*.dll。
通过反射调用即可。 参考技术C 可以有偿帮合并
先把你的程序打包发给我
如何将 C++ windows dll 合并到 C# 应用程序 exe 中?
【中文标题】如何将 C++ windows dll 合并到 C# 应用程序 exe 中?【英文标题】:How can a C++ windows dll be merged into a C# application exe? 【发布时间】:2010-09-09 11:49:14 【问题描述】:我有一个 Windows C# 程序,它使用 C++ dll 进行数据 i/o。我的目标是将应用程序部署为单个 EXE。
创建这样一个可执行文件的步骤是什么?
【问题讨论】:
您应该使用 BoxedAppPacker 或 BoxedApp SDK。它必须有帮助。 重复***.com/questions/666799/… 【参考方案1】:托管和非托管代码的单一程序集部署 2007 年 2 月 4 日,星期日
.NET 开发人员喜欢 XCOPY 部署。他们喜欢单一的装配组件。至少我总是觉得有点不安,如果我必须使用某个组件并且需要记住一个文件列表,还需要包含在该组件的主程序集中。因此,当我最近不得不开发一个托管代码组件并不得不使用来自 C DLL 的一些非托管代码来扩充它时(感谢 Marcus Heege 帮助我解决这个问题!),我想到了如何更轻松地部署这两个 DLL .如果这只是两个程序集,我可以使用 ILmerge 将它们打包到一个文件中。但这不适用于具有托管和非托管 DLL 的混合代码组件。
所以这是我想出的解决方案:
我将我想要与组件的主程序集一起部署的任何 DLL 作为嵌入式资源包含在内。 然后我设置了一个类构造函数来提取这些 DLL,如下所示。 ctor 类在每个 AppDomain 中只被调用一次,所以我认为它的开销可以忽略不计。
namespace MyLib
public class MyClass
static MyClass()
ResourceExtractor.ExtractResourceToFile("MyLib.ManagedService.dll", "managedservice.dll");
ResourceExtractor.ExtractResourceToFile("MyLib.UnmanagedService.dll", "unmanagedservice.dll");
...
在此示例中,我包含了两个 DLL 作为资源,一个是非托管代码 DLL,一个是托管代码 DLL(仅用于演示目的),以展示该技术如何适用于这两种代码。
将 DLL 提取到自己的文件中的代码很简单:
public static class ResourceExtractor
public static void ExtractResourceToFile(string resourceName, string filename)
if (!System.IO.File.Exists(filename))
using (System.IO.Stream s = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
using (System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.Create))
byte[] b = new byte[s.Length];
s.Read(b, 0, b.Length);
fs.Write(b, 0, b.Length);
使用这样的托管代码程序集与往常一样 - 几乎。您在组件的主项目(此处:MyLib)中引用它(此处:ManagedService.dll),但将 Copy Local 属性设置为 false。此外,您将程序集链接为现有项目并将构建操作设置为嵌入式资源。
对于非托管代码(此处:UnmanagedService.dll),您只需将 DLL 作为现有项链接,并将构建操作设置为嵌入式资源。要访问其功能,请照常使用 DllImport 属性,例如
[DllImport("unmanagedservice.dll")] public extern static int Add(int a, int b);
就是这样!一旦您使用静态 ctor 创建了该类的第一个实例,嵌入式 DLL 就会被提取到它们自己的文件中并准备好使用,就像您将它们部署为单独的文件一样。只要您对执行目录具有写入权限,这对您来说应该可以正常工作。至少对于原型代码,我认为这种单程序集部署方式是相当方便的。
享受吧!
http://weblogs.asp.net/ralfw/archive/2007/02/04/single-assembly-deployment-of-managed-and-unmanaged-code.aspx
【讨论】:
链接已失效。这就是为什么您应该始终 quote the most relevant parts of the linked page 而不是发布仅链接的答案。【参考方案2】:试试boxedapp;它允许从内存中加载所有 DLL。此外,您甚至可以嵌入 .net 运行时。很好地创建一个真正独立的应用程序...
【讨论】:
【参考方案3】:使用 Fody.Costura nuget
-
打开您的解决方案 -> 项目 -> 管理 Nuget 包
搜索 Fody.Costura
编译您的项目。
就是这样!
来源: http://www.manuelmeyer.net/2016/01/net-power-tip-10-merging-assemblies/
【讨论】:
【参考方案4】:您尝试过 ILMerge 吗? http://research.microsoft.com/~mbarnett/ILMerge.aspx
ILMerge 是一个实用程序,可用于将多个 .NET 程序集合并为一个程序集。它可从 Microsoft .NET Framework 开发人员中心的工具和实用程序页面免费使用。
如果您使用 /clr
标志(全部或部分 C++/CLI)构建 C++ DLL,那么它应该可以工作:
ilmerge /out:Composite.exe MyMainApp.exe Utility.dll
但是,它不适用于普通(本机)Windows DLL。
【讨论】:
很确定它需要 DLL 上的/clr:pure
或更高版本。【参考方案5】:
只需在 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/
【讨论】:
请不要多次发布完全相同的帖子,特别是如果您要发布非常老的问题。如果与上一篇文章完全相同的答案是合适的,请将问题标记为重复。如果您继续发布带有相同文本的博客链接,您可能会吸引一些垃圾邮件标记。【参考方案6】:Thinstall 是一种解决方案。对于本机 Windows 应用程序,我建议将 DLL 嵌入为二进制资源对象,然后在运行时在需要它之前将其提取出来。
【讨论】:
Thinstall 非常昂贵,并且在某些 Windows 安装和第 3 方 shell 扩展方面遇到问题。我们将它用于非 .Net 代码的成功有限,但发现 ClickOnce 和 MSI 为 .Net 安装了最好的。 如果您主要是在寻找安装,我会推荐 Inno Setup,几年前我们为此放弃了 InstallShield,并且从未回头。 innosetup.com/isinfo.php【参考方案7】:Smart Assembly 可以做到这一点,甚至更多。如果您的 dll 具有非托管代码,它不会让您将 dll 合并到单个程序集中,而是可以将所需的依赖项作为资源嵌入到您的主 exe 中。它的另一面,它不是免费的。
您可以手动执行此操作,方法是将 dll 嵌入到您的资源中,然后依赖 AppDomain 的 Assembly ResolveHandler
。当谈到混合模式 dll 时,我发现 ResolveHandler
方法的许多变体和风格对我不起作用(所有这些都将 dll 字节读取到内存并从中读取)。他们都为托管 dll 工作。这对我有用:
static void Main()
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
string assemblyName = new AssemblyName(args.Name).Name;
if (assemblyName.EndsWith(".resources"))
return null;
string dllName = assemblyName + ".dll";
string dllFullPath = Path.Combine(GetMyApplicationSpecificPath(), dllName);
using (Stream s = Assembly.GetEntryAssembly().GetManifestResourceStream(typeof(Program).Namespace + ".Resources." + dllName))
byte[] data = new byte[stream.Length];
s.Read(data, 0, data.Length);
//or just byte[] data = new BinaryReader(s).ReadBytes((int)s.Length);
File.WriteAllBytes(dllFullPath, data);
return Assembly.LoadFrom(dllFullPath);
;
这里的关键是将字节写入文件并从其位置加载。为了避免先有鸡还是先有蛋的问题,您必须确保在访问程序集之前声明处理程序,并且不要在加载(程序集解析)部分中访问程序集成员(或实例化任何必须处理程序集的东西)。还要注意确保GetMyApplicationSpecificPath()
不是任何临时目录,因为临时文件可能会被其他程序或您自己尝试擦除(并不是说它会在您的程序访问 dll 时被删除,但至少它是一个麻烦。 AppData 位置很好)。另请注意,您每次都必须写入字节,您不能从位置加载,因为 dll 已经存在于那里。
如果程序集完全不受管理,您可以查看link 或this 了解如何加载此类 dll。
【讨论】:
【参考方案8】:Xenocode 的 PostBuild 可以将托管和非托管打包成一个 exe。
【讨论】:
以上是关于c#如何合并多个dll文件的主要内容,如果未能解决你的问题,请参考以下文章