Meh*_*med 14 c# embed dll itextsharp
我正在使用一个使用iTextSharp.dll和WebCam_Capture.dll的C#程序.当我构建程序时,它会在调试文件夹中创建可执行文件,并且它还会按预期将这两个dll复制到调试文件夹中.我想将它们合并为一个可执行文件,但是我失败了.这两个库在解决方案资源管理器中的引用中可见.我还将它们添加为资源.可执行文件大小变得更大,等于三个文件的总和,但是可执行文件仍然需要在其目录中使用这些库...我使用资源文件的"构建操作"属性但没有更改.我也试过ILmerge,但它给了我一个错误.所以我该怎么做?
更新:这是我从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)
Run Code Online (Sandbox Code Playgroud)
顺便说一句,这只是一个Windows应用程序,一个表格将被填写并打印为pdf,并通过网络摄像头拍照(如果有的话).谢谢大家!
您可以使用ILMerge将多个程序集合并在一起.你已经说过你这么做了,而且你收到了一个错误.虽然我不知道为什么,但您可以使用另一种选择:如果库是开源的(并且它们的许可证与您的许可证兼容),您可以下载源代码,将其添加到项目中并进行编译.这将导致单个组件.
ILMerge页面还列出了Jeffrey Richter的博客作为解决问题的另一种方法:
许多应用程序由依赖于许多DLL文件的EXE文件组成.部署此应用程序时,必须部署所有文件.但是,有一种技术可用于部署单个EXE文件.首先,确定您的EXE文件所依赖的所有DLL文件,这些文件不作为Microsoft .NET Framework本身的一部分提供.然后将这些DLL添加到Visual Studio项目中.对于您添加的每个DLL文件,显示其属性并将其"构建操作"更改为"嵌入式资源".这会导致C#编译器将DLL文件嵌入到EXE文件中,您可以部署此一个EXE文件.
在运行时,CLR将无法找到依赖的DLL程序集,这是一个问题.要解决此问题,请在应用程序初始化时,使用AppDomain的ResolveAssembly事件注册回调方法.代码看起来应该是这样的:
Run Code Online (Sandbox Code Playgroud)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 []为参数.
这是代码:
using System;
using System.Collections.Generic;
using System.Reflection;
using System.IO;
namespace WindowsForm
{
public partial class Form1 : Form
{
Dictionary<string, Assembly> _libs = new Dictionary<string, Assembly>();
public Form1()
{
InitializeComponent();
AppDomain.CurrentDomain.AssemblyResolve += FindDLL;
}
private Assembly FindDLL(object sender, ResolveEventArgs args)
{
string keyName = new AssemblyName(args.Name).Name;
// If DLL is loaded then don't load it again just return
if (_libs.ContainsKey(keyName)) return _libs[keyName];
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("YourNamespaceGoesHere." + keyName + ".dll")) // <-- To find out the Namespace name go to Your Project >> Properties >> Application >> Default namespace
{
byte[] buffer = new BinaryReader(stream).ReadBytes((int)stream.Length);
Assembly assembly = Assembly.Load(buffer);
_libs[keyName] = assembly;
return assembly;
}
}
//
// Your Methods here
//
}
}
Run Code Online (Sandbox Code Playgroud)
希望它有所帮助,巴勃罗
查看应用程序域上的AssemblyResolve事件。
我没有示例,但您基本上可以检查所要求的内容并流回资源 DLL。我相信LinqPAD做得很好 - 你可以看看 Joseph Albahari 使用反编译器等的实现。
| 归档时间: |
|
| 查看次数: |
35166 次 |
| 最近记录: |