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

时间:2008-11-10 12:42:22

标签: c# winforms console-application

如何在控制台应用程序中创建,执行和控制winform?

10 个答案:

答案 0 :(得分:88)

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

using System.Windows.Forms;

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

重要的一点是[STAThread]方法上的Main(),这是完全支持COM所必需的。

答案 1 :(得分:32)

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

如果您遵循Marc的建议并将输出类型设置为Console Application,则存在两个问题:

1)如果您从资源管理器启动应用程序,您的表单后面会出现一个恼人的控制台窗口,在您的程序退出之前该窗口不会消失。我们可以通过在显示GUI(Application.Run)之前调用FreeConsole来缓解此问题。这里的烦恼是控制台窗口仍然出现。它立刻就消失了,但是暂时还有一段时间。

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


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

然而,这有两个不同的问题:

1)由于控制台在后台启动Windows应用程序,它会立即显示提示并允许进一步输入。一方面这是个好消息,控制台没有在您的GUI应用程序上被阻止,但是如果您想要将输出转储到控制台并且从不显示GUI,则程序的输出在提示之后出现并且没有新的提示完成后显示。这看起来有点令人困惑,更不用说你的“控制台应用程序”在后台运行,用户可以在运行时自由执行其他命令。

2)流重定向也被搞砸了,例如“myapp一些参数> somefile”无法重定向。流重定向问题需要大量的p / Invoke来修复标准句柄,但它是可以解决的。


经过几个小时的狩猎和实验,我得出的结论是,没有办法完美地完成这项工作。你根本无法获得控制台和窗口的所有好处,没有任何副作用。这是一个挑选哪些副作用最不适合您的应用程序的问题。

答案 2 :(得分:23)

这是我发现的最佳方法: 首先,将项目输出类型设置为“Windows Application”,然后将P / Invoke AllocConsole设置为创建控制台窗口。

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();
        }
    }

}

答案 3 :(得分:6)

这很简单:

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

[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:)

答案 4 :(得分:4)

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

这符合我的需要......

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

这将在新线程中启动from,并且在窗体关闭之前不会释放线程。 Task位于.Net 4及更高版本中。

答案 7 :(得分:0)

完全取决于您的选择,以及您的实施方式 一个。附加过程,例如:在表格上输入并在控制台上打印
湾独立的过程,例如:启动计时器,即使控制台退出也不要关闭。

for a,

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

表示b, 使用线程,或任务, How to open win form independently?

答案 8 :(得分:0)

如果您想逃离表格冻结并使用编辑(如按钮的文字),请使用此代码

Form form = new Form();
Form.Button.Text = "randomText";
System.Windows.Forms.Application.EnableVisualStyles();
System.Windows.Forms.Application.Run(form);

答案 9 :(得分:0)

以上所有答案都有很大的帮助,但我想为绝对的初学者添加更多提示。

因此,您希望在控制台应用程序中使用 Windows窗体执行某些操作:

在解决方案资源管理器中的控制台应用程序项目中添加对 System.Windows.Forms.dll 的引用。 (右键单击Solution-name-> add-> Reference ...)

在代码中指定名称空间:using System.Windows.Forms;

在类中声明您希望添加到表单的控件所需的属性。

e.g。 int Left { get; set; } // need to specify the LEFT position of the button on the Form

然后在Main()中添加以下代码段:

static void Main(string[] args)
{
Application.EnableVisualStyles();
        Form frm = new Form();  // create aForm object

        Button btn = new Button()
        {
            Left = 120,
            Width = 130,
            Height = 30,
            Top = 150,
            Text = "Biju Joseph, Redmond, WA"
        };
       //… more code 
       frm.Controls.Add(btn);  // add button to the Form
       //  …. add more code here as needed

       frm.ShowDialog(); // a modal dialog 
}