是什么使应用程序控制台或Windows窗体应用程序?

[Visual Studio 2008]

我为控制台应用程序创建了一个新项目,并将其修改为如下所示:

class Program { static void Main (string[] args) { Thread.Sleep (2000); } } 

然后我为Windows Form应用程序创建了另一个项目并进行了修改:

 static class Program { //[STAThread] commented this line static void Main (string[] args) { //Added args //Commented following lines //Application.EnableVisualStyles (); //Application.SetCompatibleTextRenderingDefault (false); //Application.Run (new Form1 ()); commented this line Thread.Sleep (2000); } } 

现在我既没有在第一个应用程序中编写控制台function(Console.Write等),也没有在第二个应用程序中编写与表单相关的操作。 看起来和我一模一样。

第一个应用程序显示BLACK窗口,第二个应用程序没有显示任何内容。 是什么让它像这样工作?

如果您检查exe文件usine ILDASM,您可以看到Manifest存在差异(查找“子系统”)。

在Winforms应用程序中:

 .subsystem 0x0002 // WINDOWS_GUI 

在控制台应用程序中:

 .subsystem 0x0003 // WINDOWS_CUI 

IL代码中可能存在更多差异。

当谈到使编译器在两种情况下以不同方式发出这种情况的原因时,这由项目文件的OutputType值控制:

在Winforms应用程序中:

 WinExe 

在控制台应用程序中:

 Exe 

出于好奇,我还检查了类库项目的值:

 Library 

在项目属性,应用程序选项卡,输出类型中,您可以设置为“Windows应用程序”或“控制台应用程序”。

我相信在幕后VS完全是Fredrik在post中提出的。

此外,将其设置为控制台应用程序将显示Windows窗体项目的黑色控制台应用程序。

在引擎盖下,winform与console exe没有区别,只是PE-header中的一个标志显示“我需要一个控制台”。 PE头不是由C#控制的(因为它是编译的东西,而不是运行时的东西),所以这是在项目文件中定义的( ... )。

或者在命令行( csc /target:exe vs csc /target:winexe )。

可以说,他们可以使用编译器拦截的汇编级属性 – 但这真的有帮助吗? 可能不是。

如果查看项目文件(csproj),您将看到目标在那里被定义为控制台或Windows应用程序。