如何在C#中隐藏控制台应用程序

29

我有一个 C# 控制台应用程序,我希望用户无法看到它。

我该如何做到这一点?


3
你想要在后台运行的服务吗? - Matt Ellen
是的,但我不想将它作为服务运行,我想将其作为.exe文件运行。 - menacheb
应用程序该如何启动? - noocyte
自动地,从启动目录开始。 - menacheb
在程序运行时,还有一种方法可以显示和隐藏控制台窗口 - Timwi
你在那个控制台应用程序里在做什么? 如果它需要持续运行,你可以尝试使用Windows服务。 - Kamran Shahid
9个回答

55
将其编译为Windows窗体应用程序。如果您没有显式打开任何Windows,则不会显示任何UI。

不是很好的想法。为什么要改变整个基线,只是为了不显示控制台窗口呢? - Nayan
@Nayan:你说的“基线”是什么?只需要在项目属性中更改“输出类型”即可。只需两秒钟。 - Allon Guralnek
我对速度很放心。我谈论的是设计变更、程序集依赖性、庞大的可执行文件以及由于不必要的程序集引用和实现一些抽象和接口而导致的膨胀。我在谈论没有思考就进行设计修改的问题。 - Nayan
5
@Nayan,不需要进行任何设计更改。没有人说您应该实现任何接口或参考任何程序集。只是切换编译模式,这实际上只是在程序集中设置一个标志,“我是控制台程序”对“我是Windows程序”。事实上,您可以仅引用mscorlib并将其编译为Windows程序。 - driis
@driis:我大部分同意你的观点。但我的观点是,这并不总是那么简单,因为控制台程序应该在控制台中运行(它可能有访问GUI组件的权限),反之亦然,如果你真的想把它复杂化的话。最终,决定什么实际上适用于他的是OP。我只提供了我版本的美学编码实践。 - Nayan

15

在 ProjectProperties 中将“Output Type”设置为 Windows 应用程序。


5
创建一个名为"MyAppProxy"的控制台应用程序,包含以下代码,并将MyAppProxy放置在启动目录中。
public static void main(string[] args)
{
   Process p = new Process("MyApp");
   ProcessStartUpInfo pinfo = new ProcessStartUpInfo();
   p.StartupInfo = pinfo;
   pinfo.CreateNoWindow = true;
   pinfo.ShellExecute = false;

   p.RaiseEvents = true;

   AutoResetEvent wait = new AutoResetEvent(false);
   p.ProcessExit += (s,e)=>{ wait.Set(); };

   p.Start();
   wait.WaitOne();
}

您可能需要在这里修复某些项目,因为我没有检查代码的正确性,它可能无法编译,因为某些属性名称可能不同,但希望您能理解。


5
听起来你不需要一个控制台应用程序,而是一个不打开(可见)窗口的Windows GUI应用程序。

2

2

当其他方法无效时,可以使用以下代码在C#中隐藏控制台应用程序:

[DllImport("kernel32.dll")]
public static extern bool FreeConsole();

在代码中的任何位置放置FreeConsole(),我将其放置在Init()中,这样命令行就会被隐藏。


这似乎比仅仅做那个要棘手一些。当您使用FreeConsole()从其控制台分离进程时,控制台将被终止。您必须记得在完成工作时终止进程,因为没有控制台可以为您执行此操作,除非我漏了什么(如果我错了,请告诉我)。尽管如此,这是一个非常简洁的方法。 - B.K.

1

你可以使用Pinvoke调用FindWindow()来获取窗口句柄,然后调用ShowWindow()来隐藏窗口 或者 使用ProcessStartInfo.CreateNoWindow从另一个应用程序启动你的应用程序


我不知道那是否有效,但它确实读起来很有趣! :) 调用ShowWindow()来隐藏它... ;) - noocyte
与其使用笨拙的FindWindow()解决方案,我更喜欢正确地检索控制台句柄 - Timwi

1
我有一个通用的解决方案要分享:

using System;
using System.Runtime.InteropServices;

namespace WhateverNamepaceYouAreUsing
{
    class Magician
    {
    [DllImport("kernel32.dll")]
        static extern IntPtr GetConsoleWindow();

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

        const int HIDE = 0;
        const int SHOW = 5;

        public static void DisappearConsole()
        {
            ShowWindow(GetConsoleWindow(), HIDE);
        }
    }
}

只需将此类包含在您的项目中,然后调用Magician.DisappearConsole();

当通过单击启动程序时,控制台会闪烁。当从命令提示符执行时,命令提示符会在执行后很短时间内消失。

我为一个在我的计算机后台作为不可见进程永久运行的Discord Bot这样做。这比让TopShelf为我工作要容易得多。在我编写这篇文章之前,我尝试了几个TopShelf教程,但都失败了,最后在其他地方找到了一些代码的帮助。;P

我还尝试简单地更改Visual Studio > Project > Properties > Application中的设置,以将其启动为Windows应用程序而不是控制台应用程序,但由于DSharpPlus需要在启动时启动控制台,因此我的项目中的某些内容阻止了这种方式隐藏我的控制台。我不知道原因。无论原因如何,这个类允许我轻松地在弹出控制台后关闭它。

希望这位魔术师能帮助到某人。;)


-3
创建一个 WCF 服务,并根据您的需求进行托管。

1
我认为这是误导性的,并且完全走错了方向。一个隐藏应用程序的用途可能完全不同于WCF服务。 - ericosg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接