Внутри приложения С# Console я импортирую собственные методы DLL C++. например:
[DllImport("MyDll.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern int MyMethod(IntPtr somePointer);
Когда выполняется, MyMethod()
выводит вывод на консоль, который я хотел бы скрывать.
Предполагая, что я не могу изменить DLL, как я могу ее подавить?
Единственный способ, которым вы можете надеяться сделать это, - перенаправить стандартный вывод при каждом вызове в DLL. Я никогда не пытался этого и понятия не имею, работает ли это.
Используйте SetStdHandle
для прямого вывода данных в другое место. Например, дескриптор устройства nul. Если вам необходимо восстановить исходный стандартный дескриптор вывода после вызовов на возврат DLL, это вызовет другой вызов SetStdHandle
.
Вам нужно будет пройти через эти обручи для каждого вызова в DLL. Все будет еще сложнее, если у вас есть потоки и/или обратные вызовы.
Я удалил часть, в которой они пытаются перенаправить ее, потому что, если вы читаете дальше, она говорит, что у них были проблемы, когда она вызывалась более одного раза.
public static class ConsoleOutRedirector
{
#region Constants
private const Int32 STD_OUTPUT_HANDLE = -11;
#endregion
#region Externals
[DllImport("Kernel32.dll")]
extern static Boolean SetStdHandle(Int32 nStdHandle, SafeHandleZeroOrMinusOneIsInvalid handle);
[DllImport("Kernel32.dll")]
extern static SafeFileHandle GetStdHandle(Int32 nStdHandle);
#endregion
#region Methods
public static void GetOutput(Action action)
{
Debug.Assert(action != null);
using (var server = new AnonymousPipeServerStream(PipeDirection.Out))
{
var defaultHandle = GetStdHandle(STD_OUTPUT_HANDLE);
Debug.Assert(!defaultHandle.IsInvalid);
Debug.Assert(SetStdHandle(STD_OUTPUT_HANDLE, server.SafePipeHandle));
try
{
action();
}
finally
{
Debug.Assert(SetStdHandle(STD_OUTPUT_HANDLE, defaultHandle));
}
}
}
#endregion
}
и образец использования:
[DllImport("SampleLibrary.dll")]
extern static void LetterList();
private void button1_Click(object sender, EventArgs e)
{
ConsoleOutRedirector.GetOutput(() => LetterList());
}