2012-10-24 57 views
0

我有一個GUI C#應用程序,它使用用AllocConsole創建的控制檯。它在正常情況下工作,但是當應用程序在Visual Studio下以調試模式啓動時,所有輸出都將在Visual Studio輸出窗口中結束。我如何阻止?如何阻止VC#將控制檯輸出重定向到輸出窗口?

我正在使用C#3.5和Visual Studio Pro 2010. 進程託管選項已關閉。

+0

不,這應該工作得很好,如果C#代碼*實際*使用Console.Write/Line()。如果它執行諸如Debug.Print或跟蹤之類的操作,則輸出由OutputDebugString()寫入,並最終在調試器窗口中結束。輸出窗口。考慮SysInternals的DebugView工具。 –

+0

我使用Console.WriteLine,它結束於Visual Studio輸出窗口,而不是我的控制檯。 –

+0

很難解釋。嘗試關閉託管過程選項。 –

回答

3

我的解決方案是將標準流重置爲新創建的控制檯。這裏是代碼:

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); 
} 
+0

哪個命名空間做DesiredAccess來自? –

+0

啊,好像是從http://www.pinvoke.net/default.aspx/kernel32.createfile派生的 –

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

+0

我沒有重定向另一個可執行文件的流。 –

相關問題