【问题标题】:How can I hide a console window?如何隐藏控制台窗口?
【发布时间】:2011-04-03 14:05:02
【问题描述】:

问题:我有一个不应该看到的控制台程序。 (它会重置 IIS 并删除临时文件。)

现在我可以像这样在启动后立即隐藏窗口:

static void Main(string[] args)
{
    var currentProcess = System.Diagnostics.Process.GetCurrentProcess();
    Console.WriteLine(currentProcess.MainWindowTitle);

    IntPtr hWnd = currentProcess.MainWindowHandle;//FindWindow(null, "Your console windows caption"); //put your console window caption here
    if (hWnd != IntPtr.Zero)
    {
        //Hide the window
        ShowWindow(hWnd, 0); // 0 = SW_HIDE
    }

问题是这会显示窗口一秒钟。 是否有任何控制台程序的构造函数,我可以在窗口显示之前将其隐藏?

第二个:

我用

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

我不喜欢里面的 32。没有 DllImport 有没有办法做到这一点?
.NET 方式?

【问题讨论】:

  • 你为什么不喜欢user32.dll这个名字?
  • user32.dll 不是专门的 32 位 DLL,并且适用于所有当前版本的 Windows,无论体系结构如何。这个名字是可以追溯到 NT4 的遗产。

标签: c# .net vb.net winapi console


【解决方案1】:

如果您不需要控制台(例如 Console.WriteLine),则将应用程序构建选项更改为 Windows 应用程序。

这会更改 .exe 标头中的标志,因此 Windows 在应用程序启动时不会分配控制台会话。

【讨论】:

  • 或者让它成为一个windows服务,虽然它会有不同的生命周期
  • 创建一个 Windows 应用,不要创建一个 Windows 窗体
  • @Grand Crofton:服务用于长时间运行或重复的后台任务,而不是用于用户触发的操作,如 IIS 重置。所以这里的服务似乎不合适。除非你想每 5 分钟左右重置一次 IIS,当然 ;-)
  • @0xA3:重复后台任务不应作为服务实现,而应作为计划任务实现。让一个服务永远运行,而它实际上每隔几分钟就执行一次,这会浪费内存、cpu 时间、编码时间(编写服务比控制台应用程序复杂得多)和维护。此外,如果您有内存泄漏,它会在服务中随着时间的推移而增长,在计划任务中,一旦任务完成,进程就会被终止,因此几乎没有影响。
  • @Quandary:Win32 API AllocConsole 将为没有控制台的进程创建一个控制台窗口。但目前尚不清楚Console.Out 等是否会自动连接,或者您需要使用Console.OpenStandardOutput 等。
【解决方案2】:

如果我理解您的问题,只需手动创建控制台进程并隐藏控制台窗口:

Process process = new Process();
process.StartInfo.FileName = "Bogus.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true;

我为 WPF 应用程序执行此操作,该应用程序执行控制台应用程序(在后台工作程序中)并重定向标准输出,以便您可以在需要时在窗口中显示结果。如果您需要查看更多代码(工作代码、重定向、参数传递等),请告诉我。

【讨论】:

  • @Si:我认为OP希望能够通过双击启动“无窗口控制台程序”,例如,不一定以编程方式从另一个程序中启动。
  • 是的,我不确定,以前也有同样的需求。我无法捕获的一件事是彩色 ANSI 控制台输出到 WPF。见stackoverflow.com/questions/1529254/…
【解决方案3】:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FreeConsole();

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern IntPtr GetStdHandle([MarshalAs(UnmanagedType.I4)]int nStdHandle);

// see the comment below
private enum StdHandle
{
    StdIn = -10,
    StdOut = -11,
    StdErr = -12
};

void HideConsole()
{
    var ptr = GetStdHandle((int)StdHandle.StdOut);
    if (!CloseHandle(ptr))
        throw new Win32Exception();

    ptr = IntPtr.Zero;

    if (!FreeConsole())
        throw new Win32Exception();
}

查看更多与控制台相关的 API 调用here

【讨论】:

  • 请注意,不是throw new PInvokeExcpetion() 通常throw new Win32Exception()throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); 就足够了。使用Win32Exception(),您不必自己打电话给GetLastError,然后将错误代码映射到有意义的消息。一切都已为您完成。
  • 你真的应该在你的例子中包含 GetStdHandle (我使用枚举来明确 int 是什么,而不是仅仅使用 -11..) ** private enum StdHandle { Stdin = -10 , 标准输出 = -11, 标准错误 = -12 };私有静态外部 IntPtr GetStdHandle(StdHandle std); **
  • @Bostwick:更新自 here。谢谢!
【解决方案4】:
    [DllImport("user32.dll")]
    public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    [DllImport("kernel32")]
    public static extern IntPtr GetConsoleWindow();
    [DllImport("Kernel32")]
    private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);

    static void Main(string[] args)
    {
        IntPtr hConsole = GetConsoleWindow();
        if (IntPtr.Zero != hConsole)
        {
            ShowWindow(hConsole, 0); 
        }
    }

这应该满足你的要求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-10
    • 1970-01-01
    • 2014-08-23
    • 2019-07-22
    • 2012-10-14
    • 2012-10-14
    • 2010-10-10
    相关资源
    最近更新 更多