2

我正在使用第三方程序集,不幸的是它吞下了它的异常,所以我决定使用 Mono.Cecil 重写程序集(幸运的是它不是强类型)(在对 DI 和 AOP 进行一些研究后发现了这个宝石)。我试图找到尽可能多的信息,但我仍然对 IL 的组成有一些疑问。

我已经阅读了 thisthis,所以我知道我需要做什么,但就像我说的那样,我不确定如何生成正确的 IL 来进行调用。

我已经使用 Cecil 从我正在执行简单的 try/catch 的方法中提取指令 -> 登录 Elmah -> 让异常继续,这是我需要注入的。
这是我试图复制的捕获:

catch (Exception ex)
{
   Elmah.ErrorLog.GetDefault(System.Web.HttpContext.Current)
                           .Log(new Elmah.Error(ex));

   throw;
}

这些是我使用 Cecil 获得的 catch 块指令:

IL_010d: stloc.s V_7 
IL_010f: nop 
IL_0110: call System.Web.HttpContext System.Web.HttpContext::get_Current() 
IL_0115: call Elmah.ErrorLog Elmah.ErrorLog::GetDefault(System.Web.HttpContext) 
IL_011a: ldloc.s V_7 
IL_011c: newobj System.Void Elmah.Error::.ctor(System.Exception) 
IL_0121: callvirt System.String Elmah.ErrorLog::Log(Elmah.Error) 
IL_0126: pop 
IL_0127: rethrow 
IL_0129: nop

我正在尝试使用 Cecil 复制这个块,这就是我已经走了多远:

var currentHttpContextInstruction = ilProcessor.Create(OpCodes.Call, module.Import(typeof(System.Web.HttpContext).GetProperty("Current").GetGetMethod()));
var elmahGetDefaultInstruction = ilProcessor.Create(OpCodes.Call, module.Import(typeof(Elmah.ErrorLog).GetMethod("GetDefault")));
var instantiateElmahErrorInstruction = ilProcessor.Create(OpCodes.Newobj, module.Import(typeof(Elmah.Error).GetConstructor(new[] { typeof(System.Exception) })));
var elmahErrorLogInstruction = ilProcessor.Create(OpCodes.Callvirt, module.Import(typeof(Elmah.ErrorLog).GetMethod("Log")));
var rethrowInstruction = ilProcessor.Create(OpCodes.Rethrow);

我不太确定的是如何正确复制剩余的指令......
我是否只是创建一个new VariableDefinition,将其添加到method.Body.Variables然后对该变量执行stlocand操作?和命令呢ldloc?我需要担心这个问题中提出的问题吗?noppop

任何有关如何以正确方式执行此操作的指导将不胜感激!

请注意,我已经查看了命令的含义,所以我的问题不在于它们的含义。

4

0 回答 0