从.NET中的COM对象包装器重定向STDERR输出

我正在尝试在.NET库中使用ImageMagick COM对象(ImageMagickObject)。 这个库旨在从IronRuby中调用,但这并不是那么重要。 我想采用这种方法,因为它适合我现有的调用,当前调用ImageMagick二进制文件作为外部进程。 COM对象将采用与二进制文件相同的参数,但将保存进程创建速度,整体速度提高约5倍。

我唯一的障碍是COM对象的“Compare”方法将其结果返回给STDERR。 这也是二进制文件的一个问题,但很容易将其传回STDOUT,我期待它。 使用COM对象,我从函数返回值中获取结果。

如何将结果从“比较”重定向到字符串缓冲区甚至文件而不是STDERR?

我尝试了以下操作,它确实阻止输出到达STDERR,但它没有按预期写入文件:

using ImageMagickObject; ... public class ImageMagickCOM { [DllImport("Kernel32.dll", SetLastError = true)] public static extern int SetStdHandle(int device, IntPtr handle); private const int STDOUT_HANDLE = -11; private const int STDERR_HANDLE = -12; private ImageMagickObject.MagickImage magickImage = null; private FileStream filestream = null; private StreamWriter streamwriter = null; public ImageMagickCOM() { IntPtr handle; int status; filestream = new FileStream("output.txt", FileMode.Create); streamwriter = new StreamWriter(filestream); streamwriter.AutoFlush = true; //handle = filestream.Handle; // deprecated handle = filestream.SafeFileHandle.DangerousGetHandle(); // replaces filestream.handle status = SetStdHandle(STDOUT_HANDLE, handle); status = SetStdHandle(STDERR_HANDLE, handle); Console.SetOut(streamwriter); Console.SetError(streamwriter); magickImage = new ImageMagickObject.MagickImage(); } public string Compare() { object[] args = new object[] { "-metric", "AE", "-fuzz", "10%", "imageA.jpg", "imageB.jpg", "diff.png" }; return (string)this.magickImage.Compare(ref args); } public void Close() { if (this.magickImage != null) { Marshal.ReleaseComObject(magickImage); this.magickImage = null; } if (this.streamwriter != null) { this.streamwriter.Flush(); this.streamwriter.Close(); this.streamwriter = null; this.filestream = null; } } } 

只有“比较”动作似乎使用STDERR发送结果(它使用返回值作为成功指示符)。 所有其他方法(Identify,Convert,Mogrify等)都可以正常工作。

作为参考,它被称为这样的东西(来自IronRuby):

 require 'ImagingLib.dll' im = ImagingLib::ImageMagickCOM.new im.compare # returns nil im.close 

并且output.txt已创建,但为空。 什么都没有打印到STDOUT或STDERR。

编辑:关于河流写入器冲洗/关闭以及IronRuby如何使用样品的清晰度。

添加debug选项后,我终于在文件中找到了一些文本。

这是你期待的结果吗? 如果是这样,请参阅compare命令行工具的debug选项。

请注意,如果您尝试使用上述属性直接或间接记录任何内容,则将Console.ErrorConsole.Out设置为streamwriter将导致exception。

如果确实需要设置这些属性,请将它们设置为另一个StreamWriter实例。 如果您不需要它们,请省略对Console.SetOutConsole.SetError的调用。

我还注意到,一旦创建了ImageMagickObject.MagickImage实例,就无法重定向标准错误。 如果需要撤消标准错误重定向或执行多次,请尝试在另一个应用程序域中执行代码。

您是否尝试过Disposing(或刷新)编写器和流? 它可能已经死在缓冲区中。 使用块可能有帮助。

  using(filestream = new FileStream("output.txt", FileMode.Create)) using(streamwriter = new StreamWriter(filestream)) { 

…}

它看起来像.Handle已被弃用,你试过.SafeFileHandle.DangerousGetHandle()而不是?

参考: http : //msdn.microsoft.com/en-us/library/system.runtime.interopservices.safehandle.dangerousgethandle.aspx

(另外:您可以确认在写入数据后关闭StreamWriter吗?比如,如果您在应用程序关闭之前将其移动,以查看数据是否可以解决?)

根据文档“FileShare.Read是没有FileShare参数的那些FileStream构造函数的默认值”……也许它可以帮助在FileStream c中设置FileAccess.Read,FileAccess.Write,FileShare.Read和FileShare.Write -TOR?

我没有使用ImageMagick exe …如果你可以发布链接,那就太好了。