0

我正在按照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;          
}
4

1 回答 1

1

术语“程序集”不仅仅指任何 DLL;这意味着使用 .NET 和为 .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。

于 2012-10-28T21:46:56.927 回答