如何在隐藏控制台的情况下运行C#控制台应用程序


140

执行控制台应用程序时,是否可以隐藏控制台窗口?

我目前正在使用Windows Forms应用程序启动控制台进程,但是我不希望在任务运行时显示控制台窗口。


尝试从计划的任务中运行控制台应用程序。

Answers:


158

如果使用ProcessStartInfo该类,则可以将窗口样式设置为隐藏-对于控制台(不是GUI)应用程序,必须将CreateNoWindow设置为true

System.Diagnostics.ProcessStartInfo start =
      new System.Diagnostics.ProcessStartInfo();
start.FileName = dir + @"\Myprocesstostart.exe";
start.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; //Hides GUI
start.CreateNoWindow = true; //Hides console

26
这就是我要发布的内容:)
乔恩·斯基特

75
废话-比琼快的人!=)
Erik Forbes,2009年

75
我必须节制他的互联网连接才能击败他;)
亚当·马科维兹

11
它不适用于调用命令行工具。使用了yourprocess.StartInfo.CreateNoWindow = true; 相反,请参见下文。
2014年

12
不隐藏控制台窗口,StartInfo.CreateNoWindow = true是必需的。
丹尼尔(Daniel)

201

如果您编写了控制台应用程序,则可以默认将其隐藏。

创建一个新的控制台应用程序,然后将“输出类型”类型更改为“ Windows应用程序”(在项目属性中完成)


6
我试图隐藏自己的控制台,而不是调用其他东西然后将其隐藏(就像公认的答案一样)-所以这对我来说是最好的。谢谢!
令人厌恶的2012年

6
谢谢哥们 !这也是我一直在寻找的!
Varun Sharma

3
接受的答案假定是因为问题中已说明。
AQUA

简单way..really喜欢it..we当然不希望显示怎么一回事,因为它要推出从它的另一个过程我..窗口
西阿维纳什

1
这可以解决ProcessStartInfo的问题,您可以在其中指定用户凭据,而该用户恰好是登录用户或当前用户。在这种情况下,CreateNoWindow属性将被忽略,因此您始终会获得一个控制台窗口。通过将控制台应用程序设置为Windows应用程序但没有窗口,则不会显示任何窗口。
tjmoore

67

如果您使用的是Process Class,则可以编写

yourprocess.StartInfo.UseShellExecute = false;
yourprocess.StartInfo.CreateNoWindow = true;

之前yourprocess.start();和过程将被隐藏


4
祝您好运,如果您必须尽早停止该过程。Process.Kill突然终止。Process.CloseMainWindow失败。GenerateConsoleCtrlEvent无法将ctrl + c或ctrl + break发送给进程。对进程中的所有线程窗口执行WM_CLOSE失败。似乎没有办法彻底结束以这两个参数值开始的过程。在这里看到我的问题:stackoverflow.com/questions/16139571/…–
Triynko

感谢吨,这是最简单的。另外,如果您拥有(或部门)控制台代码,我会发现此互斥锁示例最容易进行干净关闭。 stackoverflow.com/a/31586184/1877412
cbuteau

1
@Triynko:您不能彻底终止任何进程,除非该进程积极配合。这不是标志或其他任何问题。操作系统中没有任何东西可以触发干净关闭。常见的解决方案是使用一个可等待的内核对象,该对象在控制过程中发出信号,即从属进程应终止。从属进程需要主动监视此等待对象的状态,并在发出信号后启动干净关闭。
IInspectable

43

简单的答案是:转到控制台应用程序的属性(项目的属性)。在“应用程序”选项卡中,只需将“输出类型”更改为“ Windows应用程序”。就这样。


4
靶心。这与创建不调用任何窗体的Windows应用程序相同。
ashes999 2011年

1
这是正确的答案。您没有其他创可贴的方法。这是实际的正确答案。您希望您的应用程序从不首先打开控制台。另外,您希望能够随时打开一个表单。因此,您只在需要时调用表格。即,当用户右键单击系统任务栏图标并选择首选项时,将调用我们的表单。这是正确的答案!!!
Bluebaron

20

您可以使用FreeConsole API从过程中分离控制台:

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

(当然,这仅在您有权访问控制台应用程序的源代码时适用)


我不想显示控制台。虽然FreeConsole做什么它的名字一样,它不会阻止Windows显示它被调用之前控制台。
贾德·迪亚斯

5
然后将项目编译为Windows应用程序,而不是控制台应用程序
Thomas Levesque 2010年

1
记录下来,这正是所需要的,谢谢。这正是标题所要求的:)因此,为了其他Google航海家的利益,+ 1
sehe 2011年

3
除了[DllImport("kernel32.dll")] static extern bool AllocConsole();让你轻松运行从一个标准的Win32应用程序控制台
sehe

