在批处理中,每行可以有不同的颜色。
例如,如果您有一个批处理文件,内容如下:
"Hello" "How are you?"
你可以让"Hello"显示为蓝色,"How are you"显示为绿色吗?
(我知道关于color命令,并且它会同时改变背景和文本的颜色)
在批处理中,每行可以有不同的颜色。
例如,如果您有一个批处理文件,内容如下:
"Hello" "How are you?"
你可以让"Hello"显示为蓝色,"How are you"显示为绿色吗?
(我知道关于color命令,并且它会同时改变背景和文本的颜色)
您可以不需要任何外部程序就能完成这个操作。以下是我几天前发现的,非常好用。
@echo off
SETLOCAL EnableDelayedExpansion
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
set "DEL=%%a"
)
echo say the name of the colors, don't read
call :ColorText 0a "blue"
call :ColorText 0C "green"
call :ColorText 0b "red"
echo(
call :ColorText 19 "yellow"
call :ColorText 2F "black"
call :ColorText 4e "white"
goto :eof
:ColorText
echo off
<nul set /p ".=%DEL%" > "%~2"
findstr /v /a:%1 /R "^$" "%~2" nul
del "%~2" > nul 2>&1
goto :eof
感谢jeb 您可以在他的帖子中找到此内容
:*?"
。 - jebfindstr
。 - Jorjoncolormsg color "Message"
。@echo off
(
echo e100
echo 0F B6 0E 80 00 E3 4F BF 81 00 B0 20 FC F3 AE 74
echo e110
echo 45 E3 43 8A 45 FF E8 43 00 80 3D 20 74 0E C0 E0
echo e120
echo 04 8A E0 8A 05 E8 34 00 0A C4 47 49 E3 28 32 E4
echo e130
echo 50 B0 22 F2 AE 75 1F E3 1D 8B F7 8B D1 F2 AE 75
echo e140
echo 01 41 2B D1 74 10 8B CA 5B B0 20 B4 09 CD 10 AC
echo e150
echo B4 0E CD 10 E2 F9 32 C0 B4 4C CD 21 3C 61 72 02
echo e160
echo 2C 20 3C 41 72 02 2C 07 2C 30 C3
echo rcx
echo 6b
echo w
echo q
) | debug colormsg.com > nul
在消息后,光标不会移动到新行,因此可能会在同一行显示多个消息。为了更轻松地设置颜色,您可以使用以下定义:
set Black=0& set Gray=8
set Blue=1& set LightBlue=9
set Green=2& set LightGreen=A
set Aqua=3& set LightAqua=B
set Red=4& set LightRed=C
set Purple=5& set LightPurple=D
set Yellow=6& set LightYellow=E
set White=7& set BrightWhite=F
例如:
colormsg %Yellow% "Message in yellow "
colormsg %Blue%%BrightWhite% "Bright white text over blue background"
这是一个更大的例子:
@echo off
setlocal EnableDelayedExpansion
set i=0
for %%c in (Blk Blu Grn Aqu Red Pur Yel Whi) do (
set color[!i!]=%%c
set /A i+=1
)
for /L %%j in (0,1,7) do (
set color[!i!]=L!color[%%j]:~0,-1!
set /A i+=1
)
cls
echo/
echo BACKGROUND / FOREGROUND COMBINATIONS OF AVAILABLE SCREEN COLORS
echo/
echo/
colormsg 7 "ForeGrnd:"
for /L %%i in (0,1,15) do colormsg 7 " !color[%%i]!"
echo/
echo BackGrnd
set i=0
for /L %%b in (0,1,9) do call :ShowLine %%b
for %%b in (A B C D E F) do call :ShowLine %%b
echo/
goto :eof
:ShowLine
colormsg 7 " !color[%i%]! "
set /A i+=1
for /L %%f in (0,1,9) do colormsg %1%%f " %1%%f "
for %%f in (A B C D E F) do colormsg %1%%f " %1%%f "
echo/
嘿,Gareth,这是给你的奖励!以下批处理文件创建TEXTPOS.COM文件(可根据您的需要重命名),以此方式移动光标到任何行和列:textpos line col
:
@echo off
(
echo e100
echo 0F B6 0E 80 00 E3 2D BF 81 00 B0 20 FC F3 AE 74
echo e110
echo 23 E3 21 8D 75 FF E8 45 00 3C 20 75 3B 86 F2 E8
echo e120
echo 3C 00 86 F2 3C 20 74 04 3C 0D 75 2C 32 FF B4 02
echo e130
echo CD 10 EB 24 32 FF B4 03 CD 10 8A C6 8A CA E8 38
echo e140
echo 00 B2 20 B4 02 CD 21 8A C1 E8 2D 00 B2 0D B4 02
echo e150
echo CD 21 B2 0A B4 02 CD 21 32 C0 B4 4C CD 21 32 E4
echo e160
echo AC 3C 20 74 FB 3C 30 72 0D 3C 39 77 09 2C 30 D5
echo e170
echo 0A 8A E0 AC EB EF 8A F4 C3 D4 0A 05 30 30 8B D0
echo e180
echo 80 FC 30 74 08 86 D6 B4 02 CD 21 8A D6 B4 02 CD
echo e190
echo 21 C3
echo rcx
echo 92
echo w
echo q
) | debug textpos.com > nul
例如:
textpos 0 0
colormsg %Red% "Red message at top left corner of the screen"
textpos 10 40
colormsg %Blue%%LightYellow% "This message start in line 10 column 40"
编辑
我稍微修改了TEXTPOS程序,如果不带参数执行,它会显示当前光标位置;这个功能可以让你将光标位置存储在一个变量中,操作如下:textpos > pipe.txt & set /P pos=< pipe.txt
(因为textpos | set /P pos=
存在错误,不能正常工作)。
如果使用相同的背景和前景颜色显示彩色消息,文本将无法在屏幕上显示;这个特性可以用于输入密码。例如,这是getpassword.bat
文件:
@echo off
set password=
for /L %%i in (1,1,%1) do set password=!password!x
colormsg 7 "Enter password: "
textpos > pipe.txt & set /P passpos=< pipe.txt
colormsg 77 "%password%"
textpos %passpos%
set password=
for /L %%i in (1,1,%1) do (
getakey
set password=!password!!errorlevel!
colormsg 7F "*"
)
之前的批处理文件可以读取一个给定字符数的密码,例如:call getpassword 8
;输入的字符会被其ASCII代码替换,因此密码具有基本的加密功能。例如,要检查输入的密码是否为“Pass”:
call getpassword 4
if %password% == 8097115115 goto right_password
我之前在一个问题中提供了GETAKEY.COM程序,但这里再提供一次:
@echo off
(
echo e100
echo B4 08 CD 21 B4 4C CD 21
echo rcx
echo 8
echo w
echo q
) | debug getakey.com > nul
:(
请注意,此解决方案是在2011年10月发布的,当时还没有64位版本的Windows,而且这种方法在所有计算机上都可以正确运行! - Aacini把这段代码保存为.bat
(它是自编译的.net混合代码):
@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal
for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do (
set "jsc=%%v"
)
if not exist "%~n0.exe" (
"%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0"
)
%~n0.exe %*
endlocal & exit /b %errorlevel%
*/
import System;
var arguments:String[] = Environment.GetCommandLineArgs();
var newLine = false;
var output = "";
var foregroundColor = Console.ForegroundColor;
var backgroundColor = Console.BackgroundColor;
var evaluate = false;
var currentBackground=Console.BackgroundColor;
var currentForeground=Console.ForegroundColor;
//http://stackoverflow.com/a/24294348/388389
var jsEscapes = {
'n': '\n',
'r': '\r',
't': '\t',
'f': '\f',
'v': '\v',
'b': '\b'
};
function decodeJsEscape(_, hex0, hex1, octal, other) {
var hex = hex0 || hex1;
if (hex) { return String.fromCharCode(parseInt(hex, 16)); }
if (octal) { return String.fromCharCode(parseInt(octal, 8)); }
return jsEscapes[other] || other;
}
function decodeJsString(s) {
return s.replace(
// Matches an escape sequence with UTF-16 in group 1, single byte hex in group 2,
// octal in group 3, and arbitrary other single-character escapes in group 4.
/\\(?:u([0-9A-Fa-f]{4})|x([0-9A-Fa-f]{2})|([0-3][0-7]{0,2}|[4-7][0-7]?)|(.))/g,
decodeJsEscape);
}
function printHelp( ) {
print( arguments[0] + " -s string [-f foreground] [-b background] [-n] [-e]" );
print( " " );
print( " string String to be printed" );
print( " foreground Foreground color - a " );
print( " number between 0 and 15." );
print( " background Background color - a " );
print( " number between 0 and 15." );
print( " -n Indicates if a new line should" );
print( " be written at the end of the ");
print( " string(by default - no)." );
print( " -e Evaluates special character " );
print( " sequences like \\n\\b\\r and etc ");
print( "" );
print( "Colors :" );
for ( var c = 0 ; c < 16 ; c++ ) {
Console.BackgroundColor = c;
Console.Write( " " );
Console.BackgroundColor=currentBackground;
Console.Write( "-"+c );
Console.WriteLine( "" );
}
Console.BackgroundColor=currentBackground;
}
function errorChecker( e:Error ) {
if ( e.message == "Input string was not in a correct format." ) {
print( "the color parameters should be numbers between 0 and 15" );
Environment.Exit( 1 );
} else if (e.message == "Index was outside the bounds of the array.") {
print( "invalid arguments" );
Environment.Exit( 2 );
} else {
print ( "Error Message: " + e.message );
print ( "Error Code: " + ( e.number & 0xFFFF ) );
print ( "Error Name: " + e.name );
Environment.Exit( 666 );
}
}
function numberChecker( i:Int32 ){
if( i > 15 || i < 0 ) {
print("the color parameters should be numbers between 0 and 15");
Environment.Exit(1);
}
}
if ( arguments.length == 1 || arguments[1].toLowerCase() == "-help" || arguments[1].toLowerCase() == "-help" ) {
printHelp();
Environment.Exit(0);
}
for (var arg = 1; arg <= arguments.length-1; arg++ ) {
if ( arguments[arg].toLowerCase() == "-n" ) {
newLine=true;
}
if ( arguments[arg].toLowerCase() == "-e" ) {
evaluate=true;
}
if ( arguments[arg].toLowerCase() == "-s" ) {
output=arguments[arg+1];
}
if ( arguments[arg].toLowerCase() == "-b" ) {
try {
backgroundColor=Int32.Parse( arguments[arg+1] );
} catch(e) {
errorChecker(e);
}
}
if ( arguments[arg].toLowerCase() == "-f" ) {
try {
foregroundColor=Int32.Parse(arguments[arg+1]);
} catch(e) {
errorChecker(e);
}
}
}
Console.BackgroundColor = backgroundColor ;
Console.ForegroundColor = foregroundColor ;
if ( evaluate ) {
output=decodeJsString(output);
}
if ( newLine ) {
Console.WriteLine(output);
} else {
Console.Write(output);
}
Console.BackgroundColor = currentBackground;
Console.ForegroundColor = currentForeground;
@echo off
REM You can do it easily by typing this at the bottom of your file.
:[any color]
powershell -Command Write-Host "%*" -foreground "[any color]" -background "[any color]"
:[any color]
powershell -Command Write-Host "%*" -foreground "[any color]" -background "[any color]"
REM for typing text in different colors you just need to write this
call :[any color] "[any message]"
call :[any color] "[any other message]"
pause
exit
你只需要使用一点命令就可以尝试这个:
@echo off
chcp 437>nul&&graftabl 936>nul
ren %WinDir%\System32\config.nt config.nt.bak 2>nul
<"%~f0" more +6 >%WinDir%\System32\config.nt
command /cecho [1;31mHel[32mlo [33mHow[35mare[36myou[m
pause>nul&exit
DOSONLY
dos=high, umb
device=%SystemRoot%\system32\himem.sys
DEVICE==%SystemRoot%\System32\ANSI.SYS /x
files=40
将其保存为colormsg.bat
@echo off
if "%~3" == "" goto usage
powershell -command write-host -foreground "%~1" -background "%~2" -nonewline "%~3"
exit /b
:usage
echo.
echo Usage: call colormsg foreground background "message"
echo.
echo Examples:
echo call colormsg white blue "example1"
echo call colormsg 4 2 "example2"
例子:
@echo off
for /f %%a in ('"prompt $H & for %%a in (-) do rem"') do set "BS=%%a"
call colormsg blue 0 "Hello"
<nul set /p "=.%BS% "
call colormsg green 0 "How are you?"
echo.
pause
您可以尝试这个简单的脚本。它不使用临时文件。请确保您在“%path%”环境变量中列出的任何文件夹中都有“debug.exe”可执行文件。
@echo off
rem Script written by BrendanSilva [bl8086]
rem You need DEBUG.EXE executable in your system.
setlocal enabledelayedexpansion
set /a _er=0
set /a _n=0
set _ln=%~4
goto init
:howuse ------------------------------------------------------------------------
echo.
echo ECOL.BAT - v2.0
echo Print colored text as batch script without temporary files.
echo Written by bl8086
echo.
echo Syntax:
echo ECOL.BAT [COLOR] [X] [Y] "Insert your text here"
echo COLOR value must be a hexadecimal number like "color /?" information
echo.
echo Example:
echo ECOL.BAT F0 20 30 "640K ought to be enough for anybody."
echo.
goto :eof
:error ------------------------------------------------------------------------
set /a "_er=_er | (%~1)"
goto :eof
:gcnvhx ------------------------------------------------------------------------
set _cvhx=
set /a _cvint=%~1
:cnvhx
set /a "_gch = _cvint & 0xF"
set _cvhx=!nsys:~%_gch%,1!%_cvhx%
set /a "_cvint = _cvint >> 4"
if !_cvint! neq 0 goto cnvhx
goto :eof
:init --------------------------------------------------------------------------
if "%~4"=="" call :error 0xff
(
set /a _cl=0x%1
call :error !errorlevel!
set _cl=%1
call :error "0x!_cl! ^>^> 8"
set /a _px=%2
call :error !errorlevel!
set /a _py=%3
call :error !errorlevel!
) 2>nul 1>&2
if !_er! neq 0 (
echo.
echo ERROR: value exception "!_er!" occurred. Check memory out.
echo.
goto howuse
)
set nsys=0123456789ABCDEF
set /a cnb=0
set /a cnl=0
set _cvhx=0
set _cvint=0
set _cvmhx=0
:parse -------------------------------------------------------------------------
set _ch=!_ln:~%_n%,1!
if "%_ch%"=="" goto perform
set /a "cnb += 1"
if %cnb% gtr 7 (
set /a cnb=0
set /a "cnl += 1"
)
set bln%cnl%=!bln%cnl%! "!_ch!" %_cl%
set /a "_n += 1"
goto parse
:perform -----------------------------------------------------------------------
set /a "in = ((_py * 0xA0) + (_px << 1)) & 0xFFFF"
call :gcnvhx %in%
set ntr=!_cvhx!
set /a jmp=0xe
set bl8086str=echo.h 0 0
@for /l %%x in (0,1,%cnl%) do (
set bl8086str=!bl8086str!^&echo.eb800:!ntr! !bln%%x!
set /a "in=!jmp! + 0x!ntr!"
call :gcnvhx !in!
set ntr=!_cvhx!
set /a jmp=0x10
)
(
echo %bl8086str%
echo.q
) |debug >nul 2>&1
这个脚本可以将你的文本写在任何屏幕位置。同时可以使用任何颜色。
::
:: Launch a PowerShell child process in the background linked to the console and
:: earing through named pipe PowerShellCon_%PID%
::
:: Parameters :
:: [ PID ] : Console Process ID used as an identifier for the named pipe, launcher PID by default.
:: [ timeout ] : Subprocess max life in seconds, 300 by default. If -1, the subprocess
:: will not terminate while the process %PID% is still alive.
:: Return :
:: 0 if the child PowerShell has been successfully launched and the named pipe is available.
:: 1 if it fails.
:: 2 if we can't get a PID.
:: 3 if PowerShell is not present or doesn't work.
::
:LaunchPowerShellSubProcess
SET LOCALV_PID=
SET LOCALV_TIMEOUT=300
IF NOT "%~1" == "" SET LOCALV_PID=%~1
IF NOT "%~2" == "" SET LOCALV_TIMEOUT=%~2
powershell -command "$_" 2>&1 >NUL
IF NOT "!ERRORLEVEL!" == "0" EXIT /B 3
IF "!LOCALV_PID!" == "" (
FOR /F %%P IN ('powershell -command "$parentId=(Get-WmiObject Win32_Process -Filter ProcessId=$PID).ParentProcessId; write-host (Get-WmiObject Win32_Process -Filter ProcessId=$parentId).ParentProcessId;"') DO (
SET LOCALV_PID=%%P
)
)
IF "!LOCALV_PID!" == "" EXIT /B 2
START /B powershell -command "$cmdPID=$PID; Start-Job -ArgumentList $cmdPID -ScriptBlock { $ProcessActive = $true; $timeout=!LOCALV_TIMEOUT!; while((!LOCALV_TIMEOUT! -eq -1 -or $timeout -gt 0) -and $ProcessActive) { Start-Sleep -s 1; $timeout-=1; $ProcessActive = Get-Process -id !LOCALV_PID! -ErrorAction SilentlyContinue; } if ($timeout -eq 0 -or ^! $ProcessActive) { Stop-Process -Id $args; } } | Out-Null ; $npipeServer = new-object System.IO.Pipes.NamedPipeServerStream('PowerShellCon_!LOCALV_PID!', [System.IO.Pipes.PipeDirection]::In); Try { $npipeServer.WaitForConnection(); $pipeReader = new-object System.IO.StreamReader($npipeServer); while(($msg = $pipeReader.ReadLine()) -notmatch 'QUIT') { $disp='write-host '+$msg+';'; invoke-expression($disp); $npipeServer.Disconnect(); $npipeServer.WaitForConnection(); }; } Finally { $npipeServer.Dispose(); }" 2>NUL
SET /A LOCALV_TRY=20 >NUL
:LaunchPowerShellSubProcess_WaitForPipe
powershell -nop -c "& {sleep -m 50}"
SET /A LOCALV_TRY=!LOCALV_TRY! - 1 >NUL
IF NOT "!LOCALV_TRY!" == "0" cmd /C "ECHO -NoNewLine|MORE 1>\\.\pipe\PowerShellCon_!LOCALV_PID!" 2>NUL || GOTO:LaunchPowerShellSubProcess_WaitForPipe
IF "!LOCALV_TRY!" == "0" EXIT /B 1
EXIT /B 0
这段“代码”是使用延迟扩展开启编写的,但可以重写以在不使用延迟扩展的情况下工作。有许多安全要点需要考虑,在野外不要直接使用。
如何使用:
@ECHO OFF
SETLOCAL ENABLEEXTENSIONS
IF ERRORLEVEL 1 (
ECHO Extension inapplicable
EXIT /B 1
)
::
SETLOCAL ENABLEDELAYEDEXPANSION
IF ERRORLEVEL 1 (
ECHO Expansion inapplicable
EXIT /B 1
)
CALL:LaunchPowerShellSubProcess
IF NOT ERRORLEVEL 0 EXIT /B 1
CALL:Color Cyan "I write this in Cyan"
CALL:Blue "I write this in Blue"
CALL:Green "And this in green"
CALL:Red -nonewline "And mix Red"
CALL:Yellow "with Yellow"
CALL:Green "And not need to trouble with ()<>&|;,%""^ and so on..."
EXIT /B 0
:Color
ECHO -foregroundcolor %*>\\.\pipe\PowerShellCon_!LOCALV_PID!
ECHO[|SET /P=>NUL
GOTO:EOF
:Blue
ECHO -foregroundcolor Blue %*>\\.\pipe\PowerShellCon_!LOCALV_PID!
ECHO[|SET /P=>NUL
GOTO:EOF
:Green
ECHO -foregroundcolor Green %*>\\.\pipe\PowerShellCon_!LOCALV_PID!
ECHO[|SET /P=>NUL
GOTO:EOF
:Red
ECHO -foregroundcolor Red %*>\\.\pipe\PowerShellCon_!LOCALV_PID!
ECHO[|SET /P=>NUL
GOTO:EOF
:Yellow
ECHO -foregroundcolor Yellow %*>\\.\pipe\PowerShellCon_!LOCALV_PID!
ECHO[|SET /P=>NUL
GOTO:EOF
::
:: Launch a PowerShell child process in the background linked to the console and
:: earing through named pipe PowerShellCon_%PID%
::
:: Parameters :
:: [ PID ] : Console Process ID used as an identifier for the named pipe, launcher PID by default.
:: [ timeout ] : Subprocess max life in seconds, 300 by default. If -1, the subprocess
:: will not terminate while the process %PID% is still alive.
:: Return :
:: 0 if the child PowerShell has been successfully launched and the named pipe is available.
:: 1 if it fails.
:: 2 if we can't get a PID.
:: 3 if PowerShell is not present or doesn't work.
::
:LaunchPowerShellSubProcess
SET LOCALV_PID=
SET LOCALV_TIMEOUT=300
IF NOT "%~1" == "" SET LOCALV_PID=%~1
IF NOT "%~2" == "" SET LOCALV_TIMEOUT=%~2
powershell -command "$_" 2>&1 >NUL
IF NOT "!ERRORLEVEL!" == "0" EXIT /B 3
IF "!LOCALV_PID!" == "" (
FOR /F %%P IN ('powershell -command "$parentId=(Get-WmiObject Win32_Process -Filter ProcessId=$PID).ParentProcessId; write-host (Get-WmiObject Win32_Process -Filter ProcessId=$parentId).ParentProcessId;"') DO (
SET LOCALV_PID=%%P
)
)
IF "!LOCALV_PID!" == "" EXIT /B 2
START /B powershell -command "$cmdPID=$PID; Start-Job -ArgumentList $cmdPID -ScriptBlock { $ProcessActive = $true; $timeout=!LOCALV_TIMEOUT!; while((!LOCALV_TIMEOUT! -eq -1 -or $timeout -gt 0) -and $ProcessActive) { Start-Sleep -s 1; $timeout-=1; $ProcessActive = Get-Process -id !LOCALV_PID! -ErrorAction SilentlyContinue; } if ($timeout -eq 0 -or ^! $ProcessActive) { Stop-Process -Id $args; } } | Out-Null ; $npipeServer = new-object System.IO.Pipes.NamedPipeServerStream('PowerShellCon_!LOCALV_PID!', [System.IO.Pipes.PipeDirection]::In); Try { $npipeServer.WaitForConnection(); $pipeReader = new-object System.IO.StreamReader($npipeServer); while(($msg = $pipeReader.ReadLine()) -notmatch 'QUIT') { $disp='write-host '+$msg+';'; invoke-expression($disp); $npipeServer.Disconnect(); $npipeServer.WaitForConnection(); }; } Finally { $npipeServer.Dispose(); }" 2>NUL
SET /A LOCALV_TRY=20 >NUL
:LaunchPowerShellSubProcess_WaitForPipe
powershell -nop -c "& {sleep -m 50}"
SET /A LOCALV_TRY=!LOCALV_TRY! - 1 >NUL
IF NOT "!LOCALV_TRY!" == "0" cmd /C "ECHO -NoNewLine|MORE 1>\\.\pipe\PowerShellCon_!LOCALV_PID!" 2>NUL || GOTO:LaunchPowerShellSubProcess_WaitForPipe
IF "!LOCALV_TRY!" == "0" EXIT /B 1
EXIT /B 0
链接到我在同一主题上的原始答案。
对于Windows 10,当在同一屏幕上显示具有多种颜色的文本时,有一个更简单的选项来处理颜色。
虚拟终端序列 允许控制颜色、光标位置和属性以及屏幕缓冲区。
下面的宏简化了它们的重复使用。
::: Author T3RRY : Created 09/04/2021 : Version 1.0.1
:::
::: Purpose : Color and cursor position macro for windows 10 batch files
::: - Allows rapid display of colored output at specified screen position.
::: For more information, read the usage.
:::
::: Uses macro parameter and switch handling template.
::: - See : https://pastebin.com/gzL7AYpC
@Echo off
:# Windows Version control. Assigns flag true if system is windows 10.
Set "Win10="
Ver | Findstr /LIC:" 10." > nul && Set "Win10=true"
:# Test if virtual terminal codes enabled ; enable if false
:# removes win10 flag definition if version does not support Virtual Terminal sequences
If defined Win10 (
Reg Query HKCU\Console | %SystemRoot%\System32\findstr.exe /LIC:"VirtualTerminalLevel REG_DWORD 0x1" > nul || (
Reg Add HKCU\Console /f /v VirtualTerminalLevel /t REG_DWORD /d 1
) > Nul || Set "Win10="
)
If not defined Win10 (
Echo(Virtual terminal sequences not supported on your system
Exit /B 1
)
If "%~1" == "" (
Mode 160,30
Cls
)
(Set \n=^^^
%= \n macro newline variable. Do not modify =%)
:# assign virtual terminal control character 0x27 'escape' variable \E
For /F %%a in ( 'Echo prompt $E ^| cmd' )Do Set "\E=%%a"
:# Virtual Terminal 'VT' sequence Resource :
:# https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
::# usage: %$Cout% /Switch /Switch value
::# -----------------------------------------------------------------------------------------------------
::# Available Switches : Description:
::# -----------------------------------------------------------------------------------------------------
::# /Help : This help screen
::# /S String : String to be output
::# /S String{FS} : '/' must be substituted with {FS}
::# /C Integer : Declare output color using VT sequence
::# /C Integer,Integer : Chain mulitple VT color sequences
::# /C Integer;Integer : Combine multiple VT values into the one sequence
::# /Y Integer : Move cursor to Line Integer [ absolute ]
::# /X Integer : Move cursor to Column Integer [ absolute ]
::# /U Integer : Move cursor Up by Integer
::# /D Integer : Move cursor Down by Integer
::# /R Integer : Move cursor Right by Integer
::# /L Integer : Move cursor Left by Integer
::# /H - : Hide the cursor
::# /H + : Show the cursor
::# /Alt : Switch to alternate buffer [ main buffer is preserved ]
::# /Main : Return to main screen buffer [ alternate buffer is cleared ]
::# /K : Clears text to right of current cursor position
::# /Z Integer : Deletes Integer columns right of the cursor, shifting existing text left
::# /I Integer : Inserts whitespace into Integer columns right of Cursor, shifting text right
::# /N : Output a newline after other switches are executed.
::# -----------------------------------------------------------------------------------------------------
::#
:# Note on macro switch handling: Switches must not share a common prefix.
:# - IE:
:# - Invalid: D and DE [ switch assessment method would assign D as true if /DE used ]
:# - Valid : DA and DE
Set Switches= "help" "S" "C" "Y" "X" "U" "D" "R" "L" "H" "Alt" "Main" "K" "Z" "I" "N"
Set $Cout=For %%n in (1 2)Do if %%n==2 (%\n%
For %%G in ( %Switches% )Do set "Switch[%%~G]="%\n%
Set "leading.args=!args:*/=!"%\n%
For /F "Delims=" %%G in ("!leading.args!")Do Set "leading.args=!args:/%%G=!"%\n%
Set ^"args=!args:"=!" %\n%
Set "i.arg=0"%\n%
For %%G in (!leading.args!)Do (%\n%
Set /A "i.arg+=1"%\n%
Set "arg[!i.arg!]=%%~G"%\n%
)%\n%
For %%G in ( %Switches% )Do If not "!args:/%%~G=!" == "!args!" (%\n%
If not "!args:/%%~G: =!" == "!args!" Set "args=!args:/%%~G: =/%%~G !"%\n%
If not "!args:/%%~G =!" == "!args!" Set "switch[%%~G]=!Args:*/%%~G =!"%\n%
If not "!args:/%%~G:=!" == "!args!" Set "switch[%%~G]=!Args:*/%%~G:=!"%\n%
If not "!switch[%%~G]:*/=!" == "!switch[%%~G]!" (%\n%
Set "Trail[%%~G]=!switch[%%~G]:*/=!"%\n%
For %%v in ("!Trail[%%~G]!")Do (%\n%
Set "switch[%%~G]=!switch[%%~G]: /%%~v=!"%\n%
Set "switch[%%~G]=!switch[%%~G]:/%%~v=!"%\n%
)%\n%
Set "Trail[%%~G]="%\n%
If "!switch[%%~G]:~-1!" == " " Set "switch[%%~G]=!switch[%%~G]:~0,-1!"%\n%
If "!switch[%%~G]!" == "" Set "switch[%%~G]=true"%\n%
)%\n%
)%\n%
If "!Switch[help]!" == "true" (For /F "Tokens=1,2 Delims=#" %%Y in ('findstr /BLIC:"::#" "%~f0"')Do Echo(%%Z) ^& Timeout /T 1 /Nobreak ^> nul ^& Pause%\n%
If not "!Switch[C]!" == "" (Set "_Color_=%\E%[!Switch[C]:,=m%\E%[!m")Else Set "_Color_="%\n%
If not "!Switch[Y]!" == "" (Set "_Ypos_=%\E%[!Switch[Y]!d")Else Set "_Ypos_="%\n%
If not "!Switch[X]!" == "" (Set "_Xpos_=%\E%[!Switch[X]!G")Else Set "_Xpos_="%\n%
If not "!Switch[U]!" == "" (Set "_Yoffset_=%\E%[!Switch[U]!A")Else Set "_Yoffset_="%\n%
If not "!Switch[D]!" == "" Set "_Yoffset_=%\E%[!Switch[D]!B"%\n%
If not "!Switch[R]!" == "" (Set "_Xoffset_=%\E%[!Switch[R]!C")Else Set "_Xoffset_="%\n%
If not "!Switch[L]!" == "" Set "_Xoffset_=%\E%[!Switch[L]!D"%\n%
If "!Switch[H]!" == "-" Set "_Cursor_=%\E%[?25l"%\n%
If "!Switch[H]!" == "+" Set "_Cursor_=%\E%[?25h"%\n%
If "!Switch[Main]!" == "true" (Set "_Buffer_=%\E%[?1049l")Else Set "_Buffer_="%\n%
If "!Switch[Alt]!" == "true" Set "_Buffer_=%\E%[?1049h"%\n%
If not "!Switch[K]!" == "" (Set "_LineClear_=%\E%[K")Else Set "_LineClear_="%\n%
If not "!Switch[Z]!" == "" (Set "_Delete_=%\E%[!Switch[Z]!P")Else Set "_Delete_="%\n%
If not "!Switch[I]!" == "" (Set "_Insert_=%\E%[!Switch[I]!@")Else Set "_Insert_="%\n%
^< nul set /P "=!_Buffer_!!_Cursor_!!_Ypos_!!_YOffset_!!_Xpos_!!_XOffset_!!_Delete_!!_Insert_!!_Color_!!_LineClear_!!Switch[S]:{FS}=/!%\E%[0m"%\n%
If "!Switch[N]!" == "true" Echo(%\n%
) Else Set args=
:# enable macro
Setlocal EnableExtensions EnableDelayedExpansion
:# facilitate testing of the macro using parameters from the command line
if not "%~1" == "" (
%$Cout% %*
Exit /B !Errorlevel!
)
:# usage examples
%$Cout% /help
CLS
%$Cout% /C 31,4,48;2;0;120;180 /S hello world /Y 5 /X 10 /H -
timeout /t 1 > nul
%$Cout% /Alt /C 32 /Y 6 /X 16 /S Goodbye
timeout /t 1 > nul
%$Cout% /Main /L 6 /I 28 /C 7,1,90,48;2;150;0;170 /S " again my friends around the "
timeout /t 1 > nul
:# Animation examples
For /L %%i in (1 1 34)Do (
For /L %%. in (1 1 20)Do Call :_FalseLabel_Delay 2> nul
%$Cout% /X 10 /Z 1
)
For %%L in (G o o d b y e " ")Do (
For /L %%. in (1 1 40)Do Call :_FalseLabel_Delay 2> nul
%$Cout% /I 1 /C 31 /S "%%~L"
)
%$Cout% /H + /N
pause
Goto :eof