从cmd运行时控制台和winforms应用程序的区别

本文关键字:应用程序 区别 winforms cmd 运行时 控制台 | 更新日期: 2023-09-27 18:10:13

我有一个winforms应用程序,有时从命令行使用。下面是代码(当然简化了):

[STAThread]
static void Main()
{
    AttachConsole(ATTACH_PARENT_PROCESS);
    Console.WriteLine("Hello");
    /*Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());*/
}

如果这是一个控制台应用程序,输出可以是:

C:'ConsoleApplication'ConsoleApplication.exe
Hello
C:'ConsoleApplication'_

对于windows应用程序,它实际上是:

C:'WindowsApplication'WindowsApplication.exe
C:'WindowsApplication'Hello
_

有没有人能告诉我为什么我们有这样的差异,是否有可能使我的windows应用程序在从cmd运行时表现得像控制台?

编辑:

我希望我的windows应用程序在运行cmd时表现得像控制台:

C:'WindowsApplication'WindowsApplication.exe
Hello
C:'WindowsApplication'_

解决方案:

作为结果,我运行我的应用程序

C:'WindowsApplication'start /wait WindowsApplication.exe

从cmd运行时控制台和winforms应用程序的区别

是。不同之处在于cmd.exe知道可执行文件的类型。当它是一个控制台模式应用程序时,它知道等待进程终止。当它是一个常规的Windows gui应用程序时,它不会等待。相信它会创建自己的窗口。所以它再次显示命令提示符,您的输出被附加到其中。顺便说一句,你也会在使用Console.ReadLine()时遇到麻烦。

你必须用start /wait yourapp.exe启动你的程序来强制cmd.exe等待。调用AllocConsole()是唯一的通用解决方案。当你的应用程序从快捷方式启动时,它还负责创建控制台。

AllocConsole()相当令人迷惑。考虑编写一个小型的控制台模式应用,除了进程之外什么都不做。Start + WaitForExit启动主程序。可能还需要修改命令行参数。现在又恢复了阻塞行为。如果你将可执行文件重命名为mainapp.com(以启动mainapp.exe),那么差异就会被隐藏得很好,VS也使用了这个技巧(devenv.exe VS devenv.com)。

在exe中有一个标志,告诉你这是一个控制台应用程序还是gui(在你的情况下是winform)应用程序。当你启动一个应用程序时,如果它是一个控制台应用程序,Windows将从程序中分离控制台。你可以使用以下方法来实现你想要的:

  1. 将应用程序编译为gui,命名为mytool.exe
  2. 创建一个别名mytool=start/wait c:'path'mytool.exe $*

这样,当你在资源管理器或快捷方式中启动mytool.exe时,你启动了一个普通的windows应用程序;当你在控制台中输入mytool时,你实际上是通过"start/wait"启动它,这将不会分离控制台,更少的标志。(然而,如果你想从控制台输出/输入一些东西,你确实需要在应用程序中附加到父控制台。

如果我理解正确的话,您希望Windows应用程序在运行时阻止控制台线程。我不知道你为什么要这样做,但我可以试着告诉你它是如何工作的:

将WinForms应用程序更改为控制台应用程序,打开一个窗体。这样,它将在显示窗口时阻塞控制台线程。