我有一個GUI C#應用程序,它使用用AllocConsole
創建的控制檯。它在正常情況下工作,但是當應用程序在Visual Studio下以調試模式啓動時,所有輸出都將在Visual Studio輸出窗口中結束。我如何阻止?如何阻止VC#將控制檯輸出重定向到輸出窗口?
我正在使用C#3.5和Visual Studio Pro 2010. 進程託管選項已關閉。
我有一個GUI C#應用程序,它使用用AllocConsole
創建的控制檯。它在正常情況下工作,但是當應用程序在Visual Studio下以調試模式啓動時,所有輸出都將在Visual Studio輸出窗口中結束。我如何阻止?如何阻止VC#將控制檯輸出重定向到輸出窗口?
我正在使用C#3.5和Visual Studio Pro 2010. 進程託管選項已關閉。
我的解決方案是將標準流重置爲新創建的控制檯。這裏是代碼:
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);
}
哪個命名空間做DesiredAccess來自? –
啊,好像是從http://www.pinvoke.net/default.aspx/kernel32.createfile派生的 –
您可以通過啓動該應用程序不同,像這樣(參考文獻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);
}
}
我沒有重定向另一個可執行文件的流。 –
不,這應該工作得很好,如果C#代碼*實際*使用Console.Write/Line()。如果它執行諸如Debug.Print或跟蹤之類的操作,則輸出由OutputDebugString()寫入,並最終在調試器窗口中結束。輸出窗口。考慮SysInternals的DebugView工具。 –
我使用Console.WriteLine,它結束於Visual Studio輸出窗口,而不是我的控制檯。 –
很難解釋。嘗試關閉託管過程選項。 –