Próbuję użyć obiektu COM ImageMagick (ImageMagickObject) w bibliotece .NET. Ta biblioteka ma być wywoływana z IronRuby, ale nie jest to aż tak ważne. Chcę przyjąć to podejście, ponieważ będzie pasować do moich istniejących połączeń, które obecnie nazywają binaria ImageMagick jako procesy zewnętrzne. Obiekt COM będzie przyjmował te same argumenty co pliki binarne, ale zapisze proces tworzenia i będzie około 5 razy szybszy.Przekierowanie danych wyjściowych STDERR z opakowania obiektu COM w .NET
Moja jedyna przeszkoda polega na tym, że metoda "Porównaj" dla obiektu COM zwraca wynik do STDERR. Jest to również problem związany z binariami, ale łatwo można go przekierować z powrotem do STDOUT, gdzie oczekiwałem. Za pomocą obiektu COM otrzymuję wyniki z wartości zwracanych przez funkcję.
Jak mogę przekierować wynik z "Porównaj" do bufora ciągów lub nawet do pliku zamiast STDERR?
Próbowałem następujące dane, które kończy wyjście z dotarciem STDERR, ale nie zapisuje do pliku zgodnie z oczekiwaniami:
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;
}
}
}
Tylko „Porównaj” akcja wydaje się używać STDERR wysłać wynik (używa wartości zwracanej jako wskaźnika sukcesu). Wszystkie inne metody (Identify, Convert, Mogrify, itp.) Działają tak, jak byś tego oczekiwał.
Dla porównania, to jest wywoływana coś takiego (z IronRuby):
require 'ImagingLib.dll'
im = ImagingLib::ImageMagickCOM.new
im.compare # returns nil
im.close
I output.txt jest tworzony, ale pusty. Nic nie zostanie wydrukowane na STDOUT lub STDERR.
EDYCJE: Dla przejrzystości w odniesieniu do flush/close streamwriter i sposobu użycia próbki z IronRuby.
Próbowałem jawnie opróżniać bufor przed i po wywołaniu funkcji Kompiluj bez powodzenia. – cgyDeveloper