使用<nul调用C# ReadKey时导致控制台应用程序崩溃

7

我决定开始学习C#编程,并且其中一件事情就是创建一个“pausec.exe”(类似于pause.exe的克隆版)。它可以正常工作,但是当像下面这样调用它时:

< nul pausec  

当程序崩溃时,我收到了以下错误消息(从西班牙语翻译而来):
未处理的异常:System.InvalidOperationException:当任何应用程序没有控制台或控制台输入被重定向到文件时,无法读取键。尝试使用Console.Read。
这是错误出现的堆栈跟踪:
 in System.Console.ReadKey(Boolean intercept)  
 in System.Console.ReadKey()  
 in pausec.Program.Main(String[] args)

这是我正在运行的代码:

using System;

namespace pausec
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);
            Console.Write("\n");
        }
    }
}

我想知道是否有一种解决方法,甚至可以在使用< nul时忽略ReadKey

非常感谢任何帮助。
提前致谢。

更新:找到了一种方法,通过删除拦截(如Alberto Solano所建议的那样),然后在ReadKey方法后添加Console.Write("\b \b"); 它就可以工作了。奇怪的是,当我将应用程序复制到我的桌面时,它不等待用户输入而自动关闭。

更新2:现在它完美地工作了。感谢大家的回答!


未被认可的部落知识。你能解释一下 pause.exe 是什么吗? - P.Brian.Mackey
@P.Brian.Mackey pause.exe 是一个 cmd 命令,它会显示 "按任意键继续. . ." 消息,等待您按下任意键后,才会继续执行代码。 - user2630793
4个回答

7
控制台有一个方法可以用来检查stdin是否被重定向。
public static bool IsInputRedirected { get; }

啊...但只在CLR的v4.5版本中可用。该属性在CLR的早期版本中不存在:http://msdn.microsoft.com/zh-cn/library/system.console.isinputredirected(v=vs.110).aspx - Nicholas Carey

3
您的程序抛出异常是因为,在Console.ReadKey(true);中,根据MSDN文档所述:

如果intercept参数为true,则拦截按下的键,并且不在控制台窗口中显示;否则,按下的键将显示。

您没有读取或“监听”键盘上按下的任何键,因此没有键可以拦截并在控制台窗口中不显示。
如果您只想按任意键关闭程序,请使用:
Console.ReadKey(); //this won't intercept any key pressed

或者

Console.ReadLine();

更新:您在评论中问如何隐藏用户按下的键。这段代码应该可以解决问题:

ConsoleKeyInfo cki;
Console.Write("Press any key to continue . . . ");
cki = Console.ReadKey(true);

这个方法可行,但唯一的问题是我想找到一种隐藏按键的方法。如果没有其他办法,那么这个方法就只能用了。 - user2630793
我也更新了问题。我会尝试您的方法,但我找到了一种使用Console.Write("\b \b")命令的方法。编辑:您的方法似乎解决了奇怪的“按回车键第一个字母被删除”的问题。 - user2630793
我尝试使用您的新方法<nul pausec,但它与原始问题一样存在问题... - user2630793
@ALTOhDude 我用我的控制台应用程序测试了这段代码。'<nul pausec'是什么? - Alberto Solano
@ALTOhDude 你是在尝试做这个吗?如何在cmd.exe中将stderr重定向到null? - Alberto Solano

3

我曾经遇到过同样的错误。

所以我检查了一下我的项目输出类型

项目名称->右击->属性

在那里你可以看到你的输出类型。

所以我把它改成了控制台应用程序,因为在我的情况下它似乎是窗口应用程序。然后就可以正常工作了。


1
在调试 Windows 服务项目时解决了我的问题。 - ArieKanarie

0
/// <summary>
/// Written by fredrik92 (http://social.msdn.microsoft.com/Forums/vstudio/en-US/08163199-0a5d-4057-8aa9-3a0a013800c7/how-to-write-a-command-like-pause-to-console?forum=csharpgeneral)
/// Writes a message to the console prompting the user to press a certain key in order to exit the current program.
/// This procedure intercepts all keys that are pressed, so that nothing is displayed in the Console. By default the
/// Enter key is used as the key that has to be pressed.
/// </summary>
/// <param name="key">The key that the Console will wait for. If this parameter is omitted the Enter key is used.</param>    
public static void WriteKeyPressForExit(ConsoleKey key = ConsoleKey.Enter)
{
    Console.WriteLine();
    Console.WriteLine("Press the {0} key on your keyboard to exit . . .", key);
    while (Console.ReadKey(intercept: true).Key != key) { }
}

它允许您选择需要按下的键,而不是任意键,但您可以轻松修改为任意键。 - Recursor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接