使用 .NET Core 在 windows 上执行 cmd.exe 命令 (webpack) 并保留颜色和输出
Execute cmd.exe command (webpack) on windows with .NET Core and preserve colors and output
如何从 .NET Core - 控制台应用程序执行 cmd 命令 (webpack
) 并保留颜色?
这是我当前的代码:
static void Main(string[] args)
{
var dir = args.First();
//build:vendor -> webpack --config webpack.config.vendor.js --progress --color --display-error-details
Console.WriteLine("npm run build:vendor -- --env.prod".Execute(dir));
Console.ReadKey();
}
public static string Execute(this string cmd, string startDir)
{
var process = new Process()
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/c {cmd}",
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
WorkingDirectory = startDir
}
};
process.Start();
string result = process.StandardOutput.ReadToEnd();
process.WaitForExit();
return result;
}
我的输出:
预期输出:
我看到 2 个问题:
当我 运行 命令
- 从 cmd.exe 开始,进度以百分比显示,但 运行ning 命令
从 dotnet 输出奇怪的字符 ...
- 缺少颜色
从您的屏幕截图来看,您的工具似乎使用 ANSI escape codes 来格式化输出。这些是由支持命令而不是常规文本的终端解释的字符序列。
在Windows10之前,cmd.exe不支持此类代码,而是需要使用特定的winapi函数来控制控制台文本颜色和其他属性。从 Windows 10 开始支持,但必须启用。
例如,假设您这样做:
Console.WriteLine("\x1b[35mHello World\x1b[0m");
默认情况下,它会打印一些类似于您当前输出的废话。现在让我们启用对 ANSI 转义码的支持。为此,我们需要调用 winapi 函数 SetConsoleMode
:
[DllImport("kernel32.dll")]
static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
并使用一些辅助 winapi 函数:
[DllImport("kernel32.dll")]
static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
现在我们可以启用所需的标志:
public class Program {
static void Main(string[] args) {
const int STD_OUTPUT_HANDLE = -11;
// get handle to console output
IntPtr hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut != IntPtr.Zero) {
uint mode;
// get current mode
if (GetConsoleMode(hOut, out mode)) {
// add ENABLE_VIRTUAL_TERMINAL_PROCESSING flag which enables support for ANSI escape codes
mode |= 0x0004; // ENABLE_VIRTUAL_TERMINAL_PROCESSING flag
SetConsoleMode(hOut, mode);
}
}
Console.WriteLine("\x1b[35mHello World\x1b[0m");
}
[DllImport("kernel32.dll")]
static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
[DllImport("kernel32.dll")]
static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
}
如果你 运行 在 Windows 10 上这样做,而不是一些废话,它应该以 magentoo 颜色打印 "Hello World" 到控制台输出。
因此,如果您在编写重定向输出之前执行此操作 - 它应该可以解决您的问题。
如何从 .NET Core - 控制台应用程序执行 cmd 命令 (webpack
) 并保留颜色?
这是我当前的代码:
static void Main(string[] args)
{
var dir = args.First();
//build:vendor -> webpack --config webpack.config.vendor.js --progress --color --display-error-details
Console.WriteLine("npm run build:vendor -- --env.prod".Execute(dir));
Console.ReadKey();
}
public static string Execute(this string cmd, string startDir)
{
var process = new Process()
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/c {cmd}",
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
WorkingDirectory = startDir
}
};
process.Start();
string result = process.StandardOutput.ReadToEnd();
process.WaitForExit();
return result;
}
我的输出:
预期输出:
我看到 2 个问题: 当我 运行 命令
- 从 cmd.exe 开始,进度以百分比显示,但 运行ning 命令 从 dotnet 输出奇怪的字符 ...
- 缺少颜色
从您的屏幕截图来看,您的工具似乎使用 ANSI escape codes 来格式化输出。这些是由支持命令而不是常规文本的终端解释的字符序列。
在Windows10之前,cmd.exe不支持此类代码,而是需要使用特定的winapi函数来控制控制台文本颜色和其他属性。从 Windows 10 开始支持,但必须启用。
例如,假设您这样做:
Console.WriteLine("\x1b[35mHello World\x1b[0m");
默认情况下,它会打印一些类似于您当前输出的废话。现在让我们启用对 ANSI 转义码的支持。为此,我们需要调用 winapi 函数 SetConsoleMode
:
[DllImport("kernel32.dll")]
static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
并使用一些辅助 winapi 函数:
[DllImport("kernel32.dll")]
static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
现在我们可以启用所需的标志:
public class Program {
static void Main(string[] args) {
const int STD_OUTPUT_HANDLE = -11;
// get handle to console output
IntPtr hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut != IntPtr.Zero) {
uint mode;
// get current mode
if (GetConsoleMode(hOut, out mode)) {
// add ENABLE_VIRTUAL_TERMINAL_PROCESSING flag which enables support for ANSI escape codes
mode |= 0x0004; // ENABLE_VIRTUAL_TERMINAL_PROCESSING flag
SetConsoleMode(hOut, mode);
}
}
Console.WriteLine("\x1b[35mHello World\x1b[0m");
}
[DllImport("kernel32.dll")]
static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
[DllImport("kernel32.dll")]
static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
}
如果你 运行 在 Windows 10 上这样做,而不是一些废话,它应该以 magentoo 颜色打印 "Hello World" 到控制台输出。
因此,如果您在编写重定向输出之前执行此操作 - 它应该可以解决您的问题。