我有一个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
答案 0 :(得分:9)
是。区别在于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)。
答案 1 :(得分:4)
exe中有一个标志,告诉它是控制台应用程序还是gui(在你的情况下是winform)应用程序。当您启动应用程序时,如果它是控制台应用程序,Windows将从程序中分离控制台。您可以使用以下方法来实现您的目标:
这样,当您在资源管理器或快捷方式中启动mytool.exe时,您启动一个普通的Windows应用程序;当你在控制台中键入mytool时,你实际上是通过“start / wait”启动它,这不会分离控制台而不是标记。 (但是,如果要从控制台输出/输入内容,则需要在应用程序中附加到父控制台。
答案 2 :(得分:0)
如果我理解正确,您希望Windows应用程序在运行时阻止控制台线程。我不知道你为什么会这样做,但我可以试一下它是如何工作的:
将WinForms应用程序更改为打开表单的控制台应用程序。这样它会在显示窗口时阻塞控制台线程。