.net里怎樣在Main方法之前執行代碼?


  眾說周知,Main方法是.net程序的入口,那有什么方法可以在Main方法之前執行代碼呢?研究過.net的高人也許已經知道了方法。

  為什么在.net中Main方法是程序入口呢?那么Main方法和其他非Main的方法有什么差異呢?看下面代碼:

public class Program
{
    static void Main()
    {
        Console.WriteLine("Main");
    }
    static void OtherMain()
    {
        Console.WriteLine("OtherMain");
    }
}

  Main()和OtherMain()方法就是輸出的東西不一樣,那我們再看一看兩都的IL代碼吧::

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  // 代碼大小       13 (0xd)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "Main"
  IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000b:  nop
  IL_000c:  ret
} // end of method Program::Main
.method private hidebysig static void  OtherMain() cil managed
{
  // 代碼大小       13 (0xd)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "OtherMain"
  IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000b:  nop
  IL_000c:  ret
} // end of method Program::OtherMain

  從兩者的比較我們可以看出Main方法生成的IL代碼多了一條“.entrypoint”的指令,.entrypoint”什么意思?隨便一看就知道是“進入點”,就是程序入口的意思了,而且一個程序(exe,非dll,dll是沒有的)只能找到一個.entrypoint”,不信你可以找找。要在Main方法之前執行代碼我們只要如下代碼的樣子,把入口改為OtherMain即可:

public class Program
{
    static void Main()
    {
        Console.WriteLine("Main");
    }
    static void OtherMain()
    {
        Console.WriteLine("OtherMain");
        Main();
    }
}

  編譯,再用強大的反匯編程序——IL 反匯編程序打開編譯好的exe文件,點擊菜單文件》轉儲。保存后再用文件編輯工具打開(如notepad),將“.entrypoint”移動到OtherMain()的下面,保存,結果如下。

  .method private hidebysig static void  OtherMain() cil managed
  {
    .entrypoint
    // 代碼大小       19 (0x13)
    .maxstack  8
    IL_0000:  nop
    IL_0001:  ldstr      "OtherMain"
    IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_000b:  nop
    IL_000c:  call       void Test.Program::Main()
    IL_0011:  nop
    IL_0012:  ret
  } // end of method Program::OtherMain

  用ilasm編譯修改好的文件,生成exe,再運行。看看結束是什么,是不是在輸出“Main”之前輸出了“OtherMain"。如果是,那恭喜你,程序入口修改成功!大家可以動手試試。

  如果你覺得這種方法太麻煩了,那有個簡單的方法。知道類型構造器(又稱靜態構造方法)嗎?不知道?那先知道什么是類型構造器再看下面的。

  類型構造器會在類第一次被使用的初始化類,在類的其他代碼被執行前執行。想要在Main方法之前執行代碼只要在包含Main方法的類里加一個類型構造器不就可以了:

public class Program
{
    static Program()
    {
        Console.WriteLine("我執行了,Main方法還沒執行哦!");
    }
    static void Main()
    {
        Console.WriteLine("Main");
    }
}

  因為Main方法也是一個類的靜態方法,也會符合CLR規范的。如果在類型構造器拋出一個異常,你知道會發生什么嗎?

  如果高人還知道其他方法,可以在評論中留言。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM