2

在 C# 控制台应用程序中,我正在导入本机 C++ DLL 方法。例如:

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

执行时,MyMethod()正在将输出打印到控制台,我想将其隐藏。

假设我无法更改 DLL,我怎么还能抑制它的输出?

4

2 回答 2

2

修改自http://social.msdn.microsoft.com/Forums/vstudio/en-US/31a93b8b-3289-4a7e-9acc-71554ab8fca4/net-gui-application-native-library-console-stdout-redirection-via-匿名管道

我删除了他们尝试重定向它的部分,因为如果您进一步阅读,它会说他们在多次调用它时遇到了问题。

 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());
}
于 2013-10-11T17:26:33.377 回答
1

您希望这样做的唯一方法是在调用 DLL 时重定向标准输出。我从未尝试过,也不知道它是否有效。

用于SetStdHandle将标准输出定向到其他地方。例如,一个 nul 设备的句柄就可以了。如果您需要在对 DLL 的调用返回后恢复原始标准输出句柄,则需要再次调用SetStdHandle.

每次调用 DLL 时,您都需要跳过这些环节。如果你有线程和/或回调,事情会变得更加复杂。

于 2013-10-11T17:20:31.197 回答