1
适用于我的.NET Core 2.2应用程序-如果有人正在专门寻找它。
Medismal

7

如果您对输出感兴趣,可以使用以下功能:

private static string ExecCommand(string filename, string arguments)
{
    Process process = new Process();
    ProcessStartInfo psi = new ProcessStartInfo(filename);
    psi.Arguments = arguments;
    psi.CreateNoWindow = true;
    psi.RedirectStandardOutput = true;
    psi.RedirectStandardError = true;
    psi.UseShellExecute = false;
    process.StartInfo = psi;

    StringBuilder output = new StringBuilder();
    process.OutputDataReceived += (sender, e) => { output.AppendLine(e.Data); };
    process.ErrorDataReceived += (sender, e) => { output.AppendLine(e.Data); };

    // run the process
    process.Start();

    // start reading output to events
    process.BeginOutputReadLine();
    process.BeginErrorReadLine();

    // wait for process to exit
    process.WaitForExit();

    if (process.ExitCode != 0)
        throw new Exception("Command " + psi.FileName + " returned exit code " + process.ExitCode);

    return output.ToString();
}

它运行给定的命令行程序,等待它完成并以字符串形式返回输出。


4

如果要创建不需要用户输入的程序,则始终可以将其创建为服务。服务不会显示任何类型的UI。


但是,如果您只想运行该过程直到退出,例如通过从“任务计划程序”中调用它,那么服务将不便,因为它继续存在。在某些情况下,将“输出类型”更改为“ Windows应用程序”,而不是将“ ProcessWindowStyle”替换为“隐藏”是非常方便的。
subsci 2014年

2

将此添加到您的类以导入DLL文件:

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

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

const int SW_HIDE = 0;
const int SW_SHOW = 5;

然后,如果要隐藏它,请使用以下命令:

 var handle = GetConsoleWindow();
 ShowWindow(handle, SW_HIDE);

如果要显示控制台:

var handle = GetConsoleWindow();
ShowWindow(handle, SW_SHOW);

1
[DllImport(“ user32.dll”)]静态外部布尔ShowWindow(IntPtr hWnd,int nCmdShow); [DllImport(“ kernel32.dll”)]静态外部IntPtr GetConsoleWindow(); const int SW_HIDE = 0; const int SW_SHOW = 5;
soulmachine

1

我知道我没有完全回答您想要的内容,但是我想知道您是否在问正确的问题。

您为什么不使用:

  1. Windows服务
  2. 创建一个新线程并在该线程上运行您的进程

如果您只想运行一个进程,这些听起来是更好的选择。


3
在很多情况下,启动实用程序控制台应用程序都是完全合法的。
亚当·罗宾逊

在我的情况下,由于我正在使用的软件使用的客户端/服务器模型,因此需要一个单独的过程。
亚伦·托马斯

创建新线程并不总是解决问题。有时候,您只是不想在后台看到烦人的窗口。另外,如果您有一个process.start循环运行,那么您将无法完成任何工作,因为控制台窗口突然弹出。
user890332'2

1
我从任务计划程序启动无窗口实用程序控制台应用程序。无需服务,也没有派生线程的父进程。如果需要其他输出,这些应用程序将写入EventLog。
subsci 2014年

1

尽管如此处其他答案所述,您可以将“输出类型”更改为“ Windows应用程序”,但是请注意,这将意味着您将无法使用Console.In它,因为它将成为NullStreamReader。

Console.Out并且Console.Error似乎仍然可以正常工作。


2
你是认真的吗?Console.In没有控制台输入内容时,为什么有人会使用?可以从哪里访问什么东西Console.In?这根本没有任何意义。换句话说:这完全是显而易见的,合乎逻辑的Console.InNullStreamReader在这种情况下。
罗伯特·S。

1
@RobertS。可能是管道。即另一个程序的输出。当我发现这一点时,这就是我的用例。
kjbartel'2

1

基于Adam Markowitz的上述回答,以下对我有用:

process = new Process();
process.StartInfo = new ProcessStartInfo("cmd.exe", "/k \"" + CmdFilePath + "\"");
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
//process.StartInfo.UseShellExecute = false;
//process.StartInfo.CreateNoWindow = true;
process.Start();

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>“项目”>“属性”>“应用程序”中的设置以作为Windows应用程序而不是控制台应用程序启动,并且有关我的项目的某些操作阻止了它隐藏我的控制台-可能是因为DSharpPlus要求在启动时启动控制台。我不知道。不管是什么原因,此类都可以让我在弹出控制台后轻松终止控制台。

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


0

写就好了

ProcessStartInfo psi= new ProcessStartInfo("cmd.exe");
......

psi.CreateNoWindow = true;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.