将一个dll嵌入另一个作为嵌入式资源,然后从我的代码中调用它 [英] Embedding one dll inside another as an embedded resource and then calling it from my code
问题描述
这是C#和.NET 3.5。
我想这样做的方式是通过将第三方DLL作为嵌入式资源存储,然后在第一个DLL的执行期间将其放置在适当的位置。
我原本打算这样做的方式是编写代码将第三方DLL放在System.Reflection.Assembly.GetExecutingAssembly()指定的位置。Location.ToString()减去最后一个/nameOfMyAssembly.dll。我可以成功保存第三方.DLL在这个位置(最后是(C:\Documents and Settings\myUserName\Local Settings\Application Data\assembly\dl3\KXPPAX6Y.ZCY\A1MZ1499 .1TR\e0115d44\91bb86eb_fe18c901),但是当我到我的代码的一部分需要这个DLL它找不到它。
有人有任何想法关于我需要做的不同?
将第三方程序集嵌入资源后,添加代码以订阅 AppDomain.AssemblyResolve
在应用程序启动期间当前域的事件当CLR的Fusion子系统根据实际的探测(策略)找不到程序集时,会触发此事件。 AppDomain.AssemblyResolve
的事件处理程序,加载资源ce使用 Assembly.GetManifestResourceStream
,并将其内容作为字节数组提供到相应的 Assembly.Load
重载。以下是C#中的一个这样的实现方式:
AppDomain.CurrentDomain.AssemblyResolve + =(sender,args)=> ;
{
var resName = args.Name +.dll;
var thisAssembly = Assembly.GetExecutingAssembly();
使用(var input = thisAssembly.GetManifestResourceStream(resName))
{
return input!= null
? Assembly.Load(StreamToBytes(input))
:null;
}
};
其中 StreamToBytes
可以定义为: / p>
静态字节[] StreamToBytes(流输入)
{
var capacity = input.CanSeek? (int)input.Length:0;
using(var output = new MemoryStream(capacity))
{
int readLength;
var buffer = new byte [4096];
do
{
readLength = input.Read(buffer,0,buffer.Length);
output.Write(buffer,0,readLength);
}
while(readLength!= 0);
return output.ToArray();
}
}
最后,有几个已经提到, ILMerge 可能是另一个可以考虑的选择,尽管有更多的参与。
I've got a situation where I have a DLL I'm creating that uses another third party DLL, but I would prefer to be able to build the third party DLL into my DLL instead of having to keep them both together if possible.
This with is C# and .NET 3.5.
The way I would like to do this is by storing the third party DLL as an embedded resource which I then place in the appropriate place during execution of the first DLL.
The way I originally planned to do this is by writing code to put the third party DLL in the location specified by System.Reflection.Assembly.GetExecutingAssembly().Location.ToString() minus the last /nameOfMyAssembly.dll. I can successfully save the third party .DLL in this location (which ends up being (C:\Documents and Settings\myUserName\Local Settings\Application Data\assembly\dl3\KXPPAX6Y.ZCY\A1MZ1499.1TR\e0115d44\91bb86eb_fe18c901) , but when I get to the part of my code requiring this DLL it can't find it.
Does anybody have any idea as to what I need to be doing differently?
Once you've embedded the third-party assembly as a resource, add code to subscribe to the AppDomain.AssemblyResolve
event of the current domain during application start-up. This event fires whenever the Fusion sub-system of the CLR fails to locate an assembly according to the probing (policies) in effect. In the event handler for AppDomain.AssemblyResolve
, load the resource using Assembly.GetManifestResourceStream
and feed its content as a byte array into the corresponding Assembly.Load
overload. Below is how one such implementation could look like in C#:
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
var resName = args.Name + ".dll";
var thisAssembly = Assembly.GetExecutingAssembly();
using (var input = thisAssembly.GetManifestResourceStream(resName))
{
return input != null
? Assembly.Load(StreamToBytes(input))
: null;
}
};
where StreamToBytes
could be defined as:
static byte[] StreamToBytes(Stream input)
{
var capacity = input.CanSeek ? (int) input.Length : 0;
using (var output = new MemoryStream(capacity))
{
int readLength;
var buffer = new byte[4096];
do
{
readLength = input.Read(buffer, 0, buffer.Length);
output.Write(buffer, 0, readLength);
}
while (readLength != 0);
return output.ToArray();
}
}
Finally, as a few have already mentioned, ILMerge may be another option to consider, albeit somewhat more involved.
这篇关于将一个dll嵌入另一个作为嵌入式资源,然后从我的代码中调用它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!