如何阻止VC#将控制台输出重定向到输出窗口?

时间:2012-10-24 14:04:52

标签: c# visual-studio stdout

我有一个GUI C#应用程序,它使用用AllocConsole创建的控制台。它在正常情况下工作,但是当在Visual Studio下以调试模式启动应用程序时,所有输出都会在Visual Studio输出窗口中结束。我该怎么做呢?

我正在使用C#3.5和Visual Studio Pro 2010。 进程托管选项已关闭。

2 个答案:

答案 0 :(得分:5)

我的解决方案是将标准流重置为新创建的控制台。这是代码:

public static class ConsoleHelper
{
    /// <summary>
    /// Allocates a console and resets the standard stream handles.
    /// </summary>
    public static void Alloc()
    {
        if (!AllocConsole())
            throw new Win32Exception();
        SetStdHandle(StdHandle.Output, GetConsoleStandardOutput());
        SetStdHandle(StdHandle.Input,  GetConsoleStandardInput());
    }

    private static IntPtr GetConsoleStandardInput()
    {
        var handle = CreateFile
            ( "CONIN$"
            , DesiredAccess.GenericRead | DesiredAccess.GenericWrite
            , FileShare.ReadWrite
            , IntPtr.Zero
            , FileMode.Open
            , FileAttributes.Normal
            , IntPtr.Zero
            );
        if (handle == InvalidHandleValue)
            throw new Win32Exception();
        return handle;
    }

    private static IntPtr GetConsoleStandardOutput()
    {
        var handle = CreateFile
            ( "CONOUT$"
            , DesiredAccess.GenericWrite | DesiredAccess.GenericWrite
            , FileShare.ReadWrite
            , IntPtr.Zero
            , FileMode.Open
            , FileAttributes.Normal
            , IntPtr.Zero
            );
        if (handle == InvalidHandleValue)
            throw new Win32Exception();
        return handle;
    }

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool AllocConsole();

    [DllImport("kernel32.dll")]
    private static extern bool SetStdHandle(StdHandle nStdHandle, IntPtr hHandle);

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern IntPtr CreateFile
        (                               string         lpFileName
        , [MarshalAs(UnmanagedType.U4)] DesiredAccess  dwDesiredAccess
        , [MarshalAs(UnmanagedType.U4)] FileShare      dwShareMode
        ,                               IntPtr         lpSecurityAttributes
        , [MarshalAs(UnmanagedType.U4)] FileMode       dwCreationDisposition
        , [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes
        ,                               IntPtr         hTemplateFile
        );

    [Flags]
    enum DesiredAccess : uint
    {
        GenericRead    = 0x80000000,
        GenericWrite   = 0x40000000,
        GenericExecute = 0x20000000,
        GenericAll     = 0x10000000
    }

    private enum StdHandle : int
    {
        Input  = -10,
        Output = -11,
        Error  = -12
    }

    private static readonly IntPtr InvalidHandleValue = new IntPtr(-1);
}

答案 1 :(得分:0)

您可以通过启动应用程序来重定向输出,如此(参考1)

//
// Setup the process with the ProcessStartInfo class.
//
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = @"C:\MyExe.exe"; // Specify exe name.
start.UseShellExecute = false;
start.RedirectStandardOutput = true;

您还可以通过以下(参考1)消耗输出(如果需要):

//
// Start the process.
//
using (Process process = Process.Start(start))
{
    //
    // Read in all the text from the process with the StreamReader.
    //
    using (StreamReader reader = process.StandardOutput)
    {
    string result = reader.ReadToEnd();
    Console.Write(result);
    }
}

参考文献: (1)http://www.dotnetperls.com/redirectstandardoutput