简体   繁体   中英

Exception when using console window in C# (Windows form application)

I have a program WFA that also has and command Window. I open the window with AllocConsole(); When I close the console window, I use FreeConsole(); but when I open it again with AllocConsole(); I wanna write and read from it and it throws an exeption.

The code:

    namespace WindowsFormsApplication2
{

class classx
{

    [DllImport("kernel32.dll")]
    public static extern Int32 AllocConsole();
    [DllImport("kernel32.dll")]
    public static extern bool FreeConsole();
    [DllImport("kernel32")]
    public static extern bool AttachConsole();
    [DllImport("kernel32")]
    public static extern bool GetConsoleWindow();
    public static bool z = false;
    [DllImport("kernel32")]
    public static extern bool SetConsoleCtrlHandler(HandlerRoutine HandlerRoutine, bool Add);
    public delegate bool HandlerRoutine(uint dwControlType);
}



public partial class Form1 : Form
{
    NotifyIcon icontask;
    Icon iconone_active;
    Icon iconone_inactive;
    /*Icon icontwo;
    Icon iconthree;
    Icon iconfour;
    Icon iconfive;*/
    Thread Threadworkermy;

    public Form1()
    {
        InitializeComponent();
        this.WindowState = FormWindowState.Minimized;
        this.ShowInTaskbar = false;
        iconone_active = new Icon(".../iconone_active.ico");
        iconone_inactive = new Icon(".../iconone_inactive.ico");
        icontask = new NotifyIcon();
        icontask.Icon = iconone_active;
        icontask.Visible = true;
        Threadworkermy = new Thread(new ThreadStart(checkActivityThread));
        Threadworkermy.Start();

        MenuItem Nameapp = new MenuItem("xr");
        MenuItem quitappitem = new MenuItem("quit program");
        MenuItem OpenGUI = new MenuItem("Open GUI");
        MenuItem Advancedmodewindow = new MenuItem("x");
        ContextMenu contextmenu = new ContextMenu();

        quitappitem.Click += quitappitem_click;
        OpenGUI.Click += OpenGUI_click;
        Advancedmodewindow.Click += Advancedmodewindow_click;
        contextmenu.MenuItems.Add(Nameapp);
        contextmenu.MenuItems[0].Enabled = false;
        contextmenu.MenuItems.Add("-");
        contextmenu.MenuItems.Add(OpenGUI);
        contextmenu.MenuItems.Add(Advancedmodewindow);
        contextmenu.MenuItems.Add("-");
        contextmenu.MenuItems.Add(quitappitem);
        icontask.ContextMenu = contextmenu;

        icontask.Icon = iconone_active;
        icontask.Visible = true;
    }

    private void Advancedmodewindow_click(object sender, EventArgs e)
    {
        classx.AllocConsole();
        Console.WriteLine("X");
        classx.FreeConsole();
    }

    private void OpenGUI_click(object sender, EventArgs e)
    {
        this.ShowInTaskbar = true;
        this.WindowState = FormWindowState.Normal;  
    }

    private void quitappitem_click(object sender, EventArgs e)
    {
        Threadworkermy.Abort();
        icontask.Dispose();
        this.Close();
    }

    public void checkActivityThread()
    {
        try
        {
            while(true)
            {
                Thread.Sleep(100);   
            }
        } catch(ThreadAbortException tbe)
        {

        }

    }

    private void button1_Click(object sender, EventArgs e)
    {
        this.WindowState = FormWindowState.Minimized;
        this.ShowInTaskbar = false;
    }


}

}

Exception that it throws out 'System.IO.IOException' in mscorlib.dll Additional information: The handle is invalid.

To those who will be saying to change the type, I can't. (it needs to be WFA application)

there seems to be an issue with destroying the consolewindow, so you could just hide it.

For hiding the window you need an additional DllImport from user32.dll and change the returnvalue of GetConsoleWindow to IntPtr:

[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

[DllImport("kernel32.dll")]
public static extern IntPtr GetConsoleWindow();

Now check if a console-handle already exists. If it does show the console otherwise create the consolewindow:

private void Advancedmodewindow_click(object sender, EventArgs e)
{
    IntPtr handle = classx.GetConsoleWindow();
    if (handle == IntPtr.Zero)
    {
        classx.AllocConsole();
        handle = classx.GetConsoleWindow();
    }
    else
    {
        //shows the window with the given handle
        classx.ShowWindow(handle, 8);
    }
    Console.WriteLine("X");
    //hides the window with the given handle
    classx.ShowWindow(handle, 0);
}

The original solution can be found here:

https://social.msdn.microsoft.com/Forums/vstudio/en-US/cdee5d88-3325-47ce-9f6b-83aa4447f8ca/console-exception-on-windows-8?forum=clr

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM