c# - 在 .NET 中重定向来自 COM 对象包装器的 STDERR 输出

标签 c# .net com imagemagick

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

我唯一的障碍是 COM 对象的“比较”方法将其结果返回给 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。

编辑:关于 streamwriter flush/close 以及示例如何从 IronRuby 使用的清晰度。

最佳答案

您是否尝试处理(或刷新)编写器和流?它可能死于缓冲区。 using block 可能会有所帮助。

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

...

关于c# - 在 .NET 中重定向来自 COM 对象包装器的 STDERR 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4925189/

相关文章:

c# - .NET C# ComboBox 默认文本

java - 可以修改第三方 ActiveX 控件中的枚举吗?

C#配置管理器。连接字符串

C# - 我可以从具有泛型基类型的类派生吗?

c# - 创建动态快照路径

c# - 单个 LINQ 表达式来计算数据集中的多个列

.net - 如何强制Web浏览器控件始终在同一窗口中打开网页?

.net - 使用 VBScript 中的 System.Globalization.CultureInfo

windows - RegSvr32.exe的/n和/i参数有什么区别?

c# - WPF 多行文本框插入符位置