大厦从wischi答案,如果你想要的属性静态控制台类才能正常工作,例如Console.ForegroundColor,将所需的访问权限设置为GENERIC_READ | GENERIC_WRITE。我认为这是因为控制台在内部使用GetConsoleScreenBufferInfo,当我尝试在由CreateFile返回的句柄上使用该方法时,只有GENERIC_WRITE给了我一个ACCESS_DENIED错误。
[DllImport("kernel32.dll")]
private static extern bool AllocConsole();
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr CreateFile(string lpFileName
, [MarshalAs(UnmanagedType.U4)] DesiredAccess dwDesiredAccess
, [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode
, uint lpSecurityAttributes
, [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition
, [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes
, uint hTemplateFile);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetStdHandle(StdHandle nStdHandle, IntPtr hHandle);
private enum StdHandle : int
{
Input = -10,
Output = -11,
Error = -12
}
[Flags]
enum DesiredAccess : uint
{
GenericRead = 0x80000000,
GenericWrite = 0x40000000,
GenericExecute = 0x20000000,
GenericAll = 0x10000000
}
public static void CreateConsole()
{
if (AllocConsole())
{
//https://developercommunity.visualstudio.com/content/problem/12166/console-output-is-gone-in-vs2017-works-fine-when-d.html
// Console.OpenStandardOutput eventually calls into GetStdHandle. As per MSDN documentation of GetStdHandle: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231(v=vs.85).aspx will return the redirected handle and not the allocated console:
// "The standard handles of a process may be redirected by a call to SetStdHandle, in which case GetStdHandle returns the redirected handle. If the standard handles have been redirected, you can specify the CONIN$ value in a call to the CreateFile function to get a handle to a console's input buffer. Similarly, you can specify the CONOUT$ value to get a handle to a console's active screen buffer."
// Get the handle to CONOUT$.
var stdOutHandle = CreateFile("CONOUT$", DesiredAccess.GenericRead | DesiredAccess.GenericWrite, FileShare.ReadWrite, 0, FileMode.Open, FileAttributes.Normal, 0);
if (stdOutHandle == new IntPtr(-1))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
if (!SetStdHandle(StdHandle.Output, stdOutHandle))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
var standardOutput = new StreamWriter(Console.OpenStandardOutput());
standardOutput.AutoFlush = true;
Console.SetOut(standardOutput);
}
}
由于VS2017仍处于RC阶段,[我会直接询问](https://docs.microsoft.com/en-us/visualstudio/ide/how-to-report-a-问题与视觉工作室2017) –
可能重复...这是你可以在项目中设置的东西。查看Chaz的答案[如何在窗体中显示控制台输出/窗口](http://stackoverflow.com/questions/4362111/how-do-i-show-a-console-output-window-in-a -forms-application) – JohnG
@JohnG谢谢!一种更简单的方法来完成所需的工作。 – apotter96