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

发布于 2024-07-08 19:43:46 字数 35 浏览 4 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

烧了回忆取暖 2024-07-15 19:43:46

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

using System.Windows.Forms;

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

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

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:

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.

箹锭⒈辈孓 2024-07-15 19:43:46

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

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

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

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

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

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

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

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

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

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:

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.

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 &").

If you leave the output-type as Windows Application, but correctly call 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).

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.

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.

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.

很糊涂小朋友 2024-07-15 19:43:46

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

}

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.

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

}
沉默的熊 2024-07-15 19:43:46

做起来非常简单:

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

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

It´s very simple to do:

Just add following attribute and code to your 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 :)

七月上 2024-07-15 19:43:46

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

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.

携余温的黄昏 2024-07-15 19:43:46

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

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

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

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

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

例如 int Left { get; 放; } // 需要指定按钮在Form上的LEFT位置

然后在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 
}

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:

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

Specify the name space in code: 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

And then add the following code snippet in 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 
}
千鲤 2024-07-15 19:43:46

这满足了我的需要...

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

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

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. Task is in .Net 4 and later.

养猫人 2024-07-15 19:43:46

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

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

居里长安 2024-07-15 19:43:46

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

对于a,

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

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

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.

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?

蘑菇王子 2024-07-15 19:43:46

如果您想摆脱表单冻结并使用编辑(如按钮的文本),请使用此代码

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

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

Form form = new Form();
Form.Button.Text = "randomText";
System.Windows.Forms.Application.EnableVisualStyles();
System.Windows.Forms.Application.Run(form);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文