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

我有一个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.exe知道可执行文件的类型。 它知道等待进程在它是控制台模式应用程序时终止。 它不等待它是一个常规的Windows gui应用程序。 相信它会创建自己的窗口。 因此它再次显示命令提示符,您的输出将附加到该输出。 使用Console.ReadLine() btw也会遇到问题。

您必须使用start /wait yourapp.exe启动程序以强制cmd.exe等待。 相反,调用AllocConsole()是唯一的通用修复。 当您的应用程序从快捷方式启动时,还会负责创建控制台。

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

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

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

这样,当您在资源管理器或快捷方式中启动mytool.exe时,您启动一​​个普通的Windows应用程序; 当您在控制台中键入mytool时,实际上是通过“start / wait”启动它,这不会将控制台与标志分开。 (但是,如果要从控制台输出/输入内容,则需要在应用程序中附加到父控制台。

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

将WinForms应用程序更改为打开表单的控制台应用程序。 这样它会在显示窗口时阻止控制台线程。