process.start()参数

bru*_*rux 36 .net c# command-line process

当我对dos执行以下命令时,它将正常工作

ffmpeg -f image2 -i frame%d.jpg -vcodec mpeg4 -b 800k video.avi
Run Code Online (Sandbox Code Playgroud)

当我尝试在c#中使用流程类而没有参数时,它会在控制台窗口中加载ffmpeg,然后像往常一样消失.但是,当我尝试使用上面的参数时,格式完全相同......它不起作用!ffmpeg仍然加载,但是由于控制台窗口关闭如此之快,我无法确定错误是什么:/

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();
Run Code Online (Sandbox Code Playgroud)

谁知道为什么会这样?为什么命令可以从dos工作,然后使用c#无法工作,即使参数完全相同?我之前使用过这种方法很多东西,从来没有遇到过这种情况.

Dan*_*den 40

这不是一个直接的答案,但我强烈建议使用LINQPad进行这种"探索式"C#编程.

我在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();
Run Code Online (Sandbox Code Playgroud)

随意根据需要进行调整.


cri*_*ito 31

尝试完全限定参数中的文件名 - 我注意到你在FileName部分中指定了路径,因此有可能在其他地方启动进程,然后找不到参数并导致错误.

如果可以,那么在StartInfo上设置WorkingDirectory属性可能是有用的.

实际上,根据链接

如果提供了UserName和Password,则必须设置WorkingDirectory属性.如果未设置该属性,则默认工作目录为%SYSTEMROOT%\ system32.

  • 谢谢,我设置workingdirectory属性以匹配与ffmpeg相同的路径并立即工作 (2认同)

Dir*_*mar 12

确保使用完整路径,例如不仅是"video.avi",而是使用该文件的完整路径.

调试的一个简单技巧是使用以下命令启动命令窗口cmd /k <command>:

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();
Run Code Online (Sandbox Code Playgroud)

这将使命令窗口保持打开状态,以便您可以轻松检查输出.

  • @ 0xA3它确实有效.即使我使用process.WaitForExit(10*1000)`10(s)`,ffmpeg也会快速消失.这个"/ k"究竟意味着什么?怎么找到的?谢谢. (2认同)

Chr*_*Rea 7

为了更好地进行诊断,您可以捕获外部程序的标准输出和标准错误流,以查看生成的输出以及可能无法按预期运行的原因.

抬头:

如果将每个设置为true,则可以稍后调用process.StandardOutput.ReadToEnd()并将process.StandardError.ReadToEnd()输出转换为字符串变量,您可以在调试器下轻松检查,或输出到跟踪或日志文件.