问题
I am making a tutorial program for a friend of mine using batching programming. I would like to know if it is possible if there is code I can write in the file that will display the current color code.
Example being the color is currently set to 0A and I want be displayed on the line saying:
echo The color is currently set to 0A
.
I want my file to read the code that is set to and display it to help them remember what changes they have made as this is an example program for color codes in the command prompt/batch.
Thank you for your help!
回答1:
It is easy to make your own command to do this. Copy both below text files into GetConsoleColour.bat
and GetConsoleColour.vb
in the same folder. Double click the batch file and it will create GetConsoleColour.exe
.
PS Colour is spelt right for my culture. As I'm writing it I don't see any need to use American spelling which in programming you usually have to do.
See https://docs.microsoft.com/en-us/windows/console/getconsolescreenbufferinfo
GetConsoleColour.exe prints the current console colour in hex and returns an errorlevel with the value
To use
C:\PathToFile\GetConsoleColour
I have a program here that sets text color line by line. It is the only technique that will work on all Windows computers.
Command Prompt Scripting: Problem with multiple colors in a batch file.
Also a similar program saying how many processes are in this console window - ListConsole.exe list the processes in the current console and returns an errorlevel saying how many . https://winsourcecode.blogspot.com/2019/05/listconsoleexe-list-processes-in.html
REM GetConsoleColour.bat
REM This file compiles GetConsoleColour.vb to GetConsoleColour.exe
REM GetConsoleColour.exe prints the current console colour and returns an errorlevel with the value
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\vbc.exe" /target:exe /out:"%~dp0\GetConsoleColour.exe" "%~dp0\GetConsoleColour.vb"
pause
Note: There is only 4 lines of code here. The rest is just information the program needs to do those 4 lines. In a big program they would be hidden away in a separate file.
'GetConsoleColour.vb
Imports System
Imports System.IO
Imports System.Runtime.InteropServices
Imports Microsoft.Win32
Public Module MyApplication
Public Declare Function GetStdHandle Lib "kernel32" Alias "GetStdHandle" (ByVal nStdHandle As Long) As Long
Public Declare Function SetConsoleTextAttribute Lib "kernel32" Alias "SetConsoleTextAttribute" (ByVal hConsoleOutput As Long, ByVal wAttributes As Long) As Long
Public Declare Function GetConsoleScreenBufferInfo Lib "kernel32" (ByVal hConsoleOutput As Integer, ByRef lpConsoleScreenBufferInfo As CONSOLE_SCREEN_BUFFER_INFO) As Integer
Public Const STD_ERROR_HANDLE = -12&
Public Const STD_INPUT_HANDLE = -10&
Public Const STD_OUTPUT_HANDLE = -11&
<StructLayout(LayoutKind.Sequential)> _
Public Structure COORD
Public x As Short
Public y As Short
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure SMALL_RECT
Public Left As Short
Public Top As Short
Public Right As Short
Public Bottom As Short
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure CONSOLE_SCREEN_BUFFER_INFO
Public dwSize As COORD
Public dwCursorPosition As COORD
Public wAttributes As Integer
Public srWindow As SMALL_RECT
Public dwMaximumWindowSize As COORD
End Structure
Sub Main()
Dim hOut as IntPtr
Dim Ret as Integer
Dim CSBI as Console_Screen_Buffer_Info
hOut = GetStdHandle(STD_OUTPUT_HANDLE)
Ret = GetConsoleScreenBufferInfo(hOut, CSBI)
Console.Writeline(Hex(CSBI.wAttributes))
Environment.ExitCode = CSBI.wAttributes
End Sub
End Module
回答2:
As already indicated in another answer, you can use powershell from your batch-file to show you the current color sequence:
@(Set/P "=The color is currently set to "<NUL&For /F %%# In ('^""%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoP "$Console=(Get-Host).UI.RawUI;Switch($Console.BackgroundColor,$Console.ForegroundColor){'Black'{'0'}'DarkBlue'{'1'}'DarkGreen'{'2'}'DarkCyan'{'3'}'DarkRed'{'4'}'DarkMagenta'{'5'}'DarkYellow'{'6'}'Gray'{'7'}'DarkGray'{'8'}'Blue'{'9'}'Green'{'A'}'Cyan'{'B'}'Red'{'C'}'Magenta'{'D'}'Yellow'{'E'}'White'{'F'}}" 2^>NUL^"')Do @Set/P=%%#<NUL)&Echo(&Pause
You should also be able to do it from the command-prompt thus:
(Set/P "=The color is currently set to "<NUL&For /F %# In ('^""%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoP "$Console=(Get-Host).UI.RawUI;Switch($Console.BackgroundColor,$Console.ForegroundColor){'Black'{'0'}'DarkBlue'{'1'}'DarkGreen'{'2'}'DarkCyan'{'3'}'DarkRed'{'4'}'DarkMagenta'{'5'}'DarkYellow'{'6'}'Gray'{'7'}'DarkGray'{'8'}'Blue'{'9'}'Green'{'A'}'Cyan'{'B'}'Red'{'C'}'Magenta'{'D'}'Yellow'{'E'}'White'{'F'}}" 2^>NUL^"')Do @Set/P=%#<NUL)&Echo(
回答3:
By making a compromise and using setlocal EnableDelayedExpansion, you can do so using the following:
@ECHO OFF
Setlocal enableDelayedExpansion
Set "Color=Color 02" && !color!
ECHO Color is currently %color%
pause
The downside of this approach being changing console Color becomes a 2 Step process (depending on how your displaying information).
回答4:
- Updated based in comments from @phuclv
@echo off && setlocal EnableDelayedExpansion
set "_color="0 Black","1 DarkBlue","2 DarkGreen","3 DarkCyan","4 DarkRed","
@set "_color=!_color!"5 DarkMagenta","6 DarkYellow","7 Gray","8 DarkGray","
set "_color=!_color!"9 Blue","A Green","B Cyan","C Red","D Magenta","
set "_color=!_color!"E Yellow","F White"" && cd/d "%~dp0" && title %0
;for /f %%I in ('powershell echo "$([console]::ForegroundColor) $([console]::BackgroundColor)"
')do for %%# in (!_color!)do set "_Hex=%%~#"&& for /f %%a in ('cd')do if "%%~I"=="!_Hex:~2!" (
if not "!_FB!"=="!_Hex:~1,1!" ( set "_FB=!_Hex:~0,1!!_FB!" && set "_L= !_Hex:~2!!_L!"))
set "_L=!_L:~1!"&& cmd/v/c echo The color is currently set to !_FB! (!_L: =/!^)&&endlocal
- Output:
The color is currently set to 0A (Black/Green)
rem :: powershell command ::
echo "$([console]::BackgroundColor) $([console]::ForegroundColor)"
@echo off && setlocal EnableDelayedExpansion
set "_color="0 Black","1 DarkBlue","2 DarkGreen","3 DarkCyan","4 DarkRed","
;set "_color=!_color!"5 DarkMagenta","6 DarkYellow","7 Gray","8 DarkGray","
set "_color=!_color!"9 Blue","A Green","B Cyan","C Red","D Magenta","
set "_color=!_color!"E Yellow","F White"" && cd/d "%~dp0" && title %0
for /f %%I in ('powershell echo "$Host.UI.RawUI.BackgroundColor $Host.UI.RawUI.ForegroundColor"
')do for %%# in (!_color!)do set "_Hex=%%~#"&& for /f %%a in ('cd')do if "%%~I"=="!_Hex:~2!" (
if not "!_FB!"=="!_Hex:~1,1!" ( set "_FB=!_Hex:~0,1!!_FB!" && set "_L= !_Hex:~2!!_L!" ))
set "_L=!_L:~1!"&& cmd/v/c echo The color is currently set to !_FB! (!_L: =/!^)&&endlocal
- Output:
The color is currently set to 0A (Black/Green)
rem :: powershell command ::
echo "$Host.UI.RawUI.BackgroundColor $Host.UI.RawUI.ForegroundColor"
- Generate C# .exe in Run Time
This bat file that generate a file cFB.cs (colorForegroundBackground.C#) and in run time, will build the executable cFB.exe for execute them using ConsoleColor Enum
@echo off && setlocal EnableDelayedExpansion
set "_color="0 Black","1 DarkBlue","2 DarkGreen","3 DarkCyan","4 DarkRed","
@set "_color=!_color!"5 DarkMagenta","6 DarkYellow","7 Gray","8 DarkGray","
set "_color=!_color!"9 Blue","A Green","B Cyan","C Red","D Magenta","
set "_color=!_color!"E Yellow","F White"" && cd/d "%~dp0" && title %0
for %%D in (.exe,.cs) do if exist "%temp%\cFB%%~D" (2>nul >nul del /q /f "%temp%\cFB%%~D")
set "_csc=%windir%\Microsoft.NET"&& set "_where=%__appdir__%where.exe" && set "_cs=cFB.cs"
set "_arg=/t:exe /out:"%tmp%\!_cs:~,-3!.exe" "%tmp%\!_cs!" /platform:x86 /unsafe+ /w:0 /o"
set "_c=!_where! /r "!_csc!" "csc.exe" "&& set "_#=%temp%\!_cs!" && cmd/v/c echo=&>"!_#!"^
(
echo/ using System; namespace cFB ^{class Program ^{public static void Main(^)^{
echo/ ConsoleColor currentForeground=Console.ForegroundColor;
echo/ ConsoleColor currentBackground=Console.BackgroundColor;
echo/ Console.WriteLine("{0}\n{1}",Console.ForegroundColor,Console.BackgroundColor^);^}^}^}
) && (pushd "%temp%" & goto :run)||echo=Well, something is really wrong here^!! & goto :Err
:run
for /f tokens^=* %%i in ('!_c!^|find "k\v2"')do "%%~i" /nologo !_arg!&& if exist "!_#:~0,-3!.exe" (
for /f ^delims^=^ ^eol^= %%r in ('"!_#:~0,-3!.exe"')do set "_Hex=%%r") else (popd && cls 2>nul && (
echo=File: "!_#:~0,-3!.exe" not found, something is really wrong here^^!!& timeout -1& goto :Err) )
for /f tokens^=^*^delims^= %%I in ('"!_#:~0,-3!.exe"')do for %%# in (!_color!)do set "_h=%%~#" && (
if "%%~I"=="!_h:~2!" if not "!_fb!"=="!_h:~0,l!" (set "_fb=!_h:~0,1!!_fb!"&&set "_l= !_h:~2!!_l!"))
set "_l=!_l:~1!" && for %%D in (.exe,.cs) do if exist "%temp%\cFB%%~D" >nul del /q "%temp%\cFB%%~D"
cmd /v /c echo The color is currently set to: !_fb! (!_l: =/!^) && endlocal && exit /b || goto :EOF
:Err
endlocal & exit /b || goto :EOF
This is C# code without escaping:
using System;
namespace CBF
{
class Program
{
public static void Main()
{
ConsoleColor currentBackground=Console.BackgroundColor;
ConsoleColor currentForeground=Console.ForegroundColor;
Console.WriteLine("{0}\n{1}",Console.ForegroundColor,Console.BackgroundColor);
}
}
}
- Bat Run C# Commmand Output:
The color is currently set to: 0A (Black/Green)
- Command line to build executable:
"C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe" /nologo /t:exe /out:"%temp%\cFB.exe" "%temp%\cFB.cs" /platform:x86 /w:0 /o
You also, can try get some help with $Host.UI.RawUI in powershell?
@echo off && setlocal EnableDelayedExpansion
set "_color="0 Black","1 DarkBlue","2 DarkGreen","3 DarkCyan","4 DarkRed","
@set "_color=!_color!"5 DarkMagenta","6 DarkYellow","7 Gray","8 DarkGray","
set "_color=!_color!"9 Blue","A Green","B Cyan","C Red","D Magenta","
set "_color=!_color!"E Yellow","F White""&& cd/d "%~dp0" && title %~0
for /f tokens^=2^delims^=^:^ %%I in ('powershell -nOp $Host.UI.RawUI^|find "Color"')do (
for %%# in (!_color!)do set "_Hex=%%~#"&& for /f %%a in ('cd')do if "%%~I"=="!_Hex:~2!" (
if not "!_FB!"=="!_Hex:~1,1!" ( set "_FB=!_Hex:~0,1!!_FB!" && set "_L= !_Hex:~2!!_L!" )))
set "_L=!_L:~1!"&& cmd/v/c echo The color is currently set to !_FB! (!_L: =/!^)&&endlocal
- Bat File Output:
The color is currently set to A3 (Green/DarkCyan)
rem :: just type ::
powershell -nop -c "$Host.UI.RawUI"|find "Color"
- $Host.UI.RawUI Output:
ForegroundColor : White
BackgroundColor : Blue
- $Host.UI.RawUI Full output:
ForegroundColor : White
BackgroundColor : Blue
CursorPosition : 0,108
WindowPosition : 0,90
CursorSize : 25
BufferSize : 99,770
WindowSize : 89,48
MaxWindowSize : 99,50
MaxPhysicalWindowSize : 174,50
KeyAvailable : False
WindowTitle : Q59449889v2.cmd - powershell $Host.UI.RawUI
Sorry my limited English
来源:https://stackoverflow.com/questions/59472921/is-it-possible-to-output-the-current-color-code-on-the-command-prompt-using-batc