2009-06-04 2 views
1

Ich habe das bekam:Probleme beim Starten eines Prozesses mit Process.Start() - wie konstruiere ich die Argumentliste?

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

und ich brauche es passieren Aufforderung von C# Systems.Diagnostics.Process zu befehlen.

Keine Kombination scheint zu funktionieren. Programm funktioniert gut, wenn ich es in der Eingabeaufforderung ausführen. Läuft auch gut, wenn ich die gleiche Zeichenfolge in VB.Net verwenden

finPath hat Leerzeichen wie foutPath und es macht das Programm nicht ausgeführt.

Ich brauche finPath ausgedrückt als finPath. Gleiches mit foutPath.


Mehr des Codes (verwendet die Linie hier vorgeschlagen, kein Glück):

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(); 
+1

Bitte schreiben Sie alle Code, der den Prozess startet. Es ist schwer zu entziffern, was das Problem nur von der Befehlszeile args –

+0

Erledigt ist. Bearbeitet Hauptpost –

+0

Dies wird benötigt: ffmpeg.exe -i "C: \ Dokumente und Einstellungen \ Benutzer \ Eigene Dateien \ Visual Studio 2008 \ Projekte \ Projekt \ Videoeingang \ eaf2cc1d-6MTNTUGOFWAR.wmv" -ar 44100 - ab -160k "videooutput \ eaf2cc1d-6MTNTUGOFWAR.flv" –

Antwort

9

Dies sollte für Sie arbeiten:

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

Stellen Sie sicher, den ausführbaren Pfad getrennt angeben von den Befehlszeilenargumenten.


bearbeiten in Reaktion auf die Kommentare und Fragen bearbeiten:

Ich lief dies in einer Konsole, mit dem folgenden Code:

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(); 
    } 
} 

Dies schreibt:

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

Wie gesagt - wenn du es so machst, sollte es funktionieren. Davon abgesehen würde ich empfehlen, in der Klasse System.IO.Path nachzulesen und Path.Combine(), Path.GetFullPath() usw. zu verwenden, um die Eingabedateien zu reparieren. Dies kann Ihnen helfen, einen Teil Ihres Problems zu korrigieren.

+0

erscheint als: "-i \ "Videoeingang/file.wmv \" -ar 44100 -ab 160k \ "C: \\ Dokumente und Einstellungen \\ Benutzer \\ My Documents \\ Visual Studio 2008 \\ Projekte \\ Projektname \\ Videoausgang/eaf2cc1d-6mtnR. flv \ „“ \t die \ nach -i und die \ nach 160k ist nach wie vor ein Problem, wenn Sie in Eingabeaufforderung ausführen, obwohl es jetzt ein Anführungszeichen um den Dateinamen ist. –

+0

@Haste: Ich habe gerade bearbeitet, um Ihnen zu zeigen, wie Sie das machen können. Ich habe ein ganzes Programm in die Quelle gestellt - und getestet. Das funktioniert definitiv. –

+0

Vielen Dank für Ihre Hilfe Reed. leider noch mein Code zeigt im Debugger als -i \ "Videoeingang/file.wmv" -ar 44100 -ab 160k \ „C oben: \ Dokumente und Einstellungen \ Benutzer \ Eigene Dateien \ Visual Studio 2008 \ Projects \ Projektname \ Videoausgang/eaf2cc1d-6mtnR.flv“ (beachten Sie den Backslash nach -i und 160k) und läuft immer noch nicht. Ich hatte dies in Vb.net in Ordnung mit: cmd = "-i" "" & filePath & "" "-ar 44100 -ab 160k" "" & encodefileoutPath & "" "" Weiß nicht während C# ist so ein Schmerz. –

2

Ist das nur ein Problem, das den Zitaten entgeht? Der Code gepostet Sie verwendet „“ anstelle von \“Für C# sollte es sein.

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

Nein, das Problem ist das Hinzufügen von Anführungszeichen um finPath und foutPath. –

+0

@Haste: Dies wird Zitate um diese beiden Variablen hinzufügen. Ihr Code verwendete "" anstelle von ", was Sie in C# benötigen. –

3

Die Dokumentation für CommandLineToArgvW beschreibt, wie die Argumente analysiert werden interpretieren dies:.

  1. Jedem Argument, enthält Leerzeichen in äußeren Anführungszeichen sollte
  2. Irgendwelche im Argument inneren Anführungszeichen sollte von Schrägstriche vorangestellt werden.
  3. Backslash (oder Sequenzen von umgekehrten Schrägstrichen) umgeben sein. dass pre cede ein Angebot sollte verdoppelt werden.

Die folgende Klasse verwendet, um diese Ergebnisse zu erzielen sind:

/// <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()); 
    } 
} 

Für die Befehlszeile in dieser Frage beschrieben, würden Sie es so nennen:

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

Und hier ist mein Versuch:

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() + '"'; 
    }