如何让附加控制台的WPF程序运行时阻塞控制台提示符返回
搞定WPF命令行模式下控制台提示符提前返回的问题
我明白你的困扰——当用命令行参数启动WPF程序时,控制台提示符嗖地一下就回来了,根本没等程序跑完逻辑。这问题其实出在WPF的退出机制上,咱们来一步步解决它。
问题根源
你已经用AttachConsole成功连接了父控制台,但程序执行完命令逻辑后直接调用Shutdown(),WPF的这个方法会快速终止整个应用进程。父控制台一检测到进程结束,就立刻恢复提示符,完全不管你刚输出的内容用户有没有看完。
解决方案:让程序在命令行模式下保持阻塞
咱们只需要在命令行逻辑执行完后,加一段让主线程保持活跃的代码,直到你希望程序退出为止。这里有两种常用方式:
方式一:等待用户交互(适合需要确认的场景)
在命令逻辑结束后,添加等待用户按键的代码,这样控制台会一直停着,直到用户按下任意键:
Console.WriteLine("Press any key to exit..."); Console.ReadKey();
方式二:无交互阻塞(适合自动化场景)
如果不需要用户操作,也可以让主线程无限等待(不过这种情况你得确保有其他退出触发条件,比如任务完成信号):
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
修改后的完整代码
下面是整合了第一种方式的代码,既保留了你的原有逻辑,又解决了提示符提前返回的问题:
public partial class App : Application { [DllImport("kernel32.dll")] static extern bool AttachConsole(int dwProcessId); private const int ATTACH_PARENT_PROCESS = -1; protected override void OnStartup(StartupEventArgs e) { if (e.Args.Length == 0) { // 启动GUI界面 base.OnStartup(e); new MainWindow().ShowDialog(); } else { // 命令行模式:先连接父控制台 AttachConsole(ATTACH_PARENT_PROCESS); if (e.Args.Contains("-i")) { var stopWatch = new Stopwatch(); stopWatch.Reset(); stopWatch.Start(); for (int i = 0; i < 100; i++) { Console.WriteLine(i); } stopWatch.Stop(); var ts = stopWatch.Elapsed; var elapsedTime = $"{ts.Hours:00}:{ts.Minutes:00}:{ts.Seconds:00}.{ts.Milliseconds / 10:00}"; Console.WriteLine("RunTime " + elapsedTime); // 等待用户按键,阻塞控制台 Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } else { Console.WriteLine("Incorrect arguments"); // 同样添加等待,避免立刻返回提示符 Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } // 等待完成后再关闭应用 Shutdown(); } } }
额外小贴士
- 如果你觉得提示语没必要,也可以直接用
Console.ReadKey(true),这样用户按键不会在控制台显示出来。 - 要是你用的是异步命令逻辑,记得要等待异步任务完成后再执行阻塞代码,不然还是会提前退出哦。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

