我在C#中按顺序启动多个进程时遇到一些问题。我试图开始的这些过程或多或少花了30秒来完成他的程序。而且我不希望这些流程从任何应用程序中窃取焦点。我尝试了两种方法(以下代码进入循环语句):
myProcess.StartInfo.UseShellExecute = true;
myProcess.StartInfo.FileName = "References\\InclinacaoHGrid.exe";
myProcess.StartInfo.CreateNoWindow = true;
myProcess.StartInfo.Arguments = i.ToString() + " " + j.ToString() + " " +
valA + " " + valS + " " + valP + " " + pathNodes;
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(myProcess_Exited);
myProcess.OutputDataReceived += new DataReceivedEventHandler(myProcess_OutputDataReceived);
myProcess.Start();
myProcess.WaitForExit();
使用Interaction.Shell和参数“AppWinStyle.MinimizedNoFocus”:
int pid = Interaction.Shell("References\\InclinacaoHGrid.exe " + i.ToString() + " " + j.ToString() + " " +
valA + " " + valS + " " + valP + " " + pathNodes, AppWinStyle.NormalNoFocus,true);
这两种方法对我不起作用,因为过程(或开始和结束过程的动作)正在从任何应用程序中窃取焦点。我的应用程序运行时无法执行任何操作。
答案 0 :(得分:2)
变化:
myProcess.StartInfo.UseShellExecute = true;
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
分为:
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
您的示例中似乎不需要UseShellExecute
,因为您直接运行可执行文件,因此在这种情况下不需要shell。
但请注意,将UseShellExecute
更改为false会产生以下影响:
当UseShellExecute为false时,不是WorkingDirectory属性 用于查找可执行文件。相反,它仅由进程使用 这是开始的,只有在新的背景下才有意义 处理。当UseShellExecute为false时,FileName属性必须为 可执行文件的完全限定路径。
除非你真的想等待进程退出,否则不要使用myProcess.WaitForExit();
。
WaitForExit()重载用于使当前线程等待 直到相关的进程终止。这个方法指示 处理组件为进程等待无限长的时间 和事件处理程序退出。这可能导致应用程序停止 响应。
有关ProcessWindowStyle
枚举和可能值的详细信息,另请参阅this。
答案 1 :(得分:0)
代码
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
像Johannes Kommer suggested这样的不适用于我。原因the doc说:
要使用“隐藏”,UseShellExecute属性必须为true。
但是我发现startInfo.CreateNoWindow = true;
与startInfo.WindowStyle = ProcessWindowStyle.Hidden;
的效果相同
以下是完全隐藏该Process窗口的代码:
var startInfo = new ProcessStartInfo();
startInfo.FileName = "E:\ffmpeg.exe";
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.Arguments = "-i \"E:\\Download\\Video\\Test\\20.mp4\" -ss 00:00:20 -vframes 1 \"E:\\Download\\Video\\Thumbs\\20.png\"";
using (var proc = Process.Start(startInfo))
{
proc.WaitForExit();
//Beware, there is case the exe ask for user confirmation
//But the the Process Windows is hidden, thus user can't choose Y/N
//Thus the proc never exit.
}
The
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
可以替换为
startInfo.UseShellExecute = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
并且进程的窗口被隐藏,您的焦点没有被窃取。但是,当流程要求您确认时,问题就出现了(例如:覆盖现有文件[Y / N]?),但是该窗口是隐藏的,因此您无法选择[Y / N],因此卡住了。如果您不喜欢这样,请阅读我的“最小化解决方案”。
焦点仍然被盗,但是焦点已被最小化,因此它不会突然出现在您的脸上,当它要求确认时,请打开并选择Y
。这是最小化的代码:
var startInfo = new ProcessStartInfo();
startInfo.FileName = "E:\ffmpeg.exe";
startInfo.WindowStyle = ProcessWindowStyle.Minimized;
startInfo.Arguments = "-i \"E:\\Download\\Video\\Test\\20.mp4\" -ss 00:00:20 -vframes 1 \"E:\\Download\\Video\\Thumbs\\20.png\"";
using (var proc = Process.Start(startInfo))
{
proc.WaitForExit();
}