在 Visual C# 2010 中将 DLL 嵌入到 .exe 中 [英] Embedding DLL's into .exe in in Visual C# 2010

查看:29
本文介绍了在 Visual C# 2010 中将 DLL 嵌入到 .exe 中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个使用 iTextSharp.dll 和 WebCam_Capture.dll 的 C# 程序.当我构建程序时,它会在调试文件夹中创建可执行文件,并且还会按预期将这两个 dll 复制到调试文件夹.我想将它们合并为一个可执行文件,但是我失败了.这两个库通常在解决方案资源管理器的引用中可见.我也将它们添加为资源.可执行文件的大小变得更大,等于三个文件的总和,但是可执行文件仍然需要在其目录中使用这些库......我使用了资源文件的构建操作"属性,但没有任何变化.我也试过 ILmerge 但它给了我一个错误.那我该怎么办?

I'm working on a C# program that uses iTextSharp.dll and WebCam_Capture.dll. When I build the program, it creates executable in the debug folder and it also copies these two dll's to the debug folder as expected. I want to merge them into a single executable, however I failed. These two libraries are visible in the references normally in the solution explorer. I also add them as resources. Executable size got bigger which equals the sum of three files, nevertheless the executable still requires these libraries in its directory... I played with "build action" property of the resource files but no change. I also tried ILmerge but it gave me an error. so what should I do?

更新:这是我从 ILmerge 得到的:

Update: This is what I get from ILmerge:

An exception occurred during merging:
Unresolved assembly reference not allowed: System.Core.
at System.Compiler.Ir2md.GetAssemblyRefIndex(AssemblyNode assembly)
   at System.Compiler.Ir2md.GetTypeRefIndex(TypeNode type)

顺便说一下,它只是一个 Windows 应用程序,一个需要填写并打印为 pdf 的表格,如果有的话,还可以通过网络摄像头拍摄一张照片.谢谢大家!

It is just a windows application by the way, a form to be filled and printed as pdf with a photo taken via webcam if available. Thanks all!

推荐答案

您可以使用 ILMerge 将多个程序集合并在一起.你已经说过你这样做了,但你收到了一个错误.虽然我不知道为什么,但您可以使用替代方法:如果库是开源的(并且它们的许可证与您的兼容),您可以下载源代码,将其添加到您的项目中并进行编译.这将导致单个程序集.

You can use ILMerge to merge multiple assemblies together. You've already said you did this, and you've received an error. Though I don't know why, you can use an alternative: if the libraries are open source (and their licenses are compatible with yours), you can download the source code, add it to your project and compile. This will result in a single assembly.

ILMerge 页面还列出了 Jeffrey Richter 的博客 作为解决您问题的另一种选择:

The ILMerge page also lists Jeffrey Richter's blog as yet another alternative to solve your issue:

许多应用程序由依赖于许多 DLL 的 EXE 文件组成文件.部署此应用程序时,所有文件必须部署.但是,您可以使用一种技术来部署只是一个EXE文件.首先,确定您的所有 DLL 文件EXE 文件取决于不作为 Microsoft .NET 的一部分提供的文件框架本身.然后将这些 DLL 添加到您的 Visual Studio 项目中.对于您添加的每个 DLL 文件,显示其属性并更改其构建操作"到嵌入式资源".这会导致 C# 编译器将 DLL 文件嵌入到您的 EXE 文件中,然后您就可以部署这个文件了EXE 文件.

Many applications consist of an EXE file that depends on many DLL files. When deploying this application, all the files must be deployed. However, there is a technique that you can use to deploy just a single EXE file. First, identify all the DLL files that your EXE file depends on that do not ship as part of the Microsoft .NET Framework itself. Then add these DLLs to your Visual Studio project. For each DLL file you add, display its properties and change its "Build Action" to "Embedded Resource." This causes the C# compiler to embed the DLL file(s) into your EXE file, and you can deploy this one EXE file.

在运行时,CLR 将无法找到依赖的 DLL程序集,这是一个问题.要解决此问题,当您的应用程序初始化,注册一个回调方法到 AppDomain 的ResolveAssembly 事件.代码应如下所示:

At runtime, the CLR won’t be able to find the dependent DLL assemblies, which is a problem. To fix this, when your application initializes, register a callback method with the AppDomain’s ResolveAssembly event. The code should look something like this:

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { 
   String resourceName = "AssemblyLoadingAndReflection." + 
       new AssemblyName(args.Name).Name + ".dll"; 
   using (var stream = Assembly.GetExecutingAssembly()
                               .GetManifestResourceStream(resourceName)) { 
      Byte[] assemblyData = new Byte[stream.Length]; 
      stream.Read(assemblyData, 0, assemblyData.Length); 
      return Assembly.Load(assemblyData); 
   }   
}; 

现在,线程第一次调用引用类型的方法一个依赖的 DLL 文件,AssemblyResolve 事件将被引发,并且上面显示的回调代码将找到所需的嵌入式 DLL 资源并通过调用 Assembly 的 Load 方法的重载来加载它接受一个 Byte[] 作为参数.

Now, the first time a thread calls a method that references a type in a dependent DLL file, the AssemblyResolve event will be raised and the callback code shown above will find the embedded DLL resource desired and load it by calling an overload of Assembly’s Load method that takes a Byte[] as an argument.

这篇关于在 Visual C# 2010 中将 DLL 嵌入到 .exe 中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