我正在尝试做一些看起来应该相对简单的事情:从 C# 调用 jpegoptim。
我可以让它很好地写入磁盘,但是让它接受一个流并发出一个流到目前为止我还没有遇到 - 我总是以 0 长度输出或不祥的“管道已结束”告终。
我尝试过的一种方法:
var processInfo = new ProcessInfo(
jpegOptimPath,
"-m" + quality + " -T1 -o -p --strip-all --all-normal"
);
processInfo.CreateNoWindow = true;
processInfo.WindowStyle = ProcessWindowStyle.Hidden;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardInput = true;
processInfo.RedirectStandardOutput = true;
processInfo.RedirectStandardError = true;
using(var process = Process.Start(processInfo))
{
await Task.WhenAll(
inputStream.CopyToAsync(process.StandardInput.BaseStream),
process.StandardOutput.BaseStream.CopyToAsync(outputStream)
);
while (!process.HasExited)
{
await Task.Delay(100);
}
// Do stuff with outputStream here - always length 0 or exception
}
我也试过这个解决方案:
http://alabaxblog.info/2013/06/redirectstandardoutput-beginoutputreadline-pattern-broken/
using (var process = new Process())
{
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.FileName = fileName;
process.StartInfo.Arguments = arguments;
process.Start();
//Thread.Sleep(100);
using (Task processWaiter = Task.Factory.StartNew(() => process.WaitForExit()))
using (Task<string> outputReader = Task.Factory.StartNew(() => process.StandardOutput.ReadToEnd()))
using (Task<string> errorReader = Task.Factory.StartNew(() => process.StandardError.ReadToEnd()))
{
Task.WaitAll(processWaiter, outputReader, errorReader);
standardOutput = outputReader.Result;
standardError = errorReader.Result;
}
}
同样的问题。输出长度 0。如果我让 jpegoptim 在没有输出重定向的情况下运行,我会得到我所期望的 - 一个优化的文件 - 但当我以这种方式运行它时不会。
必须有正确的方法来做到这一点?
更新:找到了一条线索——我不觉得害羞吗——jpegoptim 直到 2014 年的实验性版本才支持管道到标准输入,并于今年修复。我拥有的版本来自一个较旧的库,日期为 2013 年。https://github.com/tjko/jpegoptim/issues/6