"AssemblyResolve"未被触发以解决依赖项问题

21

我一直在苦苦钻研AssenblyResolve事件。我已经搜索了stackoverflow和做了其他谷歌搜索,尝试了我认为相关的所有内容。以下链接是我认为与我的问题最接近(仅为我个人意见):

  1. AssemblyResolve未被调用并且在序列化期间引发了FileNotFoundException

  2. 在类库中处理AssemblyResolve事件的位置?

我有一个Bootstrapper类,其中有两个静态方法(出于清晰起见,我将删除我们拥有的线程安全代码):

public static void Initialize()
{
    AppDomain.CurrentDomain.AssemblyResolve += CustomResolve;
}

private static Assembly CustomResolve(object sender, ResolveEventArgs args)
{
    // There is a lot code here but basicall what it does.
    // Is determining which architecture the computer is running on and
    // extract the correct embedded dll (x86 or x64). The code was based
    // on milang on GitHub (https://github.com/milang/P4.net). And it's the same
    // purpose we want to be able to load the x86 or x64 version of the perforce dll
    // but this time with the officially Perforce supported p4api.net.
    // Once the dll is extracted we assign it to the boostrapper
    Bootstrapper._p4dnAssembly = Assembly.LoadFile(targetFileName);

    // Make sure we can satisfy the requested reference with the embedded assembly (now extracted).
    AssemblyName reference = new AssemblyName(args.Name);
    if (AssemblyName.ReferenceMatchesDefinition(reference, Bootstrapper._p4dnAssembly.GetName()))
    {
        return Bootstrapper._p4dnAssembly;
    }
}

如果我有一个带有主方法和静态构造函数的简单类,那么我就能够使代码工作。静态构造函数只是调用了Boostrapper.Initialize()方法。之后,我就可以使用我的库,它能够按照预期工作:

public static class Test
{
    static Test()
    {
        Bootstrapper.Initialize();
    }

    public static void Main()
    {
         // Using the library here is working fine. The AssemblyResolve event was
         // fired (confirmed by a breakpoint in Visual Studio)
    }
}

我的问题在于如果存在至少一个依赖层。基本上代码保持不变,但这次我的库的代码位于另一个库内:

public static class Test
{
    static Test()
    {
        Bootstrapper.Initialize();
    }

    public static void Main()
    {
        Class1 myClass = new Class1();

        // The following line is using the code of the extracted library, but
        // The AssemblyResolve event is not fired (or fired before I register the  
        // callback) and therefore the library is not found : result  
        // BadImageFormatException() error could not load libary because one
        myClass.Connect();
    }
}

听起来我之前提到的链接中的第二个解释了我的问题,但它并没有起作用。在AssemblyResove回调上,Visual Studio断点从未被触发。

有任何想法吗?

Francis

2个回答

35

我知道这个问题和答案已经过了一段时间,但我还是想就此问题发表我的看法(因为我刚刚浪费了几个小时在这上面,希望通过这篇文章,能让其他人不必再浪费时间)

问题基本上在于应用程序试图在方法的开头解析执行该方法所需的所有程序集:

static void main(string[] args)
{
    // <-- here the app tries to resolve MyAssembly
    // and as MyAssembly.Class1 is not found, the app crashes

    // this next line is never called:
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly);

    // class contained in an assemnly that we need to resolve
    MyAssembly.Class1 myClass = new MyAssembly.Class1();
}

因此,上述代码将崩溃:ResolveAssembly事件处理程序将永远不会被调用,因为它从未被挂钩。

这也是为什么下面的解决方案有效(由原帖作者发布):

static void main(string[] args)
{
    Initialize();
    RealMain();
}

static void Initialize()
{
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly);
}

static void RealMain()
{
   // <-- here the app tries to resolve MyAssembly
   // class contained in an assemnly that we need to resolve      
   MyAssembly.Class1 myClass = new MyAssembly.Class1();
   // and everything is OK
}

11

有人回答了,但答案已被删除。因此我无法将其标记为已回答。 基本上,代码不需要在“main”方法之外工作的事实正在起作用。 从新项目开始,解决问题,所以我想我可能遇到了一些dll问题(可能是x86 dll在x64文件夹中或反之亦然)。

static void main(string[] args)
{
    Boostrapper.Initialize();
    RealMain();
}

static void RealMain()
{
    Class1 myClass = new Class1();
    myClass.Connect();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接