8

我什至不确定这是否可能,如果没有,我深表歉意。我用谷歌搜索了很多,没有找到我要找的东西。

基本上,我们有一个由第三方制作的应用程序,说白了就是垃圾。我们有一个特定的问题,并且已经设法使用 ILSpy 将问题追溯到 DLL 中的一个方法。显然,我们没有(也无法获得)源代码,而相关公司也不愿意在任何合理的时间范围内解决问题。

因此,我们调查了各种调查途径,但一无所获。我一直在研究这是否可以使用反射来完成,这几乎是我们让它发挥作用的最后希望。简而言之,我想做的是以下几点:

  • 创建一个与现有 DLL 同名的简单类库
  • 使用反射从现有的 DLL 中导入方法
  • 不知何故,用我自己的正确代码覆盖了有问题的方法
  • 重建代码,所以我有一个新的 DLL,它包含现有 DLL 的 99% 的功能,但我的覆盖代码提供了正确的功能。

我在调查期间发现了 TypeBuilder.DefineMethodOverride 以及 StackOverflow 的一个页面,它看起来很相似,但并不完全符合我的要求。

http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.definemethodoverride.aspx

有没有办法用反射“覆盖”一个方法?

任何建议表示赞赏!

安德鲁

编辑

我的另一个可能的想法是生成一个包含覆盖函数的部分类,但这似乎也不可行。

4

4 回答 4

6

仅当方法是虚拟的时,您才能覆盖该方法,无论您是通过反射还是静态方法都无关紧要。我建议使用反编译器(有很多免费的可用)并修复 MSIL 中的代码。然后,您可以从 MSIL 生成新程序集。

于 2013-06-18T14:00:27.307 回答
0

根据您的描述,我建议修改原始程序集。该过程本质上是

  • 将程序集反编译为 MSIL、C# 或您选择的任何语言
  • 修改反编译的程序集以包含您的更改
  • 使用修改后的源重新编译程序集

从我所看到的 Reflexil可以让您做到这一点,尽管它可能需要您购买 Resharper(我自己没有尝试过)

或者,您可以使用ILDasm将整个程序集反编译为单个文件,修改该文件,然后使用ILAsm重新编译它

于 2013-06-18T14:44:58.267 回答
0

我知道我来晚了,但我同意 Charleh 的观点;如果您有一个表现不佳且不利于替换的类,但至少将其方法声明为virtual,那么您很幸运。以下使用对Castle.Coreand的引用Patterns

var interceptor = new DelegateInterceptor(proceed: call => 
{
  if(ShouldCallProceed(call)) call.Proceed();
  else AlternativeLogic();
});

var generator = new ProxyGenerator();
var proxy = generator.CreateClassProxy<UncooperativeType>(interceptor);

proxy.RubbishMethod();

我还冒昧地在 LinqPad中提供了一个运行示例。virtual它显示了允许拦截的方法(一个)和不允许拦截的方法之间的区别。它还展示了一种无需使用Try.Dofrom的所有代码即可捕获异常的有用方法Patterns

于 2013-12-08T02:16:08.933 回答
0

我认为你的第一个想法是好的。如果第三方类不是sealed,您可以从它派生,并添加您自己的方法,使用不同的名称,以纠正错误的行为。如果您需要它在 1 个 dll 中,您可以使用IlMerge

如果您的第三方类是密封的,您可以在新类中拥有这个第三方类的实例,并在需要时调用这些方法。

但是你必须检查你想要“覆盖”的方法没有在那个库中被调用,因为如果是这个解决方案将不起作用......

它不是很干净,但在编辑库的公司修复问题期间,它可能是一个临时解决方案。

当它修复后,您只需重命名您使用的方法,因此不会很耗时。

于 2013-06-18T14:36:17.827 回答