嵌入的.dll - 装配在C#中解决 [英] Embedding .dlls - Assembly resolving in C#

查看:195
本文介绍了嵌入的.dll - 装配在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屋!

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