使用assemblyresolve处理C#中缺少的程序集

时间:2012-10-28 21:19:48

标签: c# interop assemblyresolve

我在http://support.microsoft.com/kb/837908中按照方法3在C#中动态加载程序集。但是,代码对我不起作用。在代码的以下部分中,仅当缺少程序集的名称是应用程序引用的程序集之一时,作者才会加载缺少的程序集。

当我在调试下运行它时,函数被调用,但缺少的程序集不在任何引用的程序集中,因此在我的情况下没有设置。任何想法为什么会这样?我不确定该DLL是C#还是本机C ++。这可能是因为C ++ dll无法以这种方式加载吗?那么,为什么要为缺少的C ++程序集调用此函数?任何解释都表示赞赏。如果这不适用于从C#引用的C ++程序集,那么还有什么选择呢?

private Assembly MyResolveEventHandler(object sender,ResolveEventArgs args)
{
    //This handler is called only when the common language runtime tries to bind to the assembly and fails.

    //Retrieve the list of referenced assemblies in an array of AssemblyName.
    Assembly MyAssembly,objExecutingAssemblies;
    string strTempAssmbPath="";

    objExecutingAssemblies=Assembly.GetExecutingAssembly();
    AssemblyName [] arrReferencedAssmbNames=objExecutingAssemblies.GetReferencedAssemblies();

    //Loop through the array of referenced assembly names.
    foreach(AssemblyName strAssmbName in arrReferencedAssmbNames)
    {
        //Check for the assembly names that have raised the "AssemblyResolve" event.
        if(strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(","))==args.Name.Substring(0, args.Name.IndexOf(",")))
        {
            //Build the path of the assembly from where it has to be loaded.                
            strTempAssmbPath="C:\\Myassemblies\\"+args.Name.Substring(0,args.Name.IndexOf(","))+".dll";
            break;
        }

    }
    //Load the assembly from the specified path.                    
    MyAssembly = Assembly.LoadFrom(strTempAssmbPath);                   

    //Return the loaded assembly.
    return MyAssembly;          
}

1 个答案:

答案 0 :(得分:1)

术语“汇编”并不仅仅意味着任何DLL;它表示用.NET创建的DLL。它通常也被称为“托管代码”,大致意味着您使用.NET垃圾收集器而不是传统的C ++堆来管理内存。 (我正在简化。还有“混合模式程序集”,它们可以通过这种方式解决,尽管它们使用托管和非托管代码的混合。而“托管”意味着不仅仅是内存管理。)

引用的程序集是用C ++ / CLI编写还是用C#编写并不重要。 C ++ / CLI经常与C ++混淆,但它实际上是另一种具有额外功能的语言,可以利用托管环境。如果使用/clr开关编译C ++'ish,那就是C ++ / CLI而不是C ++。

您需要了解引用的知识库文章有三个问题。

  1. 本文中的“方法3”未考虑间接引用的程序集。也就是说,从主程序集引用的程序集引用的程序集。这可能是你现在正在咬你的。

  2. 文章没有提到,在注册处理程序的方法体中尽可能少地执行操作至关重要,否则抖动将在处理程序之前解析某些程序集已注册 - 即使负责的代码行在同一方法的注册之下。这是因为JIT编译先于执行。

  3. 如果您处理C ++ / CLI代码,可能还需要加载一些前者链接的非托管C ++ DLL。它使用传统的Windows DLL搜索顺序和解析器外部完成。但只要您看到为特定DLL输入的处理程序,这不是您的问题。根本不会在处理程序中看到与.NET无关的正常类型的C或C ++ DLL。