【发布时间】:2018-05-13 05:09:56
【问题描述】:
我正在尝试通过单击按钮从 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();,我就会得到:
在 mscorlib.dll 中发生了“System.IO.IOException”类型的未处理异常
附加信息:句柄无效。
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(); 引发的异常。如果我遗漏了什么,谁能告诉我?
【问题讨论】:
-
@Tony "一个进程可以使用 FreeConsole 函数将自己与当前控制台分离,然后它可以调用 AllocConsole 创建一个新控制台或 AttachConsole 连接到另一个控制台。"从您的来源...
-
你没有检查 AllocConsole() 是否成功
-
@BugFinder,怎么会不成功?我能够很好地通过 AllocConsole() 并执行 Console.WriteLine 和 Console.ReadLine。两者都很好,特别是 Console.Clear() 是引发异常的原因。尽管如此,我只是进行了一次测试,并且可以确认它是成功的。 AllocConsole() 返回 1。
-
您是在 Visual Studio 中运行的吗?
标签: c#