.NET Core控制台程序在PowerShell ISE中Console.ReadLine()挂起的原因及解决办法
为什么会出现挂起?
PowerShell ISE(Integrated Scripting Environment)并不是基于原生Windows控制台宿主构建的——它的“控制台窗口”是一个模拟的文本编辑器控件,而非真正的Cmd/PowerShell那种原生控制台窗口。
而.NET Core的Console.ReadLine()方法(包括直接调用[console]::ReadLine())依赖原生控制台的标准输入流(STDIN)来获取用户输入。但ISE并没有正确绑定这个原生STDIN流,当程序尝试等待用户输入时,会陷入无限等待状态——因为ISE根本无法把用户在模拟窗口的输入传递给程序的STDIN,最终只能通过Ctrl+C强制终止。
你测试的Windows 7/10、PS 5.0/5.1环境都会出现这个问题,这是ISE本身的设计局限,和.NET Core版本或者Windows系统版本关系不大。
可行的解决办法
这里有几个实用的方案,你可以根据需求选择:
1. 改用原生PowerShell/Cmd窗口运行
这是最直接的解决办法:打开普通的PowerShell或者Cmd窗口,导航到程序所在目录,再执行dotnet .\CoreTest01.dll,就能正常进行交互式输入了——原生控制台完全支持.NET Console类的所有交互操作。
2. 调整程序逻辑,避免交互式输入
如果必须在ISE里运行,可以修改程序,把输入方式改成非交互式的:
- 通过命令行参数传递输入:比如把程序改成读取
args参数,运行时用dotnet .\CoreTest01.dll "YourName" - 从文件读取输入:修改程序读取指定文本文件的内容作为输入,比如
string name = File.ReadAllText("input.txt");
修改后的示例代码(命令行参数版):
using System; namespace CoreTest01 { class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); string name = args.Length > 0 ? args[0] : "Unknown"; Console.WriteLine($"Your name is : {name}"); } } }
3. 在ISE中通过管道传递输入
如果不想修改程序,可以先在ISE里用Read-Host获取输入,再通过管道把输入传递给程序,这样Console.ReadLine()会读取管道中的内容,不需要等待交互式输入:
$userName = Read-Host "Enter your name" echo $userName | dotnet .\CoreTest01.dll
4. 用Start-Process启动原生控制台窗口
在ISE里使用Start-Process命令,让程序在独立的原生控制台窗口中运行,这样就能正常交互了:
Start-Process -FilePath "dotnet" -ArgumentList ".\CoreTest01.dll" -WindowStyle Normal
如果想让程序运行完后窗口不自动关闭,可以调整命令让窗口停留:
Start-Process -FilePath "cmd.exe" -ArgumentList "/k dotnet .\CoreTest01.dll && pause" -WindowStyle Normal
内容的提问来源于stack exchange,提问作者JPBlanc

