2

で作成されたコンソールを使用する GUI C# アプリがありますAllocConsole。通常の状態では機能しますが、Visual Studio でアプリをデバッグ モードで起動すると、すべての出力が Visual Studio の [出力] ウィンドウに表示されます。どうすればそれを止めることができますか?

C# 3.5 と Visual Studio Pro 2010 を使用しています。プロセス ホスティング オプションはオフになっています。

4

2 に答える 2

6

私の解決策は、標準ストリームを新しく作成したコンソールに自分でリセットすることでした。コードは次のとおりです。

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);
}
于 2012-12-31T10:40:29.107 に答える
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

于 2012-10-24T14:09:18.507 に答える