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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/277771/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 21:14:20  来源:igfitidea点击:

how to run a winform from console application?

c#winformsconsole-application

提问by reshefm

How do I create, execute and control a winform from within a console application?

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

采纳答案by Marc Gravell

The easiest option is to start a windows forms project, then change the output-type to Console Application. Alternatively, just add a reference to System.Windows.Forms.dll, and start coding:

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

using System.Windows.Forms;

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

The important bit is the [STAThread]on your Main()method, required for full COM support.

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

回答by David Arno

You can create a winform project in VS2005/ VS2008 and then change its properties to be a command line application. It can then be started from the command line, but will still open a winform.

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

回答by Grzenio

You should be able to use the Application class in the same way as Winform apps do. Probably the easiest way to start a new project is to do what Marc suggested: create a new Winform project, and then change it in the options to a console application

您应该能够以与 Winform 应用程序相同的方式使用 Application 类。启动新项目的最简单方法可能是按照 Marc 的建议进行操作:创建一个新的 Winform 项目,然后在选项中将其更改为控制台应用程序

回答by Grzenio

Here is the best method that I've found: First, set your projects output type to "Windows Application", then P/Invoke AllocConsole to create a console window.

这是我发现的最佳方法:首先,将项目输出类型设置为“Windows 应用程序”,然后 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();
        }
    }

}

回答by SharpShade

It′s very simple to do:

做起来很简单:

Just add following attribute and code to your Main-method:

只需将以下属性和代码添加到您的 Main-method 中:

[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
   }
}

Now you′re fully able to show WinForms :)

现在你完全可以展示 WinForms 了 :)

回答by Tergiver

I recently wanted to do this and found that I was not happy with any of the answers here.

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

If you follow Marc's advice and set the output-type to Console Application there are two problems:

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

1) If you launch the application from Explorer, you get an annoying console window behind your Form which doesn't go away until your program exits. We can mitigate this problem by calling FreeConsole prior to showing the GUI (Application.Run). The annoyance here is that the console window still appears. It immediately goes away, but is there for a moment none-the-less.

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

2) If you launch it from a console, and display a GUI, the console is blocked until the GUI exits. This is because the console (cmd.exe) thinks it should launch Console apps synchronously and Windows apps asynchronously (the unix equivalent of "myprocess &").

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


If you leave the output-type as Windows Application, but correctlycall AttachConsole, you don't get a second console window when invoked from a console and you don't get the unnecessary console when invoked from Explorer. The correct way to call AttachConsole is to pass -1 to it. This causes our process to attach to the console of our parent process (the console window that launched us).


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

However, this has two different problems:

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

1) Because the console launches Windows apps in the background, it immediately displays the prompt and allows further input. On the one hand this is good news, the console is not blocked on your GUI app, but in the case where you want to dump output to the console and never show the GUI, your program's output comes after the prompt and no new prompt is displayed when you're done. This looks a bit confusing, not to mention that your "console app" is running in the background and the user is free to execute other commands while it's running.

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

2) Stream redirection gets messed up as well, e.g. "myapp some parameters > somefile" fails to redirect. The stream redirection problem requires a significant amount of p/Invoke to fixup the standard handles, but it is solvable.

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


After many hours of hunting and experimenting, I've come to the conclusion that there is no way to do this perfectly. You simply cannot get all the benefits of both console and window without any side effects. It's a matter of picking which side effects are least annoying for your application's purposes.


经过数小时的探索和试验,我得出的结论是,没有办法完美地做到这一点。您根本无法在没有任何副作用的情况下获得控制台和窗口的所有好处。选择哪种副作用对您的应用程序而言最不烦人是一个问题。

回答by Sunsetquest

This worked for my needs...

这对我的需求有用...

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

This starts the from in a new thread and does not release the thread until the form is closed. Taskis in .Net 4 and later.

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

回答by Raj kumar

Its totally depends upon your choice, that how you are implementing.
a. Attached process , ex: input on form and print on console
b. Independent process, ex: start a timer, don't close even if console exit.

它完全取决于您的选择,即您如何实施。
一种。附加流程,例如:在表单上输入并在控制台上打印
b。独立进程,例如:启动计时器,即使控制台退出也不关闭。

for a,

为一个,

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

for b, Use thread, or task anything, How to open win form independently?

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

回答by AndrewToasterr

If you want to escape from Form Freezeand use editing (like text for a button) use this code

如果您想从Form Freeze 中退出并使用编辑(如按钮的文本),请使用此代码

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

回答by Biju Joseph

All the above answers are great help, but I thought to add some more tips for the absolute beginner.

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

So, you want to do something with Windows Forms, in a Console Application:

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

Add a reference to System.Windows.Forms.dllin your Console application project in Solution Explorer. (Right Click on Solution-name->add->Reference...)

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

Specify the name space in code: using System.Windows.Forms;

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

Declare the needed properties in your class for the controls you wish to add to the form.

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

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

例如 int Left { get; set; } // need to specify the LEFT position of the button on the Form

And then add the following code snippet in Main():

然后在 中添加以下代码片段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 
}