#c# #wpf #forms #kernel32
#c# #wpf #формы #kernel32
Вопрос:
Я хочу открыть консоль в wpf, я дважды пытался открыть консоль, не закрывая программу, но во второй раз программа разбилась, я действительно не знаю почему, и я хотел бы помочь
using System;
using System.Windows;
using System.Runtime.InteropServices;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
[DllImport("Kernel32")]
public static extern void AllocConsole();
[DllImport("Kernel32")]
public static extern void FreeConsole();
private void button_Click(object sender, RoutedEventArgs e)
{
AllocConsole();
string x = Console.ReadLine();
FreeConsole();
}
}
}
Комментарии:
1. «программа разбилась» — пожалуйста, будьте конкретны. Каким образом программа «вылетела»? Она просто перестала отвечать? Это вызвало исключение? Она просто исчезла? Где есть какие-либо сообщения об ошибках любого рода? Если да, то что они сказали, точно ? Если было исключение, какова была трассировка стека? Пожалуйста, улучшите свой вопрос.
2. Я попробовал опубликованный вами код, и я получаю три разных варианта поведения: иногда он работает нормально; иногда он зависает на консоли и, следовательно, на всей программе; и иногда он выдает исключение при
ReadLine()
вызове:The handle is invalid
. Я недостаточно знаю о консольном API, чтобы объяснить, почему то, что вы делаете, само по себе неправильно, но кажется очевидным, что это не то, как вы должны использовать консольный API. Более того, я бы сказал, что даже если бы это сработало, это неправильный поступок. У вас есть программа с графическим интерфейсом; если вы хотите отобразить консоль, отобразите свое собственное окно и используйте его для этой цели.
Ответ №1:
Похоже, вам также нужно перераспределить входной поток Console
класса, если вы хотите продолжать выделять новую консоль, а затем использовать ReadLine()
для этой новой консоли:
private void button_Click(object sender, RoutedEventArgs e)
{
AllocConsole();
using (Stream stream = Console.OpenStandardInput())
using (TextReader reader = new StreamReader(stream))
{
string x = reader.ReadLine();
}
FreeConsole();
}
Тем не менее, я думаю, что вы действительно движетесь в неправильном направлении с этим. Окно консоли является чрезвычайно ограниченным средством взаимодействия с пользователем. Именно поэтому у нас в первую очередь есть программы с графическим интерфейсом (Winforms, WPF и т.д.). С очень небольшими трудностями и, конечно, намного меньшими трудностями, чем сталкиваться с незнакомыми ошибками, связанными со смешиванием неуправляемых вызовов в вашей управляемой программе, вы можете создать окно для своей программы, которое выполняет все, что делает окно консоли, но делает это лучше. ИМХО, это действительно правильный путь.