3

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

所以,我写了这个小应用程序,它有两个 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 标头中,这些信息在反汇编程序中看不到,但可以在十六进制编辑器中看到?

4

3 回答 3

6

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

.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>
于 2010-07-26T17:40:49.370 回答
2

您可以使用ildasm.exe

ildasm /ALL /TEXT program.exe
于 2010-07-26T17:40:27.223 回答
2

在偏移量 20 处的 PE 文件的 CLI 标头中,有入口点标记。请参阅 ecma 335 规范的第 25.3.3 节。

在 IL 中,您可以将.entrypoint指令放入方法体中。该方法必须是静态的,没有参数或接受一系列字符串。(包括可变参数)。如果您将语言更改为 IL,您应该在反射器中看到这一点。

于 2010-07-26T17:49:51.117 回答