C# 如何使用Mono.Cecil在注入的try-catch处理程序中多次访问异常变量?

C# 如何使用Mono.Cecil在注入的try-catch处理程序中多次访问异常变量?,c#,mono.cecil,C#,Mono.cecil,我使用Mono.Cecil在方法体周围添加了一个try-catch块 一切进展顺利,甚至我可以在catch块中调用带有catch exception1参数的方法,因为exception1值似乎位于堆栈顶部 但是,在调用之后,该值将从堆栈中删除,如果我想调用另一个方法,并将exception1作为参数,那么我无法在调用之前找出如何通过ldloc访问它 因此,下面的代码正在运行,我只是不知道如何在catch块中调用另一个方法,并将捕获的异常值作为参数 var statementInTheCatchB

我使用Mono.Cecil在方法体周围添加了一个try-catch块

一切进展顺利,甚至我可以在catch块中调用带有catch exception1参数的方法,因为exception1值似乎位于堆栈顶部

但是,在调用之后,该值将从堆栈中删除,如果我想调用另一个方法,并将exception1作为参数,那么我无法在调用之前找出如何通过ldloc访问它

因此,下面的代码正在运行,我只是不知道如何在catch块中调用另一个方法,并将捕获的异常值作为参数

var statementInTheCatchBlock = il.Create(OpCodes.Call, module.Import(typeof(AnyType).GetMethod("AnyMethod", new[] { typeof(Exception) })));
var ret = il.Create(OpCodes.Ret);
var leave = il.Create(OpCodes.Leave, ret);

il.InsertAfter(method.Body.Instructions.Last(), statementInTheCatchBlock);
il.InsertAfter(statementInTheCatchBlock, leave);
il.InsertAfter(leave, ret);

var handler = new ExceptionHandler(ExceptionHandlerType.Catch)
{
    TryStart = method.Body.Instructions.First(),
    TryEnd = statementInTheCatchBlock,
    HandlerStart = statementInTheCatchBlock,
    HandlerEnd = ret,
    CatchType = module.Import(typeof(Exception)),
};
method.Body.ExceptionHandlers.Add(handler);

Thx提前

我终于找到了答案。 关键是定义自己的变量,在catch块的第一条指令中,将eval堆栈的顶部存储在此变量中:

var exceptionVariable = new VariableDefinition("e", method.Module.Import(typeof (Exception)));
method.Body.Variables.Add(exceptionVariable);

var last = method.Body.Instructions.Last();
Instruction tryEnd;
il.InsertAfter(last, tryEnd = last = il.Create(OpCodes.Stloc_S, exceptionVariable));
il.InsertAfter(last, last = il.Create(OpCodes.Ldloc_S, exceptionVariable));
il.InsertAfter(last, last = anyCallInstructionWithExceptionParamter);
il.InsertAfter(last, last = il.Create(OpCodes.Ldloc_S, exceptionVariable));
il.InsertAfter(last, last = otherCallInstructionWithExceptionParamter);
il.InsertAfter(last, last = leave);
il.InsertAfter(last, ret);

var handler = new ExceptionHandler(ExceptionHandlerType.Catch)
{
    TryStart = method.Body.Instructions.First(),
    TryEnd = tryEnd,
    HandlerStart = tryEnd,
    HandlerEnd = ret,
    CatchType = module.Import(typeof (Exception)),
};
感谢所有花时间在这件事上的人(对我来说是3个小时:-()