Suppress Console prints from imported DLL

2019-07-28 19:35发布

Inside a C# Console application, I'm importing a native C++ DLL methods. for example:

    [DllImport("MyDll.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
    public static extern int MyMethod(IntPtr somePointer);

When executed, MyMethod() is printing output to the Console, which I would like to be hidden.

Assuming I can't change the DLL, how can I still suppress it's output?

2条回答
Deceive 欺骗
2楼-- · 2019-07-28 19:56

Modified from 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

I removed the part where they try to redirect it because if you read further, it says they were having issues when it was called more than once.

 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
  }

and usage sample:

[DllImport("SampleLibrary.dll")]
extern static void LetterList();

private void button1_Click(object sender, EventArgs e)
{
  ConsoleOutRedirector.GetOutput(() => LetterList());
}
查看更多
一夜七次
3楼-- · 2019-07-28 19:58

The only way you can hope to do this is to redirect the standard output whenever you call into the DLL. I've never attempted this and have no idea whether or not it works.

Use SetStdHandle to direct standard output to some other place. For example a handle to the nul device would do. If you need to restore the original standard output handle after calls to the DLL return, that takes another call to SetStdHandle.

You'll need to jump through these hoops for each and every call to the DLL. Things would get even more complex if you have threads and/or callbacks.

查看更多
登录 后发表回答