【发布时间】:2010-10-24 14:23:06
【问题描述】:
有没有办法在执行控制台应用程序时隐藏控制台窗口?
我目前正在使用 Windows 窗体应用程序来启动控制台进程,但我不希望在任务运行时显示控制台窗口。
【问题讨论】:
-
尝试从计划任务运行控制台应用程序。
有没有办法在执行控制台应用程序时隐藏控制台窗口?
我目前正在使用 Windows 窗体应用程序来启动控制台进程,但我不希望在任务运行时显示控制台窗口。
【问题讨论】:
如果您使用 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
【讨论】:
我知道我没有准确回答你想要的,但我想知道你是否问对了问题。
你为什么不使用任何一个:
如果您只想运行一个进程,这些听起来像是更好的选择。
【讨论】:
您可以使用FreeConsole API 将控制台与进程分离:
[DllImport("kernel32.dll")]
static extern bool FreeConsole();
(当然这仅适用于您可以访问控制台应用程序的源代码)
【讨论】:
FreeConsole 的功能与它的名字一样,但它不会阻止 Windows 在调用它之前显示控制台。
[DllImport("kernel32.dll")] static extern bool AllocConsole(); 允许您从标准 Win32 应用程序使用控制台轻松运行
如果您正在创建一个不需要用户输入的程序,您始终可以将其创建为服务。服务不会显示任何类型的 UI。
【讨论】:
如果您编写了控制台应用程序,则可以将其默认隐藏。
创建一个新的控制台应用程序,然后将“输出类型”类型更改为“Windows 应用程序”(在项目属性中完成)
【讨论】:
如果你使用的是进程类,那么你可以写
yourprocess.StartInfo.UseShellExecute = false;
yourprocess.StartInfo.CreateNoWindow = true;
在yourprocess.start(); 之前,进程将被隐藏
【讨论】:
简单的答案是:转到控制台应用程序的属性(项目的属性)。在“应用程序”选项卡中,只需将“输出类型”更改为“Windows 应用程序”。就是这样。
【讨论】:
虽然这里的其他答案说您可以将“输出类型”更改为“Windows 应用程序”,但请注意,这意味着您不能使用 Console.In,因为它将成为 NullStreamReader。
Console.Out 和 Console.Error 似乎仍然可以正常工作。
【讨论】:
Console.In?可以通过Console.In 访问的东西应该来自哪里?这根本没有任何意义。换句话说:在这种情况下,Console.In 是 NullStreamReader 是完全明显和合乎逻辑的。
如果你对输出感兴趣,可以使用这个函数:
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();
}
它运行给定的命令行程序,等待它完成并将输出作为字符串返回。
【讨论】:
将此添加到您的类以导入 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);
【讨论】:
随便写
ProcessStartInfo psi= new ProcessStartInfo("cmd.exe");
......
psi.CreateNoWindow = true;
【讨论】:
根据上面 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();
【讨论】:
我有一个通用的解决方案要分享:
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 要求启动一个启动时控制台。我不知道。不管是什么原因,这个类让我可以在控制台弹出后轻松杀死它。
希望这位魔术师能帮助别人。 ;)
【讨论】: