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

问题描述 投票:0回答:11

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

c# winforms console-application
11个回答
108
投票

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

using System.Windows.Forms;

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

重要的一点是

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


42
投票

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

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

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

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


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

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

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


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



27
投票

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



6
投票

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

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


5
投票


4
投票

因此,您想在控制台应用程序中使用

Windows 窗体执行某些操作:

在解决方案资源管理器的控制台应用程序项目中添加对

System.Windows.Forms.dll

的引用。 (右键单击解决方案名称->添加->参考...) 在代码中指定名称空间:

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 }



2
投票

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

这会在新线程中启动,并且在表单关闭之前不会释放线程。 
Task

位于 .Net 4 及更高版本中。

    


1
投票


0
投票
A。附加流程,例如:在表单上输入并在控制台上打印

b.独立进程,例如:启动一个计时器,即使控制台退出也不关闭。

对于一个,

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

对于 b,
使用线程或任何任务,
如何独立打开win窗体?


0
投票
Form Freeze

并使用编辑功能(如按钮的文本),请使用此代码 Form form = new Form(); Form.Button.Text = "randomText"; System.Windows.Forms.Application.EnableVisualStyles(); System.Windows.Forms.Application.Run(form);



-3
投票

© www.soinside.com 2019 - 2024. All rights reserved.