zoukankan      html  css  js  c++  java
  • 编译时MSIL注入实践Mono Cecil(1)

       紧接上两篇浅谈.NET编译时注入(C#-->IL)浅谈VS编译自定义编译任务—MSBuild Task(csproject),在第一篇中我们简单研究了c#语法糖和PostSharp的MSIl注入,紧接第二篇中我们介绍了自定义MSBuild编译任务(记得有位老兄发链接用 MSBuild自动发布Silverlight xap ,我想说的我做的是自定义编译任务,不是什么发布,MSBuild本就是一个发布工具)。之所以在此前介绍编译Task是因为我讲介绍的就是利用MSBuild和MSILInject制作静态注入式AOP,想成熟的产品PostSharp,当然我也不会去重造轮子,但需要明白起原理和自动化注入时机。废话不多说,今天将请出我们的MSIL注入的好东西:Mono.Cecil.官方网站http://www.mono-project.com/Cecil,他是一个强大的MSIL 注入工具,在我们的Reflector插件Reflexil(动态修改程序集插件,很好用,我已经尝试多次)就有他的身影出现。还有如大名鼎鼎的SharpDevelopLINQPadJa.NET等等(可以参见https://github.com/jbevain/cecil/wiki/Users)。

          在本节我们需要看看这个Mono.Cecil,先来一个简单的认识。

    我来在我们的方法执行前后加入我们的输出信息:

    原来代码:

    class Program 
       { 
           
    static void Main(string[] args) 
           { 
               Console.WriteLine(
    "破浪Blog:http://www.cnblogs.com/whitewolf/"); 
           } 
       }

    任务:

    1我将在方法执行前后添加一个Console.WriteLine("Method start…");

    2方法最后添加Console.WriteLine("Method finish…“);

    具体Mono.Cecil Code:

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using Mono.Cecil; 
    using Mono.Cecil.Cil; 

    namespace BlogSample 

        
    class Program 
        { 
            
    static void Main(string[] args) 
            { 
                AssemblyDefinition assembiy 
    = AssemblyFactory.GetAssembly(args[0]); 
                
    foreach (Mono.Cecil.TypeDefinition item in assembiy.MainModule.Types) 
                { 
                    
    foreach (MethodDefinition method in item.Methods) 
                    { 
                        
    if (method.Name.Equals("Main")) 
                        { 

                            var ins 
    = method.Body.Instructions[0]; 
                            var worker 
    = method.Body.CilWorker; 
                            worker.InsertBefore(ins, worker.Create(OpCodes.Ldstr, 
    "Method start…")); 
                            worker.InsertBefore(ins, worker.Create(OpCodes.Call, 
                                assembiy.MainModule.Import(
    typeof(Console).GetMethod("WriteLine"new Type[] { typeof(string) })))); 
                            ins 
    = method.Body.Instructions[method.Body.Instructions.Count - 1]; 

                            worker.InsertBefore(ins, worker.Create(OpCodes.Ldstr, 
    "Method finish…")); 
                            worker.InsertBefore(ins, worker.Create(OpCodes.Call, 
                                assembiy.MainModule.Import(
    typeof(Console).GetMethod("WriteLine"new Type[] { typeof(string) })))); 
                            
    break
                        } 
                    } 

                } 

                AssemblyFactory.SaveAssembly(assembiy, 
    "IL_" + args[0]); 
                Console.Read(); 
            } 
        } 
    }

    DOS运行结果:

    无标题

    我们在来看看反编译后的MSIL

    image

    C#:

    image

        在这最后我们可以想一下,如果我们利用Mono.Cecil可以干些什么事情,能做的当然很多,我首先想尝试的了与上一节浅谈VS编译自定义编译任务—MSBuild Task(csproject)结合PostSharp一样的静态注入AOP框架。还能做什么的就要靠大家发挥大家聪明的才智。


    作者:破  狼
    出处:http://www.cnblogs.com/whitewolf/
    本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-个人独立博客博客园--破狼51CTO--破狼

  • 相关阅读:
    android入门教程(十六)之 使用Intent传递数据
    Android入门教程(十八)之ListView (二) (转)
    Android入门教程(十四)之ListView的应用 (转)
    Android入门教程(十七)之GridView(转自http://blog.csdn.net/hellogv/)
    (原创)Android入门教程(十五)之 Activity生命周期及其配置使用
    Android入门教程(十九)之ListView (三) (转)
    Android入门教程(十三)之自定义下拉菜单模式Spinner与setDropDownViewResource的应用(转)
    Android入门教程(十)之Menu功能菜单设计 (转)
    [vp]ARC059
    欧拉路学习笔记
  • 原文地址:https://www.cnblogs.com/whitewolf/p/2119969.html
Copyright © 2011-2022 走看看