如何从控制台应用程序运行一个winform?

如何从控制台应用程序中创build,执行和控制一个winform?

最简单的select是启动一个Windows窗体项目,然后将输出types更改为控制台应用程序。 或者,只需添加对System.Windows.Forms.dll的引用,然后开始编码:

using System.Windows.Forms; [STAThread] static void Main() { Application.EnableVisualStyles(); Application.Run(new Form()); // or whatever } 

重要的是你的Main()方法上的[STAThread] ,它是完整的COM支持所必需的。

我最近想这样做,发现我对这里的任何答案都不满意。

如果您遵循Marc的build议并将输出types设置为控制台应用程序,则会出现两个问题:

1)如果你从资源pipe理器启动应用程序,你的窗体后面会出现一个恼人的控制台窗口,在你的程序退出之前这个窗口不会消失。 我们可以通过在显示GUI之前调用FreeConsole来缓解这个问题(Application.Run)。 这里的烦恼是控制台窗口仍然出现。 它立即消失,但在那里一时无一不在。

2)如果从控制台启动它并显示GUI,控制台将被阻止,直到GUI退出。 这是因为控制台(cmd.exe)认为它应该asynchronous启动控制台应用程序和Windows应用程序(与“myprocess&”相同的unix)。

如果将输出types保留为Windows应用程序,但正确调用AttachConsole,则从控制台调用时不会获得第二个控制台窗口,并且从资源pipe理器调用时不会获得不必要的控制台。 调用AttachConsole的正确方法是将-1传递给它。 这会导致我们的进程附加到我们的父进程(启动我们的控制台窗口)的控制台。

但是,这有两个不同的问题:

1)由于控制台在后台启动Windows应用程序,它立即显示提示并允许进一步input。 一方面,这是一个好消息,控制台不会在您的GUI应用程序中被阻塞,但是在您要将输出转储到控制台而不显示GUI的情况下,程序的输出会在提示符后出现,并且没有新的提示当你完成后显示。 这看起来有点混乱,更不要说你的“控制台应用程序”在后台运行,用户可以在运行时自由执行其他命令。

2)streamredirect也会混乱,例如“myapp some parameters> somefile”无法redirect。 streamredirect问题需要大量的p / Invoke来修复标准句柄,但它是可以解决的。

经过几个小时的狩猎和试验,我得出的结论是没有办法做到这一点完美。 你根本无法获得控制台和窗口的所有好处,没有任何副作用。 这是挑选哪些副作用最不讨厌您的应用程序的目的。

这里是我find的最好的方法:首先,将项目输出types设置为“Windows应用程序”,然后P / Invoke AllocConsole创build一个控制台窗口。

 internal static class NativeMethods { [DllImport("kernel32.dll")] internal static extern Boolean AllocConsole(); } static class Program { static void Main(string[] args) { if (args.Length == 0) { // run as windows app Application.EnableVisualStyles(); Application.Run(new Form1()); } else { // run as console app NativeMethods.AllocConsole(); Console.WriteLine("Hello World"); Console.ReadLine(); } } } 

这很简单:

只需将以下属性和代码添加到您的主要方法:

 [STAThread] void Main(string[] args]) { Application.EnableVisualStyles(); //Do some stuff... while(!Exit) { Application.DoEvents(); //Now if you call "form.Show()" your form won´t be frozen //Do your stuff } } 

现在你完全能够显示WinForms 🙂

您可以在VS2005 / VS2008中创build一个winform项目,然后将其属性更改为命令行应用程序。 然后可以从命令行启动,但仍然会打开一个winform。

您应该能够像Winform应用程序一样使用Application类。 开始一个新项目的最简单的方法可能是做Marc的build议:创build一个新的Winform项目,然后在选项中将其更改为控制台应用程序

这适用于我的需要…

 Task mytask = Task.Run(() => { MyForm form = new MyForm(); form.ShowDialog(); }); 

这从一个新的线程开始,直到窗体closures才释放线程。 Task在.Net 4和更高版本中。

它完全取决于你的select,你如何执行。
一个。 附加过程,例如:input表格并在控制台上打印
湾 独立进程,例如:启动一个定时器,即使控制台退出也不要closures。

为一个,

 Application.Run(new Form1()); //or ------------- Form1 f = new Form1(); f.ShowDialog(); 

为b,使用线程,或任何任何事情, 如何独立打开胜利forms?