Я испытываю странное поведение при попытке PInvoke SetStdHandle () перенаправить stdout / stderr из неуправляемой DLL. А именно, с данной DLL она работает ТОЛЬКО при сборках Debug (не Release).
Соответствующий код выглядит так:
[System.Runtime.InteropServices.DllImport("Kernel32.dll", SetLastError = true)]
public static extern int SetStdHandle(int device, IntPtr handle);
const int STD_OUTPUT_HANDLE = -11;
const int STD_ERROR_HANDLE = -12;
static System.IO.FileStream outFileStream;
static System.IO.FileStream errFileStream;
public static void TestStdRedirect()
{
outFileStream = System.IO.File.Open("C:\\stdout.txt", System.IO.FileMode.Create);
if (0 == SetStdHandle(-11, outFileStream.SafeFileHandle.DangerousGetHandle()))
System.Windows.Forms.MessageBox.Show("HANDLE REASSIGNMENT FAILED!");
errFileStream = System.IO.File.Open("C:\\stderr.txt", System.IO.FileMode.Create);
if (0 == SetStdHandle(-12, errFileStream.SafeFileHandle.DangerousGetHandle()))
System.Windows.Forms.MessageBox.Show("HANDLE REASSIGNMENT FAILED!");
}
public static void EndTestStdRedirect()
{
Console.OpenStandardOutput().Flush();
Console.OpenStandardError().Flush();
outFileStream.Flush();
outFileStream.Close();
errFileStream.Flush();
errFileStream.Close();
}
Теперь, когда я делаю следующее, всегда работает (независимо от выпуска или отладочной сборки) - операторы печати перенаправляются в c: \ stdout.txt и c: \ stderr.txt, как и ожидалось.
TestStdRedirect();
byte[] buf = Console.OutputEncoding.GetBytes(DateTime.Now.ToString() + ") Start Test StdOut" + Console.Out.NewLine);
Console.OpenStandardOutput().Write(buf, 0, buf.Length);
buf = Console.OutputEncoding.GetBytes(DateTime.Now.ToString() + ") Start Test StdErr" + Console.Out.NewLine);
Console.OpenStandardError().Write(buf, 0, buf.Length);
EndTestStdRedirect();
Однако делаем следующее:
[System.Runtime.InteropServices.DllImport("SomeDLL.dll")]
static extern void FxnFromUnmanagedDLL();
TestStdRedirect();
FxnFromUnmanagedDLL();
EndTestStdRedirect();
где FxnFromUnmanagedDLL выводит в stdout / stderr через fprintf, вывод перенаправляется в файл только , когда проект создается как «Отладка». Если он построен как Release, вывод идет прямо на панель вывода Visual Studio.
... Другими словами, это:
TestStdRedirect();
FxnFromUnmanagedDLL();
byte[] buf = Console.OutputEncoding.GetBytes("blah" + Console.Out.NewLine);
Console.OpenStandardOutput().Write(buf, 0, buf.Length);
EndTestStdRedirect();
перенаправляет «бла» в файл, но вывод неуправляемой DLL направляется на консоль. Я гуглил и гуглил и не могу понять, что происходит; Моей первой мыслью было, что DLL делает что-то напуганное, например, открывание или переназначение потоков, но я ничего не могу найти по этому поводу (у меня есть доступ к исходному коду неуправляемой библиотеки DLL).
Заранее спасибо за ваши идеи ...