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

如何在控制台应用内创建、执行和控制 winform?

137729 次浏览

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

using System.Windows.Forms;


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

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

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

你应该能够使用应用程序类,以同样的方式作为信息应用程序。也许开始一个新项目最简单的方法就是按照马克的建议: 创建一个新的 winformation 项目,然后在选项中把它改成一个控制台应用

这是我找到的最好的方法: 首先,将您的项目输出类型设置为“ 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();
}
}


}

做起来很简单:

只需在 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:)

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

如果你听从马克的建议,将输出类型设置为控制台应用,那么有两个问题:

1)如果你从资源管理器启动应用程序,你会在窗体后面看到一个烦人的控制台窗口,直到程序退出才会消失。我们可以在显示 GUI (Application 之前调用 FreeConsole 来缓解这个问题。快跑)。这里的烦恼是仍然出现控制台窗口。它马上就消失了,但是有那么一会儿。

2)如果你从一个控制台启动它,并显示一个 GUI,控制台将被阻塞,直到 GUI 退出。这是因为控制台(cmd.exe)认为它应该同步启动控制台应用程序和 Windows 应用程序(Unix 版本的“ myprocess &”)。


如果将输出类型保留为 Windows Application,但 正确调用 AttachConsole,则从控制台调用时不会获得第二个控制台窗口,从 Explorer 调用时也不会获得不必要的控制台。调用 AttachConsole 的正确方法是向其传递 -1。这会导致我们的进程附加到父进程的控制台(启动我们的控制台窗口)。

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

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

2)流重定向也会出现混乱,例如“ myapp 有些参数 > some file”无法重定向。流重定向问题需要大量的 p/Invoke 来修复标准句柄,但是这是可以解决的。


经过几个小时的狩猎和实验,我得出结论,没有办法做到这一点完美。您不可能在没有任何副作用的情况下同时获得控制台和窗口的所有好处。对于应用程序的目的来说,这是一个选择哪些副作用最不烦人的问题。

这对我有用。

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

这将在新线程中启动 from,并且在窗体关闭之前不释放该线程。Task进去了。4号及以后。

它完全取决于你的选择,你是如何执行的。
附加的过程,例如: 输入的形式和打印的控制台
独立的进程,例如: 启动一个计时器,即使控制台退出也不要关闭。

对于一个,

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

第二, 使用线程,或任务任何东西, 如何独立开放取胜?

如果要从 冻结表格转义并使用编辑(如文本作为按钮) ,请使用下面的代码

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

以上所有的答案都非常有帮助,但是我想为初学者增加一些更多的技巧。

所以,你想用 返回文章页面 Windows 窗体控制台应用:做一些事情

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

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

为要添加到窗体中的控件声明类中所需的属性。

例如 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
}