process.start() 参数

Posted

技术标签:

【中文标题】process.start() 参数【英文标题】:process.start() arguments 【发布时间】:2011-03-17 03:08:40 【问题描述】:

当我在dos中执行以下命令时,它会正常工作

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

当我尝试在 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();

有人知道这是为什么吗?为什么命令会从 dos 工作,然后即使参数完全相同,也无法使用 c# 工作?这个方法我以前用过很多东西,从来没有遇到过。

【问题讨论】:

你确定FileName 是正确的吗?斜杠不应该是 \\ 而不是 //. 使用 System.IO.Path.Combine(path, "ffmpeg.exe") 代替。这会将正确的目录分隔符放在路径中(如果还没有的话)。 ye 文件名属性是正确的,就像我说的队友,这个过程实际上正在开始,所以必须找到文件,它的参数失败了。我尝试连接字符串,然后将其传递给参数而不是上面的,仍然没有乐趣: 如果我需要将 .caf 转换为 .mp3 过程的参数是什么 【参考方案1】:

并不是一个直接的答案,但我强烈建议使用 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();

根据需要随意调整。

【讨论】:

别忘了加上 p.StandardError.ReadToEnd().Dump();对于那些也写入 stderr 的(罕见的)应用程序。 @Tergiver:除了由于抖振之外,在另一个流上调用 ReadToEnd 会导致死锁。当然,对于大多数程序来说,这不太可能成为问题,但我认为,例如代码,最好留下一些东西而不是错误地实现它。 我从来没有这样尝试过,我在重定向进程时异步读取了两个流。我明白你为什么要给出那个简单的例子而不是一个完整的(异步)例子。【参考方案2】:

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

如果可行,那么在 StartInfo 上设置 WorkingDirectory 属性可能会有用。

其实根据链接

WorkingDirectory 属性必须 如果用户名和密码是设置 假如。如果没有设置属性, 默认工作目录是 %SYSTEMROOT%\system32。

【讨论】:

谢谢,我设置了 workingdirectory 属性以匹配与 ffmpeg 相同的路径,现在可以使用 "/k \"c:\\users\\jafar.baltidynamolog\\documents\\visual studio 2010\\Projects\\VideoProjectBilal\\VideoProjectBilal\\bin\\Debug\\ffmpeg。 exe\" -i \"C:\\Users\\jafar.baltidynamolog\\Videos\\videos\\SampleVideo_360x240_2mb.mp4\" -i \"C:\\Users\\jafar.baltidynamolog\\Videos\\images \\2.png\" -filter_complex \"overlay=10:10\" \"c:\\users\\jafar.baltidynamolog\\documents\\visual studio 2010\\Projects\\VideoProjectBilal\\VideoProjectBilal\\bin \\Debug\\Output\\SampleVideo_360x240_2mb_Output.mp4\"" 我在第一个空间遇到问题。请帮忙 那么答案是什么?【参考方案3】:

确保使用完整路径,例如不仅是“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();

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

【讨论】:

@0xA3 确实有效。即使我使用 process.WaitForExit(10 * 1000)10(s),ffmpeg 消失得太快而无法拍摄快照。这个“/k”实际上是什么意思?怎么找到的?谢谢。 @Stallman:/k 表示命令窗口未关闭但保持打开状态。您可以通过在命令提示符下调用cmd.exe /? 来获取所有选项。【参考方案4】:

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

向上看:

ProcessStartInfo.RedirectStandardErrorProcessStartInfo.RedirectStandardOutput.

如果您将其中的每一个都设置为 true,那么您可以稍后调用 process.StandardOutput.ReadToEnd()process.StandardError.ReadToEnd() 将输出转换为字符串变量,您可以在调试器下轻松检查这些变量,或者输出到跟踪或日志文件。

【讨论】:

【参考方案5】:

非常极端的情况,但我必须使用只有在我指定时才能正常工作的程序

StartInfo = ..., RedirectStandardOutput = true

不指定会导致错误。之后甚至不需要读取输出。

【讨论】:

以上是关于process.start() 参数的主要内容,如果未能解决你的问题,请参考以下文章

C#,Process.Start() 传递多参数问题。

将 PowerShell 参数传递给 Process.Start

C# process.Start 文件名和传递参数

C#中怎么用process调用一个exe文件并传入参数?

C# Process Start 需要带双引号的参数 - 它们消失了

使用 Process.Start() 通过快捷方式运行应用程序