-1

I want to open a console in wpf, I was try to open the console twice without close the program, but in the second time the program crashed, I don't really know why and I'd love to help

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();
        }
    }
}
  • 2
    _"the program crashed"_ -- please be specific. In what way did the program "crash"? Did it just stop responding? Did it throw an exception? Did it just disappear? Where there any error messages of any sort? If so, what did they say, _exactly_? If there was an exception, what was the stack trace? Please improve your question. – Peter Duniho Oct 19 '16 at 23:19
  • I tried the code you posted and I get three different behaviors: sometimes it works fine; sometimes it hangs the console, and thus the whole program; and sometimes it throws an exception at the `ReadLine()` call: `The handle is invalid`. I don't know enough about the console API to explain why what you're doing is wrong per se, but it seems clear this is not how you're expected to use the console API. Furthermore, I would say even if it worked, this is the wrong thing to do. You have a GUI program; if you want to show a console, display your own window and use it for the purpose. – Peter Duniho Oct 19 '16 at 23:40

1 Answers1

0

It looks like you need to also reallocate the Console class's input stream if you want to keep allocating a new console and then using ReadLine() for that new console:

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();
}

That said, I think you're really headed in the wrong direction with this. The console window is an extremely limited means for interacting with the user. It's why we have GUI programs in the first place (Winforms, WPF, etc.). With very little difficulty, and certainly way less difficulty than running into unfamiliar errors related to the mixing of unmanaged calls in your managed program, you can create a window for your program that does everything a console window does, but does it better. IMHO, that's really the right way to go.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136