隐藏Process.Start中的控制台窗口 C#

130

我正在尝试使用System.Diagnostics.Process类在远程计算机上创建进程。 我能够创建一个进程。但问题是,创建服务需要很长时间并显示控制台窗口。 另一件令人恼火的事情是,控制台窗口显示在我的Windows窗体的顶部,我无法对该窗体进行任何其他操作。 我已经设置了所有属性,例如CreateNoWindow = true

proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden

但仍然会显示控制台窗口,即使我已经将输出和错误重定向到不同的流中,但没有成功。

是否有其他方法可以隐藏控制台窗口?请帮帮我。

这是我用来执行sc命令的代码部分。

Process proc = new Process();
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo.FileName = "sc";
proc.StartInfo.Arguments = string.Format(@"\\SYS25 create MySvc binPath= C:\mysvc.exe");
proc.StartInfo.RedirectStandardError = false;
proc.StartInfo.RedirectStandardOutput = false;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
proc.WaitForExit();

你尝试过设置 proc.StartInfo.RedirectedStandardOutput = true 吗?我曾经在 Windows 应用程序中成功使用过。 - poy
有没有完整的源代码示例,可以作为最终解决方案? - Kiquenet
在 Windows 控制台 应用程序中,仅设置 UseShellExecute - 不需要重定向或其他任何内容 - 对我有效。请参见此处 - Paul
关于控制台窗口打开并锁定表单,您应该将进程作为任务或在新线程上运行。 - Ryan Dooley
2
为什么你要两次设置 UseShellExecuteCreateNoWindow - Mike Lowery
4个回答

160

当我尝试启动一个进程而不显示控制台窗口时,我遇到了类似的问题。我尝试了几种不同的属性值组合,直到找到一个符合我期望行为的组合。

这是一个页面详细说明为什么必须将UseShellExecute属性设置为false。
http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.createnowindow.aspx

在页面的备注部分:

如果UseShellExecute属性为true或UserName和Password属性不为null,则CreateNoWindow属性值将被忽略并创建一个新窗口。

ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = fullPath;
startInfo.Arguments = args;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;

Process processTemp = new Process();
processTemp.StartInfo = startInfo;
processTemp.EnableRaisingEvents = true;
try
{
    processTemp.Start();
}
catch (Exception e)
{
    throw;
}

2
是否可以添加一些额外的细节?重点是为什么这个方法可行,而不是如何实现。 - aqua
2
是因为标准输出强制窗口存在吗? - Denise Skidmore
1
@Fyodor 参考这里,但如果你有无法正常工作的可重现情况,请在 Meta 上发布一个错误报告。 - rene
22
我永远不会理解为什么有些人会捕获他们又要抛出的异常。 - Blindy
3
我在这段代码中使用try catch主要是为了简洁明了(表明这部分代码可能会抛出异常,需要采取行动)。过去,我重新抛出异常的原因是因为在我的应用程序中,该代码是使用codedom、reflection和csharpcodeprovider执行的。重新抛出异常使其可以冒泡到更高层的代码中,而不会在堆栈跟踪中添加额外的异常(如果我记得正确的话)。我不完全确定这是必要的,但这只是我创建该应用程序的方式。 - John Bartels
显示剩余6条评论

64

我对这个答案和过程(Wix light.exe)的运行遭遇了不好的运气,基本上就是出去吃午餐了,晚上却没有回来。但是,下面的方法对我很有效:

Process p = new Process();
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
// etc, then start process

2
对我很有用 - 简单明了! - J c
2
这真的应该成为被接受的答案。运行得非常好。 - Eternal21
3
CreateNoWindow = true 对我没用,但这个可以 :) - Stefan Monov
3
仅适用于带有窗口的应用程序,控制台应用程序仍会显示窗口。 - Geograph
太棒了,对我有用。我正在执行批处理文件,这个答案帮了我一个大忙。 - bonny

27

这应该可以工作,试试看;


添加一个系统引用。

using System.Diagnostics;

然后使用此代码在隐藏的CMD窗口中运行您的命令。

Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
cmd.StartInfo.Arguments = "Enter your command here";
cmd.Start();

15

这不会显示窗口:

Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
cmd.StartInfo.CreateNoWindow = true;

...
cmd.Start();

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