【问题标题】:Check to see if CMD is idle when used as a process检查CMD作为进程使用时是否空闲
【发布时间】:2025-12-01 04:50:02
【问题描述】:

问题:传递给 CMD 实用程序的文件数量存在问题。

所需的解决方案:能够在递增循环之前检查 CMD 是否已完成文件转换的方法。

我正在使用 C# 中的用户界面在 CMD 中运行实用程序。该实用程序将音频文件从 .vce 转换为 .wav。如果选择了超过 30 个文件,该实用程序就会不堪重负并停止工作。如何在循环递增之前检查它是否已完成一个文件转换? .WaitForExit().WaitForProcessIdle() 都不起作用。

//arguments are a list of files selected by the user for conversion, 
//the folder to save the converted files in, and the path that the 
//current files are under
public static void convertVCE(List<string> files, string newPath, string filePath)
{
    Process process1 = new Process();
    process1.StartInfo.FileName = "cmd.exe";
    process1.StartInfo.CreateNoWindow = false;
    process1.StartInfo.RedirectStandardInput = true;
    process1.StartInfo.RedirectStandardOutput = true;
    process1.StartInfo.UseShellExecute = false;
    process1.Start();
    //move to directory where the utility is
    process1.StandardInput.WriteLine("cd \\Program Files (x86)\\NMS Utilities");
    process1.StandardInput.Flush();

    //loop to convert each selected file
    for (int i = 0; i < files.Count; i++)
    {
        if (files[i].EndsWith(".vce"))
        {
            string fileName = Path.Combine(filePath, files[i]);
            string newFileName = Path.Combine(newPath, files[i]).Replace(".vce", "");
                
            process1.StandardInput.WriteLine(string.Format("vcecopy.exe {0} {1}.wav", fileName, newFileName));
            process1.StandardInput.Flush();
        }
    }
    process1.StandardInput.Close();
    Console.WriteLine(process1.StandardOutput.ReadToEnd());
    process1.WaitForExit();
}

【问题讨论】:

  • 为什么要启动 cmd.exe 进程?启动 vcecopy 进程并等待该进程空闲。
  • 你能用 process1.StandardOutput.ReadToEnd(); 查找输出吗?并将其用作完成指标?
  • 根据您的描述,听起来 vcecopy.exe 不是控制台应用程序 - 否则 cmd.exe 会等待它完成。您是否考虑过使用 start /wait 来等待 vcecopy.exe 的实例退出,然后再开始下一个。
  • 是的,您一次创建一个 vcecopy.exe 进程并等待它完成,然后再启动下一个。这就是你想要的不是吗?我不明白您的文件名问题,只需通过 de ProcessStartInfo.Arguments 属性在每次启动时定义相应的参数即可。
  • 什么窗口?如果 vcecopy 不需要它们,则不需要打开任何窗口。您正在创建的唯一窗口是 cmd.exe 并且您不需要它,您可以在没有 cmd.exe 的情况下启动所有 vcecopy 执行,如果可以无窗口运行,则无需应用程序的单个窗口。

标签: c# cmd process


【解决方案1】:

您正在创建一个不需要的 cmd.exe 进程。您需要创建 vcecopy.exe 进程并在启动它们时等待它们完成。大致如下(我现在无法对此进行测试,我正在对内存进行编码,但你应该明白这一点):

var vceCopyStartInfo = new StartInfo();
vceCopyStartInfo.CreateNoWindow = true;
vceCopyStartInfo.UseShellExecute = false;
vceCopyStartInfo.WorkingDirectory = "\\Program Files (x86)\\NMS Utilities";
vceCopyStartInfo.FileName = "vcecopy.exe";

for (int i = 0; i < files.Count; i++)
{
    if (files[i].EndsWith(".vce"))
    {
        string fileName = Path.Combine(filePath, files[i]);
        string newFileName = Path.Combine(newPath, files[i]).Replace(".vce", "");
        //some applications need arguments in quotes, try it if this doesn't work.
        vceCopyStartInfo.Arguments = string.Format("{0} {1}.wav", fileName, newFileName));

        using (var vceCopyProcess = Process.Start(vceCopyStartInfo))
        {
            vceCopyProcess.WaitForExit();
            //if vcecopy doesn't exit by itself when it finishes, try WaitForProcessIdle
        }
    }
}

【讨论】:

  • 这太棒了!我已经做了一些你建议的事情,但“WaitForExit”是最重要的。谢谢你的帮助。这适用于大量文件。