禁止从导入的 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,我如何仍然抑制它的输出?

禁止从导入的 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 的每次调用,都需要跳过这些箍。如果您有线程和/或回调,事情会变得更加复杂。