консоль разбилась, когда я пытаюсь открыть ее дважды в wpf

#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 и т.д.). С очень небольшими трудностями и, конечно, намного меньшими трудностями, чем сталкиваться с незнакомыми ошибками, связанными со смешиванием неуправляемых вызовов в вашей управляемой программе, вы можете создать окно для своей программы, которое выполняет все, что делает окно консоли, но делает это лучше. ИМХО, это действительно правильный путь.