我正在尝试通过点击按钮从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();
引发的异常。谁能告诉我,如果我错过了什么?
答案 0 :(得分:2)
我怀疑可以多次连接/分离到控制台。据我所知the code of private static IntPtr ConsoleInputHandle
(同样适用于ConsoleOutputHandle
),句柄在首次使用时初始化一次,因此当您从控制台分离进程并再次重新附加时,句柄无效
因此,根据需要使用Console
类是不可行的(我也不知道任何可用作控制台和Win32应用程序的实例示例 - 我见过的大多数应用程序都提供了两个版本of .exe)。
如果您确实需要Windows控制台,我猜您可以尝试在Windows API上方提供自己的控制台包装器。如果你只需要控制台的外观,你可以使用你自己的#34;类似控制台的"窗口。