如何提供一个备用程序集,而不是无法加载的程序集?

7
在运行时,如果一个引用的程序集因为测试签名而无法加载,比如出现“强名称验证失败”的情况,是否有办法从另一个真实签名的路径提供替代程序集?
我尝试订阅AppDomain.CurrentDomain.AssemblyResolve事件,但它没有被触发,因为“坏”程序集在技术上存在,只是不能加载。
是否有一种通用的方法来提供备用程序集,当无法加载程序集时?

当尝试加载程序集时,你能否尝试捕获 SecurityException? - Michael Todd
我尝试过了,但是我不知道接下来该怎么做... 我仍然需要以某种方式告诉CLR程序集加载器在加载我的程序集时选择正确的依赖项... - Kirill Osenkov
1
尝试在应用程序启动时显式加载程序集并处理异常怎么样?我有点假设您的程序集会自动加载。 - Rashack
是的,但即使我处理了异常,我如何仍然获取正确的版本来加载呢?它是静态链接的。嗯,也许我应该在正确的版本上调用Assembly.Load? - Kirill Osenkov
1
你可能需要处理发布者策略文件...我从未这样做过,所以我不会将其作为答案。 - Richard Anthony Freeman-Hein
4个回答

1

是什么触发了加载尝试?也就是说,您是否调用了Assembly.Load或者这是类型解析尝试的结果?如果是后者,您可以尝试使用AppDomain TypeResolve事件进行操作;如果是前者,则可以在对Assembly.Load的调用中添加额外的逻辑。

但是,如果您手动加载程序集,请确保使用Assembly.Load而不是Assembly.LoadFrom。根据程序集加载到哪个上下文中,类型解析存在微妙的差异。


我不使用Assembly.Load - 相关的程序集由编译器链接。每当我开始使用该程序集时,我调用typeof(TypeInAssembly).GetTypes() - 这将加载第一个程序集,并递归地加载它的未签名引用程序集。TypeResolve也没有被触发 :(还是谢谢。 - Kirill Osenkov

1

谢谢。我刚试了一下,虽然我指向了正确的程序集,但它仍然给我同样的“强名称验证失败”的错误:var assemblyName = AssemblyName.GetAssemblyName(correctFileName); var assembly = Assembly.Load(assemblyName);我想这是因为 correctFileName 在应用程序 CodeBase 文件夹之外。我想我只能放弃这个方法,走另一条路了... - Kirill Osenkov
使用loadfrom方法,您可以传递文件路径并从任何地方(几乎)加载程序集。 - Aaron Fischer
是的,LoadFrom 似乎让我解决了这个问题。后来我遇到了其他问题,所以我放弃了整个方法,但是是的,这个问题已经解决了。预加载程序集而不是响应加载失败。谢谢! - Kirill Osenkov

0

如果应用程序无法找到程序集,有一种标准的方法来查找:

// register on assembly resolve exception
AppDomain.CurrentDomain.AssemblyResolve += ResolveEventHandler;

// try to load the assembly yourself
private static Assembly ResolveEventHandler(object sender, ResolveEventArgs args)
{
    return Assembly.Load(some_location);
}

0

看起来我想要的是不可能的。我决定走另一条路。我们将不得不修改构建系统,在编译时有条件地链接到签名二进制文件,而不是测试签名二进制文件。

还是谢谢大家的建议!


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