Проблемы запуска процесса с Process.Start () - как мне создать список аргументов? - PullRequest
1 голос
/ 04 июня 2009

У меня есть это:

string cmd = " -i """ + finPath + """ -ar 44100 -ab 160k """ + foutPath + """";

и мне нужно передать его в командную строку из C #, используя Systems.Diagnostics.Process.

Кажется, ни одна комбинация не работает. Программа работает нормально, если я запускаю ее в командной строке. Также отлично работает, если я использую ту же строку в VB.Net

finPath имеет пробелы, как и foutPath, и это заставляет программу не запускаться.

Мне нужно, чтобы finPath было выражено как finPath. То же самое с foutPath.


Больше кода (использовал предложенную здесь строку, не повезло):

string inputPath = RootPath + "videoinput\\";  

string ffmpegpath = RootPath + "ffmpeg.exe"; //ffmpeg path

string outputPath = RootPath +"videooutput\\"; 

//define new extension

string fileext = ".flv";

string newfilename = namenoextension + fileext;

string namenoextension = Path.GetFileNameWithoutExtension(savedfile);

string fileoutPath = outputPath + newfilename;

string fileinPath = "/videoinput/" + savedfile;

string cmd = " -i \"" + fileinPath + "\" -ar 44100 -ab 160k \"" + fileoutPath + "\"";


//Begin encoding process

Process proc = new Process();

proc.StartInfo.FileName = ffmpegpath;

proc.StartInfo.Arguments = cmd;

proc.StartInfo.UseShellExecute = true;

proc.StartInfo.CreateNoWindow = false;

proc.StartInfo.RedirectStandardOutput = false;

proc.Start();

Ответы [ 4 ]

9 голосов
/ 04 июня 2009

Это должно работать для вас:

string arguments = string.Format("-i \"{0}\" -ar 44100 -ab 160k \"{1}\"", finPath, foutPath);
Process.Start(thePathToExecutable, arguments);

Обязательно укажите путь к исполняемому файлу отдельно от аргументов командной строки.


Редактировать в ответ на комментарии и вопросы редактировать:

Я только что запустил это в консоли, используя следующий код:

using System;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
        string RootPath = "C:\\";
        string savedFile = "test.avi";

        string inputPath = Path.Combine(RootPath, "videoinput");
        string ffmpegpath = Path.Combine(RootPath, "ffmpeg.exe"); //ffmpeg path
        string outputPath = Path.Combine(RootPath, "videooutput");

        //define new extension
        string fileext = ".flv";
        string namenoextension = Path.GetFileNameWithoutExtension(savedFile);
        string newfilename = namenoextension + fileext;

        string fileoutPath = Path.Combine(outputPath, newfilename);
        string fileinPath = Path.Combine(inputPath, savedFile);

        string arguments = string.Format("-i \"{0}\" -ar 44100 -ab 160k \"{1}\"", fileinPath, fileoutPath);

        Console.WriteLine(ffmpegpath);
        Console.WriteLine(arguments);
        Console.ReadKey();
    }
}

Это пишет:

C:\ffmpeg.exe
-i "C:\videoinput\test.avi" -ar 44100 -ab 160k "C:\videooutput\test.flv"

Как я сказал - если вы делаете это таким образом, это должно работать. При этом я рекомендую прочитать класс System.IO.Path и использовать Path.Combine (), Path.GetFullPath () и т. Д., Чтобы исправить ваши входные файлы. Это также может помочь вам исправить часть проблемы.

3 голосов
/ 05 июня 2009

Документация для CommandLineToArgvW описывает, как анализируются аргументы. Интерпретация этого:

  1. Любой аргумент, содержащий пробел, должен быть заключен в внешние кавычки.
  2. Любым внутренним кавычкам в аргументе должен предшествовать обратные косые.
  3. Обратные косые черты (или последовательности обратных косых черт), которые предшествуют цитата должна быть удвоена.

Следующий класс может быть использован для достижения этих результатов:

/// <summary>
/// Provides helper functionality for working with Windows process command-lines.
/// </summary>
public static class WindowsCommandLineHelper
{
    /// <summary>
    /// Performs escaping and quoting of arguments where necessary to
    /// build up a command-line suitable for use with the
    /// <see cref="System.Diagnostics.Process.Start(string,string)" /> method.
    /// </summary>
    /// <param name="arguments">The arguments to be included on the command-line.</param>
    /// <returns>The resulting command-line.</returns>
    public static string FormatCommandLine(params string[] arguments)
    {
        return string.Join(" ", arguments.Select(GetQuotedArgument));
    }

    private static string GetQuotedArgument(string argument)
    {
        // The argument is processed in reverse character order.
        // Any quotes (except the outer quotes) are escaped with backslash.
        // Any sequences of backslashes preceding a quote (including outer quotes) are doubled in length.
        var resultBuilder = new StringBuilder();

        var outerQuotesRequired = HasWhitespace(argument);

        var precedingQuote = false;
        if (outerQuotesRequired)
        {
            resultBuilder.Append('"');
            precedingQuote = true;
        }

        for (var index = argument.Length - 1; index >= 0; index--)
        {
            var @char = argument[index];
            resultBuilder.Append(@char);

            if (@char == '"')
            {
                precedingQuote = true;
                resultBuilder.Append('\\');
            }
            else if (@char == '\\' && precedingQuote)
            {
                resultBuilder.Append('\\');
            }
            else
            {
                precedingQuote = false;
            }
        }

        if (outerQuotesRequired)
        {
            resultBuilder.Append('"');
        }

        return Reverse(resultBuilder.ToString());
    }

    private static bool HasWhitespace(string text)
    {
        return text.Any(char.IsWhiteSpace);
    }

    private static string Reverse(string text)
    {
        return new string(text.Reverse().ToArray());
    }
}

Для командной строки, описанной в этом вопросе, вы бы назвали ее так:

string commandLine = WindowsCommandLineHelper.FormatCommandLine(
    "-i", finPath, "-ar", "44100", "-ab", "160k", foutPath);
Process.Start(exePath, commandLine);

UPDATE

Более интересная информация содержится в этом сообщении в блоге и реализации C # .

2 голосов
/ 04 июня 2009

Является ли это просто проблемой от кавычек? Код, который вы разместили, использует "" вместо \ ". Для C # это должно быть:

string cmd = " -i \"" + finPath + "\" -ar 44100 -ab 160k \"" + foutPath + "\"";
0 голосов
/ 20 декабря 2011

А вот моя попытка:

    public static string QuoteArgument(string arg)
    {
        // The inverse of http://msdn.microsoft.com/en-us/library/system.environment.getcommandlineargs.aspx

        // Suppose we wish to get after unquoting: \\share\"some folder"\
        // We should provide: "\\share\\\"some folder\"\\"

        // Escape quotes ==> \\share\\\"some folder\"\
        // For quotes with N preceding backslashes, replace with 2k+1 preceding backslashes.
        var res = new StringBuilder();
        // For sequences of backslashes before quotes:
        // odd ==> 2x+1, even => 2x ==> "\\share\\\"some folder"
        var numBackslashes = 0;
        for (var i = 0; i < arg.Length; ++i)
        {
            if(arg[i] == '"')
            {
                res.Append('\\', 2 * numBackslashes + 1);
                res.Append('"');
                numBackslashes = 0;
            }
            else if(arg[i] == '\\')
            {
                numBackslashes++;
            }
            else
            {
                res.Append('\\', numBackslashes);
                res.Append(arg[i]);
                numBackslashes = 0;
            }
        }
        res.Append('\\', numBackslashes);

        // Enquote, doubling last sequence of backslashes ==> "\\share\\\"some folder\"\\"
        var numTrailingBackslashes = 0;
        for (var i = res.Length - 1; i > 0; --i)
        {
            if (res[i] != '\\')
            {
                numTrailingBackslashes = res.Length - 1 - i;
                break;
            }
        }
        res.Append('\\', numTrailingBackslashes);

        return '"' + res.ToString() + '"';
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...