使用ReadConsoleOutput代码不像应该的那样工作,因为它没有调用FreeConsole函数 - 用于从其自身的控制台应用程序中豁免
证明
public static IEnumerable<string> ReadFromBuffer(IntPtr hOutput, short x, short y, short width, short height)
IntPtr ptr = buffer;
for (int h = 0; h < height; h++)
yield return sb.ToString();
}
}
finally
}
...
Process proc = new Process();
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.Arguments = command;
proc.Start();
Thread.Sleep(1000);
bool resultFree = ConsoleApi.FreeConsole();
if (resultFree)
{
Debug.WriteLine("FreeConsole: {0}", true);
}
else
{
Debug.WriteLine("FreeConsole: {0}", false);
}
Debug.WriteLine("Process ID: {0}", Convert.ToUInt32(proc.Id));
bool result = ConsoleApi.AttachConsole( Convert.ToUInt32(proc.Id) );
Debug.WriteLine("AttachConsole: {0}", result);
IntPtr _consoleH = ConsoleApi.GetStdHandle(ConsoleApi.STD_OUTPUT_HANDLE);
ConsoleApi.CONSOLE_SCREEN_BUFFER_INFO _bufferInfo;
bool getInfo = ConsoleApi.GetConsoleScreenBufferInfo(_consoleH, out _bufferInfo);
if (getInfo)
{
Debug.WriteLine("GetConsoleScreenBufferInfo: {0}x{1}", _bufferInfo.dwSize.X, _bufferInfo.dwSize.Y);
}
else
{
Debug.WriteLine("GetConsoleScreenBufferInfo: {0}", false);
}
short _widthConsole = _bufferInfo.dwSize.X;
short _heightConsole = _bufferInfo.dwSize.Y;
IEnumerable<string> rows = ConsoleApi.ReadFromBuffer(_consoleH, 0, 0, _widthConsole,_heightConsole);
foreach (string row in rows)
{
Debug.WriteLine(row);
}
读取颜色:
[DllImport("kernel32.dll")]
public static extern bool ReadConsoleOutputAttribute(IntPtr hConsoleOutput,
[Out] ushort[] lpAttribute, uint nLength, COORD dwReadCoord,
out uint lpNumberOfAttrsRead);
...
string[] colors = new string[]{
"black",
"darkblue",
"darkgreen",
"darkcyan",
"darkred",
"darkmagenta",
"brown",
"white",
"lightgrey",
"blue",
"green",
"cyan",
"red",
"magenta",
"yellow",
"white"
};
for (int i = 0; i < _rowsList.Length; i++)
{
ushort[] lpAttr = new ushort[_widthConsole];
ConsoleApi.COORD _coordReadAttr = new ConsoleApi.COORD(0,(short)i);
uint lpReadALast;
bool readAttr = ConsoleApi.ReadConsoleOutputAttribute(_consoleH, lpAttr, Convert.ToUInt32(_widthConsole), _coordReadAttr, out lpReadALast);
string[] attrText = new string[_widthConsole];
for (int _attr = 0; _attr < lpAttr.Length; _attr++)
{
string _text = colors[lpAttr[_attr] & 0x0F];
string _background = colors[((lpAttr[_attr] & 0xF0) >> 4) & 0x0F];
attrText[_attr] = _text + "|" + _background;
}
}