web-dev-qa-db-fra.com

arguments process.start ()

quand je fais la commande suivante en dos cela fonctionnera bien

ffmpeg -f image2 -i frame%d.jpg -vcodec mpeg4 -b 800k video.avi

Lorsque j'essaie d'utiliser la classe de processus en c #, sans les arguments, il charge ffmpeg dans une fenêtre de la console puis disparaît comme d'habitude. Cependant, lorsque j'essaie d'utiliser l'argument comme je le fais ci-dessus, le formatage est identique, cela ne fonctionne pas! ffmpeg se charge toujours, mais comme la fenêtre de la console se ferme si vite, je ne peux pas déterminer l’erreur: /

Process ffmpeg = new Process();
ffmpeg.StartInfo.FileName = path + "//" + "ffmpeg.exe";
ffmpeg.StartInfo.Arguments = " -f image2 -i frame%d.jpg -vcodec mpeg4 -b 800k video.avi";
ffmpeg.Start();

Quelqu'un sait pourquoi c'est? Pourquoi la commande fonctionne-t-elle de dos et ensuite ne fonctionne-t-elle pas avec c # même lorsque les arguments sont exactement les mêmes? J'ai déjà utilisé cette méthode pour beaucoup de choses et je ne l'ai jamais rencontrée.

34
brux

Essayez de qualifier complètement les noms de fichiers dans les arguments - je remarque que vous spécifiez le chemin dans la partie FileName. Il est donc possible que le processus soit démarré ailleurs, puis ne trouve pas les arguments et provoque une erreur.

Si cela fonctionne, il peut être utile de définir la propriété WorkingDirectory sur StartInfo.

En fait, selon le lien

La propriété WorkingDirectory doit être défini si UserName et Password sont à condition de. Si la propriété n'est pas définie, le répertoire de travail par défaut est % SYSTEMROOT%\system32.

29
cristobalito

Ce n'est pas vraiment une réponse directe, mais je vous recommande fortement d'utiliser LINQPad pour ce type de programmation "exploratoire" en C #.

J'ai le texte suivant en tant que "requête" enregistrée dans LINQPad:

var p = new System.Diagnostics.Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c echo Foo && echo Bar";
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.Start();
p.StandardOutput.ReadToEnd().Dump();

N'hésitez pas à vous adapter au besoin.

35
Daniel Pryden

Assurez-vous d’utiliser des chemins complets, par exemple non seulement "video.avi" mais le chemin complet de ce fichier.

Une astuce simple pour le débogage serait de démarrer une fenêtre de commande en utilisant cmd /k <command>instead:

string ffmpegPath = Path.Combine(path, "ffmpeg.exe");
string ffmpegParams = @"-f image2 -i frame%d.jpg -vcodec"
    + @" mpeg4 -b 800k C:\myFolder\video.avi"

Process ffmpeg = new Process();
ffmpeg.StartInfo.FileName = "cmd.exe";
ffmpeg.StartInfo.Arguments = "/k " + ffmpegPath + " " + ffmpegParams
ffmpeg.Start();

Cela laissera la fenêtre de commande ouverte afin que vous puissiez facilement vérifier le résultat.

11
Dirk Vollmar

Pour mieux diagnostiquer, vous pouvez capturer la sortie standard et les flux d'erreur standard du programme externe, afin de voir quelle sortie a été générée et pourquoi il ne s'exécute peut-être pas comme prévu.

Chercher:

Si vous définissez chacun de ces éléments sur true, vous pourrez ultérieurement appeler process.StandardOutput.ReadToEnd() et process.StandardError.ReadToEnd() pour obtenir le résultat en variables chaîne, que vous pourrez facilement inspecter sous le débogueur, ou en sortie à suivre ou dans votre fichier journal.

6
Chris W. Rea

Cas très Edge, mais je devais utiliser un programme qui ne fonctionnait correctement que lorsque j'ai spécifié

StartInfo = {..., RedirectStandardOutput = true}

Ne pas le spécifier entraînerait une erreur. Il n'était même pas nécessaire de lire la sortie par la suite.

0
Bene Tleilax