gpt4 book ai didi

c# - 第二次打开控制台后尝试调用 Console.Clear() 时出现异常

转载 作者:行者123 更新时间:2023-11-30 23:07:09 28 4
gpt4 key购买 nike

我正在尝试通过单击按钮从 winform 应用程序打开控制台。我正在通过以下代码执行此操作。

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool AllocConsole();

[DllImport("kernel32.dll")]
static extern Boolean FreeConsole();

private void button1_Click(object sender, EventArgs e)
{
int userInput = 0;
AllocConsole();

do
{
Console.Clear();
Console.WriteLine("Hello World");
Console.WriteLine("Select 1 or 2");
int.TryParse(Console.ReadLine(), out userInput);
} while (userInput != 1 && userInput != 2);

FreeConsole();
}

第一次打开控制台时,它工作正常。尝试再次打开控制台可以正常工作,但一次 Console.Clear();被调用,我得到:

An unhandled exception of type 'System.IO.IOException' occurred in mscorlib.dll

Additional information: The handle is invalid.

相同的异常将在 Console.WriteLine(); 上抛出和 Console.ReadLine(); .我已经尝试了 this 中提出的解决方案, this , 和 this ,但我最终得到了相同的“句柄无效”。 Console.Clear(); 上的错误.

我试过的一些额外代码:

    [DllImport("kernel32.dll",
EntryPoint = "GetStdHandle",
SetLastError = true,
CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr GetStdHandle(int nStdHandle);

[DllImport("kernel32.dll",
EntryPoint = "AllocConsole",
SetLastError = true,
CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
private static extern int AllocConsole();

[DllImport("kernel32.dll")]
static extern Boolean FreeConsole();


private const int STD_OUTPUT_HANDLE = -11;
private const int MY_CODE_PAGE = 437;

private void button1_Click(object sender, EventArgs e)
{
int userInput = 0;
AllocConsole();

IntPtr stdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
SafeFileHandle safeFileHandle = new SafeFileHandle(stdHandle, true);
FileStream fileStream = new FileStream(safeFileHandle, FileAccess.Write);
Encoding encoding = System.Text.Encoding.GetEncoding(MY_CODE_PAGE);
StreamWriter standardOutput = new StreamWriter(fileStream, encoding);
standardOutput.AutoFlush = true;
Console.SetOut(standardOutput);
Stream streamIn = Console.OpenStandardInput();
TextReader readerIn = new StreamReader(streamIn);
Console.SetIn(readerIn);

do
{
Console.Clear();
Console.WriteLine("Hello World");
Console.WriteLine("Select 1 or 2");
int.TryParse(Console.ReadLine(), out userInput);
} while (userInput != 1 && userInput != 2);

FreeConsole();
}

这对于 Console.WriteLine(); 似乎没问题和 Console.ReadLine();但我仍然无法解决 Console.Clear(); 抛出的异常.谁能告诉我是否遗漏了什么?

最佳答案

我怀疑是否可以多次附加/分离到控制台。据我了解the code of private static IntPtr ConsoleInputHandle (同样适用于 ConsoleOutputHandle),句柄在第一次使用时初始化一次,因此当您从控制台分离进程并再次重新附加它时,句柄无效。

所以恕我直言,根据需要使用 Console 类是不可行的(我也不知道任何同时作为控制台和 Win32 应用程序工作的程序的实例 - 我见过的大多数应用程序都提供了两个.exe 版本)。

如果您真的需要 Windows 控制台,我想您可以尝试在 Windows API 之上提供您自己的控制台包装器。如果您只需要控制台的外观,您可以渲染您自己的“类似控制台”的窗口。

关于c# - 第二次打开控制台后尝试调用 Console.Clear() 时出现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47553684/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com