嵌入的.dll - 装配在C#中解决 [英] Embedding .dlls - Assembly resolving in C#
问题描述
我有一个.dll我试图嵌入作为一个可执行内部的资源。下面的两个问题是有点用,但不是一个完整的帮助:
这似乎并不书面工作;不能使用args.Name作为编写的,但即使是固定的,程序仍抱怨缺少.dll文件,表明该组件未正确加载。
嵌入在编译的可执行文件的DLL
和在其中一个答案的链接:
的 http://codeblog.larsholm.net/2011/06/embed-dlls-easily-in-a-net-assembly/ 一>
但是,在我的任何形式的项目没有的App.xaml *文件 - 我不使用WPF;我使用的WinForms为我的可执行文件(变化是不是一个真正的选择,由于可执行文件的性质)。
我因此寻找一个完整的集对于一个可执行作为资源和加载,从资源.dll文件中嵌入一个类库,而不需要嵌入的资源之外的.dll文件的说明。
有关例如,这将是实际只需添加一个App.xaml中文件到的WinForms项目,或会有负面的互动,我不知道的?
谢谢
编辑:这是我目前使用的:
///<总结>
///存储需要是全球性的极少数的事情。
///< /总结>
静态类AssemblyResolver
{
///<总结>
///在启动类的静态构造函数调用。
///< /总结>
公共静态无效初始化()
{
AppDomain.CurrentDomain.AssemblyResolve + =
新ResolveEventHandler(分解);
}
///<总结>
///使用此解决组件。
///< /总结>
///< PARAM NAME =发件人>< /参数>
///< PARAM NAME =ARGS>< /参数>
///<&回报GT;< /回报>
公共静态大会解析器(对象发件人,ResolveEventArgs参数)
{
大会executingAssembly = Assembly.GetExecutingAssembly();
如果(args.Name == NULL)
抛出新的NullReferenceException(
项目名称为空,无法得到解决。
);
如果(!executingAssembly.GetManifestResourceNames()。包含(
Many_Objects_Display.Resources。+
新的AssemblyName(args.Name).Name.Replace(的.resources,.DLL ))
)
抛出新的ArgumentException(资源名称不存在)。
流resourceStream =
executingAssembly.GetManifestResourceStream(
Many_Objects_Display.Resources。+
新的AssemblyName(args.Name).Name.Replace(的.resources .DLL)
);
如果(resourceStream == NULL)
抛出新的NullReferenceException(资源流为空);
如果(resourceStream.Length> 104857600)
抛出新的ArgumentException(
好生长期资源 - 超过100 MB的中止......。
);
字节[] =块新的字节[resourceStream.Length]
resourceStream.Read(块0,block.Length);
大会resourceAssembly =的Assembly.Load(块);
如果(resourceAssembly == NULL)
抛出新的NullReferenceException(集结号是一个空值。);
返回resourceAssembly;
}
}
您需要将代码放在你的主入口点。事情是这样的:
类节目
{
静态程序()
{
AppDomain.CurrentDomain.AssemblyResolve + =新ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
静态无效的主要(字串[] args)
{
//什么在这里是一样的
}
静态System.Reflection.Assembly CurrentDomain_AssemblyResolve(对象发件人,ResolveEventArgs参数)
{
//示例代码
的其余}
}
您不能只是增加一个App.xaml文件到Windows窗体应用程序。
此外该示例代码 CurrentDomain_AssemblyResolve
是奇怪,我想尝试的这个代码第一位。我没有测试它,但它看起来更像是我以前使用的代码。
I have a .dll I'm trying to embed as a resource inside an executable. The following two questions are somewhat helpful, but are not a full help:
Embedding assemblies inside another assembly
This doesn't seem to work as written; the args.Name cannot be used as written, but even if it's fixed, the program still complains of a missing .dll, indicating that the assembly is not properly loaded.
Embedding DLLs in a compiled executable
and the link in one of the answers of:
http://codeblog.larsholm.net/2011/06/embed-dlls-easily-in-a-net-assembly/
However, there is no "App.xaml*" file in my project of any sort - I'm not using WPF; I'm using WinForms for my executable (changing isn't really an option, due to the nature of the executable).
I'm therefore looking for a complete set of instructions for embedding a class library in an executable as a resource and loading that .dll from the resource, without needing a .dll file outside of the embedded resource.
For example, would it be practical to simply add an "App.xaml" file to a WinForms project, or would there be negative interactions I'm not aware of?
Thanks.
Edit: This is what I'm currently using:
/// <summary>
/// Stores the very few things that need to be global.
/// </summary>
static class AssemblyResolver
{
/// <summary>
/// Call in the static constructor of the startup class.
/// </summary>
public static void Initialize( )
{
AppDomain.CurrentDomain.AssemblyResolve +=
new ResolveEventHandler( Resolver ) ;
}
/// <summary>
/// Use this to resolve assemblies.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
/// <returns></returns>
public static Assembly Resolver( object sender, ResolveEventArgs args )
{
Assembly executingAssembly = Assembly.GetExecutingAssembly( ) ;
if ( args.Name == null )
throw new NullReferenceException(
"Item name is null and could not be resolved."
) ;
if ( !executingAssembly.GetManifestResourceNames().Contains(
"Many_Objects_Display.Resources." +
new AssemblyName( args.Name ).Name.Replace( ".resources", ".dll" ) )
)
throw new ArgumentException( "Resource name does not exist." ) ;
Stream resourceStream =
executingAssembly.GetManifestResourceStream(
"Many_Objects_Display.Resources." +
new AssemblyName( args.Name ).Name.Replace( ".resources", ".dll" )
) ;
if ( resourceStream == null )
throw new NullReferenceException( "Resource stream is null." ) ;
if ( resourceStream.Length > 104857600)
throw new ArgumentException(
"Exceedingly long resource - greater than 100 MB. Aborting..."
) ;
byte[] block = new byte[ resourceStream.Length ] ;
resourceStream.Read( block, 0, block.Length ) ;
Assembly resourceAssembly = Assembly.Load( block ) ;
if ( resourceAssembly == null )
throw new NullReferenceException( "Assembly is a null value." ) ;
return resourceAssembly ;
}
}
You need to put the code in your main entry point. Something like this:
class Program
{
static Program()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
static void Main(string[] args)
{
// what was here is the same
}
static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
// the rest of sample code
}
}
You can't just add an App.xaml file to a windows forms application.
Also that sample code for CurrentDomain_AssemblyResolve
is bizarre, I would try this code first. I haven't tested it but it looks more like the code I've used before.
这篇关于嵌入的.dll - 装配在C#中解决的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!