我有一些代码:
cmdProcess = new Process();
var procStartInfo = new ProcessStartInfo( "cmd", "/k "C:\\Program Files (x86)\\Far Manager\\Far.exe"" );
procStartInfo.RedirectStandardOutput = true;
procStartInfo.RedirectStandardInput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
cmdProcess.OutputDataReceived += ( s, e ) => {
callbackFn(e.Data + "\n");
};
cmdProcess.StartInfo = procStartInfo;
cmdProcess.Start();
cmdProcess.BeginOutputReadLine();
但是使用这段代码我只能启动过程并获得一些东西,但不是完全而不是颜色。我也尝试了ReceiveConsoleOutput
函数,我只收到空白缓冲区。
使用WinAPI,我只能启动控制台,而不是其他任何东西 - 我不太了解它。但我并不反对WinAPI的例子,因为我认为我的问题可以用它来解决。
如果有人能帮助我,我将不胜感激。
P.S。我很抱歉英语不好。
答案 0 :(得分:3)
你谈到两件不同的事情。 ConEmu和原始控制台都有颜色支持,但这是通过console buffer API实现的(here是一个完整的C#库)。控制台不仅支持着色,还支持光标和鼠标;但是,它们都与标准输出无关。
但是如果你想在标准输出中接收颜色信息,你可以使用ANSI escape sequences,它是终端通信的标准(这也用于ANSI graphics art),支持着色和光标定位也可以编码为字符流。
但是如果您调用的进程没有转储ANSI序列,(cmd
不执行此操作),您将不会收到任何颜色信息。
答案 1 :(得分:-1)
使用ReadConsoleOutput代码不能正常工作,因为它不是FreeConsole函数被调用 - 免除其自己的控制台应用程序
public static IEnumerable<string> ReadFromBuffer(IntPtr hOutput, short x, short y, short width, short height)
{
IntPtr buffer = Marshal.AllocHGlobal(width * height * Marshal.SizeOf(typeof(CHAR_INFO)));
if (buffer == null)
throw new OutOfMemoryException();
try
{
COORD coord = new COORD();
SMALL_RECT rc = new SMALL_RECT();
rc.Left = x;
rc.Top = y;
rc.Right = (short)(x + width - 1);
rc.Bottom = (short)(y + height - 1);
COORD size = new COORD();
size.X = width;
size.Y = height;
if (!ReadConsoleOutput(hOutput, buffer, size, coord, ref rc))
{
// 'Not enough storage is available to process this command' may be raised for buffer size > 64K (see ReadConsoleOutput doc.)
throw new Win32Exception(Marshal.GetLastWin32Error());
}
IntPtr ptr = buffer;
for (int h = 0; h < height; h++)
{
StringBuilder sb = new StringBuilder();
for (int w = 0; w < width; w++)
{
CHAR_INFO ci = (CHAR_INFO)Marshal.PtrToStructure(ptr, typeof(CHAR_INFO));
char[] chars = Console.OutputEncoding.GetChars(ci.charData);
sb.Append(chars[0]);
ptr += Marshal.SizeOf(typeof(CHAR_INFO));
}
yield return sb.ToString();
}
}
finally
{
Marshal.FreeHGlobal(buffer);
}
}
...
Process proc = new Process();
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.Arguments = command;
//proc.StartInfo.UseShellExecute = false;
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;
}
}