禁止从导入的 DLL 打印控制台
本文关键字:打印 控制台 DLL 导入 禁止 | 更新日期: 2023-09-27 18:34:53
在 C# 控制台应用程序中,我正在导入本机C++ DLL 方法。 例如:
[DllImport("MyDll.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern int MyMethod(IntPtr somePointer);
执行时,MyMethod()
将输出打印到控制台,我希望将其隐藏。
假设我无法更改 DLL,我如何仍然抑制它的输出?
修改自 http://social.msdn.microsoft.com/Forums/vstudio/en-US/31a93b8b-3289-4a7e-9acc-71554ab8fca4/net-gui-application-native-library-console-stdout-redirection-via-anonymous-pipes
我删除了他们试图重定向它的部分,因为如果您进一步阅读,它会说他们在多次调用时遇到了问题。
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());
}
您希望
这样做的唯一方法是在调用 DLL 时重定向标准输出。我从未尝试过,也不知道它是否有效。
使用 SetStdHandle
将标准输出定向到其他位置。例如,NUL 设备的句柄就可以了。如果需要在调用 DLL 返回后还原原始标准输出句柄,则需要再次调用 SetStdHandle
。
对于对 DLL 的每次调用,都需要跳过这些箍。如果您有线程和/或回调,事情会变得更加复杂。