3

在我的 WPF 应用程序中,我使用控制台窗口作为调试/消息窗口 - 我有选项设置来根据用户的需要显示和隐藏窗口,所有这些都很好。唯一的问题是当用户关闭控制台窗口时,它会退出整个程序。如何覆盖它,以便当用户单击 X 时它只是隐藏控制台而不是退出应用程序?

这就是我到目前为止所拥有的:

const int SW_HIDE = 0;
const int SW_SHOW = 5;
public static bool ConsoleVisible { get; private set; }

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

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


public static void HideConsole()
{
    var handle = GetConsoleWindow();
    ShowWindow(handle, SW_HIDE);
    ConsoleVisible = false;

}
public static void ShowConsole()
{
    var handle = GetConsoleWindow();
    ShowWindow(handle, SW_SHOW);
    ConsoleVisible = true;
}

** 对于想要使用此功能的人,您需要:using System.Runtime.InteropServices;

此代码源自此答案:https ://stackoverflow.com/a/3571628/649382

** 编辑 **

环顾四周,似乎这是不可能的。我在这里看到了一个答案:https ://stackoverflow.com/a/12015131/649382 谈到删除退出按钮也是可以接受的,但它看起来像代码在 C++ 中,我无法弄清楚它是 C#选择。

** 编辑 2 **

我能够弄清楚到 C# 的转换并将其写为下面的答案。

4

2 回答 2

5

如前所述,没有办法阻止控制台窗口关闭 WPF/应用程序窗口。在 Windows Vista 之前有一些解决方法,但从那时起它们已被删除(可能出于安全原因)。我能够想出的解决方法是禁用控制台窗口上的退出按钮并将显示/隐藏选项放入我的应用程序中。应用程序启动类如下所示:

using System;
using System.Windows;
using System.Runtime.InteropServices;

namespace MyApp
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        public App()
        {
            ConsoleVisible = true;
            DisableConsoleExit();
        }

        #region Console Window Commands

        // Show/Hide
        [DllImport("kernel32.dll")]
        static extern IntPtr GetConsoleWindow();
        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);

        const uint SW_HIDE = 0;
        const uint SW_SHOWNORMAL = 1;
        const uint SW_SHOWNOACTIVATE = 4; // Show without activating
        public static bool ConsoleVisible { get; private set; }

        public static void HideConsole()
        {
            IntPtr handle = GetConsoleWindow();
            ShowWindow(handle, SW_HIDE);
            ConsoleVisible = false;

        }
        public static void ShowConsole(bool active = true)
        {
            IntPtr handle = GetConsoleWindow();
            if (active) { ShowWindow(handle, SW_SHOWNORMAL); }
            else { ShowWindow(handle, SW_SHOWNOACTIVATE); }
            ConsoleVisible = true;
        }

        // Disable Console Exit Button
        [DllImport("user32.dll")]
        static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
        [DllImport("user32.dll")]
        static extern IntPtr DeleteMenu(IntPtr hMenu, uint uPosition, uint uFlags);

        const uint SC_CLOSE = 0xF060;
        const uint MF_BYCOMMAND = (uint)0x00000000L;

        public static void DisableConsoleExit()
        {
            IntPtr handle = GetConsoleWindow();
            IntPtr exitButton = GetSystemMenu(handle, false);
            if (exitButton != null) DeleteMenu(exitButton, SC_CLOSE, MF_BYCOMMAND);
        }

        #endregion
    }
}

希望这可以帮助每个可能有类似问题的人。

于 2013-01-19T19:34:59.260 回答
0

我认为您应该考虑使用AllocConsole创建控制台并使用FreeConsole发布它。这样,您就可以让用户能够在保持 WPF 应用程序运行的同时关闭控制台窗口。

于 2013-01-19T18:04:39.850 回答