【问题标题】:Pass more arguments to an already opened cmd prompt in C#将更多参数传递给 C# 中已打开的 cmd 提示符
【发布时间】:2016-01-25 01:15:36
【问题描述】:

我想遍历文件夹中的所有图像,检索每个图像的名称并使用名称传递一个参数。这就是我所拥有的:

foreach (string imageFile in Directory.EnumerateFiles(filePath))
{
    //Get image name and save it as string
    string args = "something"; //a line of argument with image name in it
    Process.Start("cmd", @"/c cd C:\Tesseract-OCR && " + args);
}

上述代码的问题在于,对于每个图像文件,它都会打开一个新的命令提示符。相反,我想要类似的东西:

Process.Start("cmd", @"/k cd C:\Tesseract-OCR");
foreach (string imageFile in Directory.EnumerateFiles(filePath))
{
    //For each imageFile I have, pass an argument to the opened cmd prompt
}

【问题讨论】:

    标签: c# command-line cmd command-line-arguments command-prompt


    【解决方案1】:

    为什么不让程序创建一个包含所有要执行的文件/命令的批处理文件,然后使用 Process.Start 执行批处理文件?

    【讨论】:

      【解决方案2】:

      您可以使用Directory.GetFiles() 获取目录中所有文件的字符串数组。然后使用String.Join() 将数组合并成一长串以空格分隔的文件名。如果您的路径或文件包含空格,我还会将每个项目用引号引起来。

      const string QUOTE = "\"";
      const string SPACE = " ";
      const string SEPARATOR = QUOTE + SPACE + QUOTE;
      
      string[] files = Directory.GetFiles(filePath, "*.png");
      string allFiles = QUOTE + String.Join(SEPARATOR, files) + QUOTE;
      Console.WriteLine(@"cmd.exe /c cd C:\Tesseract-OCR && " + allFiles);
      

      【讨论】:

        【解决方案3】:

        有几种方法,但通常最简单的方法是创建一个包含您要执行的所有命令的批处理文件,然后将其作为参数传递给cmd

        类似这样的:

        string imageFolder = @"C:\Path\To\Images";
        string batchFile = @"C:\Temp\cmds.cmd";
        string outputFile = @"C:\Temp\cmds.log";
        
        // substitute your own command here.  "{0}" will be substituted for filename 
        string command = @"attrib ""{0}"" >> """ + outputFile + @"""";
        
        // delete the batch file if it exists
        if (File.Exists(batchFile))
            File.Delete(batchFile);
        
        // create batch file from content of image folder
        using (var writer = File.CreateText(batchFile))
        {
            writer.WriteLine("@echo off");
        
            foreach (var file in Directory.EnumerateFiles(imageFolder, "*.jpg"))
                writer.WriteLine(command, file);
        }
        
        // Delete the output file if it exists
        if (File.Exists(outputFile))
            File.Delete(outputFile);
        
        // Execute the batch
        var p = Process.Start("cmd", @"/c """ + batchFile + @"""");
        p.WaitForExit();
        

        完成后,您可以获取输出文件的内容并对其进行解析以获得结果。如果您需要在输出之间休息一下,只需在每个输出之间回显一些独特的东西。可能是这样的:

        // create batch file from content of image folder
        using (var writer = File.CreateText(batchFile))
        {
            writer.WriteLine("@echo off");
        
            foreach (var file in Directory.EnumerateFiles(imageFolder, "*.jpg"))
            {
                writer.WriteLine(@"echo -----Start: {0}>>""{1}""", file, outputFile);
                writer.WriteLine(command, file);
                writer.WriteLine(@"echo -----End: {0}>>""{1}""", file, outputFile);
            }
        }
        

        这样您也可以在输出中获取文件名以帮助解析。


        另一种选择是使用完整的流重定向到可以写入命令和读取响应的流。这将允许您在后台某处运行命令提示符,您可以向其发出命令。看起来很简单,但老实说,要做到恰到好处需要很多工作。如果你想这样做,我建议重定向所有三个标准流。

        【讨论】:

        • 谢谢!效果非常好!只是一个简单的问题:为什么@"tesseract ""{0}"" """ + outputFile + @""""; 而不是更短的@"tesseract {0} " + outputFile;?我看到很多代码都是用你的格式写的,一直想知道为什么。
        • 这样您就可以根据需要在文件名中使用空格,用于源文件或输出文件。
        猜你喜欢
        • 1970-01-01
        • 2020-05-29
        • 2022-01-05
        • 2018-09-29
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-05
        相关资源
        最近更新 更多