Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中嵌入.dll-程序集解析#_C#_Dll_Embedded Resource - Fatal编程技术网

C# 在C中嵌入.dll-程序集解析#

C# 在C中嵌入.dll-程序集解析#,c#,dll,embedded-resource,C#,Dll,Embedded Resource,我有一个.dll,我正试图将其作为资源嵌入到可执行文件中。以下两个问题有些帮助,但不是完全的帮助: 这似乎不像写的那样有效;args.Name不能作为书面形式使用,但即使它已修复,程序仍会抱怨缺少.dll,这表明程序集未正确加载 以及以下答案之一中的链接: 然而,在我的项目中没有任何类型的“App.xaml*”文件——我没有使用WPF;我正在为我的可执行文件使用WinForms(由于可执行文件的性质,更改实际上不是一个选项) 因此,我正在寻找一套完整的指令,用于将类库作为资源嵌入到可执行文

我有一个.dll,我正试图将其作为资源嵌入到可执行文件中。以下两个问题有些帮助,但不是完全的帮助:

这似乎不像写的那样有效;args.Name不能作为书面形式使用,但即使它已修复,程序仍会抱怨缺少.dll,这表明程序集未正确加载

以及以下答案之一中的链接:

然而,在我的项目中没有任何类型的“App.xaml*”文件——我没有使用WPF;我正在为我的可执行文件使用WinForms(由于可执行文件的性质,更改实际上不是一个选项)

因此,我正在寻找一套完整的指令,用于将类库作为资源嵌入到可执行文件中,并从资源中加载该.dll,而不需要嵌入资源之外的.dll文件

例如,简单地将“App.xaml”文件添加到WinForms项目中是否可行,或者是否存在我不知道的负面交互

谢谢

编辑:这是我目前正在使用的:

/// <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 ;
    }
}
//
///存储极少数需要全球化的东西。
/// 
静态类汇编解析器
{
/// 
///调用启动类的静态构造函数。
/// 
公共静态无效初始化()
{
AppDomain.CurrentDomain.AssemblyResolve+=
新的ResolveEventHandler(解析器);
}
/// 
///使用此选项可解析程序集。
/// 
/// 
/// 
/// 
公共静态程序集解析器(对象发送器、ResolveEventArgs args args)
{
Assembly executingAssembly=Assembly.GetExecutingAssembly();
if(args.Name==null)
抛出新的NullReferenceException(
“项目名称为null,无法解析。”
) ;
如果(!ExecutionGassembly.GetManifestResourceNames()包含(
“显示许多对象。资源。”+
新的AssemblyName(args.Name).Name.Replace(“.resources”,“.dll”))
)
抛出新ArgumentException(“资源名称不存在”);
溪流资源溪流=
ExecutiveGassembly.GetManifestResourceStream(
“显示许多对象。资源。”+
新的AssemblyName(args.Name).Name.Replace(“.resources”,“.dll”)
) ;
if(resourceStream==null)
抛出新的NullReferenceException(“资源流为null”);
如果(resourceStream.Length>104857600)
抛出新的ArgumentException(
“资源过长-超过100 MB。正在中止…”
) ;
字节[]块=新字节[resourceStream.Length];
resourceStream.Read(block,0,block.Length);
Assembly resourceAssembly=Assembly.Load(块);
if(resourceAssembly==null)
抛出新的NullReferenceException(“程序集是空值。”);
返回集合;
}
}

您需要将代码放入主入口点。大概是这样的:

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
  }

}
不能只将App.xaml文件添加到windows窗体应用程序


另外,
CurrentDomain_AssemblyResolve
的示例代码也很奇怪,我会先尝试代码。我没有测试过它,但它看起来更像我以前使用过的代码。

我也这么认为;所以我问。此外,除了将代码放入helper类之外,这正是我所做的。@NarftheMouse这也很有效。在运行时尝试加载程序集之前,您只需确保订阅了
AssemblyResolve
事件;实际上,它似乎是在调用Pogram.Program()之前完成的。或者我应该从引用中卸载.dll吗?@NarftheMouse所说的“你的”程序集我指的是你嵌入的任何程序集。显然,运行时必须在该类的静态构造函数运行之前加载入口点程序集,但是在我的示例中,静态构造函数应该在
Main
中的任何代码之前运行。我完全理解这一点。以下是顺序:我将解析器添加到AppDomain.CurrentDomain.AssemblyResolve eventhandler。我通过调试来测试它;所有已启动的解析程序调用均已成功完成,且程序集为非空。我将编译后的可执行文件(而不是.dll)复制到另一个目录中(可执行文件和.dll是唯一的内容)。然后运行可执行文件。它没有成功启动。唯一的区别是缺少.dll文件。我将把AssemblyResolver类添加到我的问题中。