C#使用cmd执行.exe文件,并在程序关闭时关闭打开的进程
程序员文章站
2022-07-12 18:55:38
...
本来是参考网上的来自酷小孩的一段代码(博主吐槽非常正确),如下:
string str = Console.ReadLine();
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动
p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
p.StartInfo.CreateNoWindow = true;//不显示程序窗口
p.Start();//启动程序
//向cmd窗口发送输入信息
p.StandardInput.WriteLine(str + "&exit");
p.StandardInput.AutoFlush = true;
//获取cmd窗口的输出信息,在执行这一行后C#调用了.exe文件执行
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();//等待程序执行完退出进程
p.Close();
Console.WriteLine(output);
直接使用这段代码进行多行命令行执行时会出现这么一个问题:可能执行了几行之后就停止了,具体原因没有找到,但是通过国外网友提供的一个官方文档的例子中对代码进行修改后可以正常运行,网址如下:https://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardinput.aspx
为了进行对比我将代码注释进行了一定量的删除,先介绍我的需求情况:需要使用命令行调用一个.exe程序对多个视频进行处理,由于视频路径比较长,视频数量大导致文本长度超过了cmd一次输入文本的长度,因此需要分成多行输入处理,暂时不需要回显cmd的输出,将代码更改如下:
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动
p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
p.StartInfo.RedirectStandardOutput = false;//不需要获取输出信息
p.StartInfo.RedirectStandardError = true;//不需要重定向标准错误输出,但false时下面的指令未执行
p.StartInfo.CreateNoWindow = true;//不显示程序窗口
p.Start();//启动程序
StreamWriter mySR = p.StandardInput;
//向cmd窗口发送输入信息
for (int nowIdx = 0; nowIdx < videos.Length; nowIdx++)
{
//str表示一行命令
mySR.WriteLine(str);
//这里的Flush()操作和我理解的不一样,尽管flush了但是命令行并没有立即执行
//而且当需要执行的命令行数量十分多的时候,在使用了WriteLine后会在随机行数之后值执行,可能与缓冲区大小有关
mySR.Flush();
}
//这个地方我对于原文所提供的exit和&exit的区别没有完全弄清,以后可能进行补充
p.StandardInput.WriteLine("&exit");
//关闭StreamWriter后,之前输入的命令行会立即执行
mySR.Close();
p.WaitForExit();
p.Close();
这里这么写会遇到一个问题,有些程序是不会自己停止的,亦或者在启动了该程序之后需要执行其他的代码,这个时候如果使用Process.WaitForExit()会使程序陷入循环(若是会自动结束,则会在结束后执行后面的代码)。因此需要做出一点改变,我是在C# WinForm程序中使用的,因此可以在Form窗体退出时结束程序。
#重写并绑定窗口退出事件
protected override void OnClosing(CancelEventArgs e)
{
#将p定义为public static变量,可以在其他文件中调用
if(nameSpace.p != null)
{
#获取进程并关闭
Process[] pro = Process.GetProcessesByName("打开的进程的名字");
pro[0].Kill();
}
base.OnClosing(e);
}
上一篇: 关闭brew执行命令时的自动更新
下一篇: 过滤HTML