一个程序集入口点的信息在程序集中的哪里编写?

3

我曾经认为一个程序集只能有一个main()方法,直到我在Jon Skeet在哥本哈根微软办公室发表的视频讲座中看到了MiscUtil。

于是,我写了这个小应用程序,并添加了两个main()方法:

namespace ManyMains
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
            Console.ReadKey();
        }
    }

    class YetAnotherProgram
    {
        static void Main()
        {
            Console.WriteLine("Yet another program.");
            Console.ReadKey();
        }
    }
}

我在Visual Studio中设置了StartUp对象,并且它可以正常工作,这很好,没有什么需要担心的。接着,我想知道这些信息具体存储在程序集中哪里,于是我用反编译工具打开了已编译的二进制文件,但是没有看到任何有关该信息的元数据。
我在想是否这种信息写在了清单或PE镜像的一些COFF头中,这些信息在反汇编器中无法看到,但是可以在十六进制编辑器中看到?
3个回答

6

我刚刚在IL反汇编器中打开了一个可执行文件。请注意Main方法的.entrypoint行。

(说明:.entrypoint是指定程序集入口点的指令,Main方法是C#程序的入口方法)

.method public hidebysig static void  Main() cil managed
{
  .entrypoint
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) 
  .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       22 (0x16)
  .maxstack  1
  .locals init ([0] class AuctionSniper.Main.App app)
  IL_0000:  nop
  ... <snipped>

与非入口点方法相比 - 假设是InitializeComponent()。

.method public hidebysig instance void  InitializeComponent() cil managed
{
  .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       20 (0x14)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldarg.0
  ... <snipped>

2
你可以使用 ildasm.exe 来检查。
ildasm /ALL /TEXT program.exe

2
在PE文件的CLI头部偏移量为20处,有一个入口点标记。参见ECMA 335规范的第25.3.3节。
在IL中,您需要将.entrypoint指令放置到方法体中。该方法必须是静态的,没有参数或接受字符串数组(包括可变参数)。如果将语言更改为IL,则应在Reflector中看到此内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接