I present you with 3 subroutines for getting coloured text and/or background in a batch file, without any special EXE. They all use the colour codes from the command «color»
These subroutines weren't created by me, I just found them on the net, and are provided "as is", I take no responsability id your computer explodes, or starts to call you Dave in a monotone voice.
They all have it's advantages and disadvantages, weakness and strenghts, you just choose accordingly with your needs. I hope you enjoy them.
Let's start with the 1st:
("::" is the same as "REM")
ADVANTAGES: it prints almost any char, easy to implement in a batch
DISADVANTAGES: it's outdated, it doesn't work from W7 on (works great on XP though), doesn't need external EXEs installed *BUT* it creates it's own .COM for each colour combination and then executes it. The more colors you use, the more .com files it creates (in your system %temp% folder)
The .COM are created with the "debug" command that is present in XP, and which W7 doesn't have anymore (hence it doesn't work)
The code is written in assembly and then compiled by debug (assembly in a batch.. awsome I know) and finally executed to show the colour
To try it you just have to call the subroutine with the colour code as the 1st argument and the text as the 2nd.
For instance you write in a batch «Hello there» in red text and white background, you do this:
CALL :SEVERAL_COLORS FC Hello there
...and that's it
****************** THE 1ST SUBROUTINE STARTS HERE:
::_________________________________THIS IS THE SUBROUTINE_____________________________
:SEVERAL_COLORS
REM ·····------=======############### ################=======------·····
REM ·····------=======############# #############=======------·····
REM ·····------=======######### OUTDATED! IT DOESN'T WORK ON WINDOWS 7 #########=======------·····
REM ········-------====#### 'debug' ONLY PRESENT AT XP ####====-------········
REM @echo off
:echo col txt -- echoes text in a specific color
:: -- col [in] - color code, append a DOT to omit line break, call 'color /?' for color codes
:: -- txt [in] - text output
:$created 20060101 :$changed 20080219 :$categories Echo,Color
:$source
http://www.dostips.com
SETLOCAL
for /f "tokens=1,*" %%a in ("%*") do (
set col=%%a
set txt=%%~b
)
set cr=Y
if "%col:~-1%"=="." (
set cr=N
set col=%col:~0,-1%
)
rem call:getColorCode "%col%" col
set "com=%temp%\color%col%.com"
if not exist "%com%" (
echo.N %COM%
echo.A 100
echo.MOV BL,%col%
echo.MOV BH,0
echo.MOV SI,0082
echo.MOV AL,[SI]
echo.MOV CX,1
echo.MOV AH,09
echo.INT 10
echo.MOV AH,3
echo.INT 10
echo.INC DL
echo.MOV AH,2
echo.INT 10
echo.INC SI
echo.MOV AL,[SI]
echo.CMP AL,0D
echo.JNZ 109
echo.RET
echo.
echo.r cx
echo.22
echo.w
echo.q
)|debug>NUL
"%com%" %txt%
if "%cr%"=="Y" echo.
EXIT /b
GOTO:EOF
::_____________________________IT ENDS HERE___________________________
----
-----------
----------------
-------------------> NOW FOR THE 2ND SUBROUTINE:
This method uses the only (or one of the only) command present in almost all Microsoft OSes that can print colours: FINDSTR, and then uses some voodoo and batch kung-fu to harness that colour output to our needs :)
First you need a «setlocal EnableDelayedExpansion» before using it; next before you call the main colour subroutine, you need to initialize another subroutine: «InitColourPrint», that will create a 1 byte file called 'x' in your temp folder (it's necessary). This subroutine only needs to be called once in the Batch.
Then you can finally print some colours by calling the main subroutine each time you want some colour goodness :)
Example:
@echo off
setlocal EnableDelayedExpansion
CALL :InitColourPrint
:: this will print in light blue/dark background a sentence
call :COR_AVANC 0b "this 2nd subroutine is awsome!"
echo.
:: ...now in blue text, dark blue background
call :COR_AVANC 0b "it sure is :)"
At the end of the batch you will undo the setlocal by putting «endlocal»; and if you want to delete the 'x' file, apply this at the end of the batch: del "%temp%\x"
ADVANTAGES: works in XP *AND* W7
DISADVANTAGES: slightly more complex to implement.
It won't make carriage returns, you'll have to write "echo." for those
If the coloured string comes too close to the end of the line (4 or 5 chars left) it writes some '.' and '/' after the string. However if the string just fills the whole line it doesn't write them anymore, and if the string lenght exceeds the line size it'll just write the rest on the next line.
The string *CAN'T* begin with a / or \, otherwise it'll give an error. It *can* end with / or \, *BUT* it can't have any other char after it (besides the ending quotation mark)
EX: all of these will give errors:
call :COR_AVANC 0b "\Damn, an error"
call :COR_AVANC 0b "/ oh no another one"
call :COR_AVANC 0b "and another/a"
call :COR_AVANC 0b "...yep, one more error\bbb"
************ And now for the "InitColourPrint" and "COR_AVANC" subroutines:
:: =====================================
:InitColourPrint
:: @@@@ INITIALIZE THE MAIN ROUTINE "COR_AVANC"
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do set "DEL=%%a"
:: Prepare a file "X" with only one dot
REM <NUL >"X" set /p ".=."
<NUL >"%temp%\x" set /p ".=."
exit /b
:: =====================================
::############################################--- IT STARTS HERE ---#################################
:: @@@@@@@@@@@@@@@@@@ IMPRIME STRINGS COM VÁRIAS CORES @@@@@@@@@@@@@@@@@@@@
:: @@@@@@ mais limitado c/ certas sequências de caracteres @@@@@@@
:: @@@@@ **e não permite mudanças de linha internas** @@@@@
:: @@@@@@@@@@@@ @@@@@@@@@@@@
:: ººººººººººººººººººººººººººº
:: »»»»»» NECESSITA DE UM 'setlocal EnableDelayedExpansion' LOGO A SEGUIR AO @ECHO OFF NO COMEÇO DO .BAT
:: »»»»»» ...E DE CHAMAR A SUB-ROTINA "InitColourPrint" **ANTES** DE CHAMAR QUALQUER COR
:: »»»»»» (SÓ PRECISA SER FEITA 1 VEZ NO .BAT)
:: »»»»»» EXEMPLOS:
:: call :COR_AVANC 1a "a"
:: call :COR_AVANC 1b "b lalala"
:: call :COR_AVANC 1c "^!<>&| %%%%"*?:\/"
::::::::::::::::: COMEÇA AQUI ::::::::::::::::::::::
:COR_AVANC
set "param=^%~2" !
set "param=!param:"=\"!"
pushd "%temp%"
findstr /P /A:%1 "." "!param!\..\X" nul
<NUL set /p ".=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%"
popd
exit /b
::##################################################################################
-----
-----------
----------------
-------------------> FINALLY, THE 3RD SUBROUTINE:
ADVANTAGES: No limits of chars, and carriage returns are now an option. Also no more limitations with the '\' and '/' like the previous one.
DISADVANTAGES: still it will only print what you see on your keyboard plus the accentuated chars, it will *NOT* print those fancy extended ASCII symbols (those in the right half of this table:
http://www.asciitable.com/index/extend.gif). Only the 1st outdated subroutine can print those.
If the coloured string comes too close to the right border (3 or 4 chars left) it writes some '.' and '/' after the string. However it it just fills the whole line it doesn't write them, and if the string lenght exceeds the line size it'll just write the rest on the next line.
It works the same way the previous one worked, but this time the subroutines are "InitColourPrint_2" and "COR_AVANC_2"
Ex:
@echo off
setlocal EnableDelayedExpansion
CALL :InitColourPrint_2
call :COR_AVANC_2 E1 "this one is even better"
echo.
call :COR_AVANC_2 C7 " indeed, it even has carriage included" /n
...the "/n" is the optional carriage return, like if I added an "echo." after it.
It can also print e.g. the variable MY_TEXT:
CALL :COR_AVANC_2 0D My_TEXT
...note that in this case the variable doesn't need the '%' around it as it's usual with batches, neither uses quoting marks (") around the text anymore.
***********************At last, the subroutines for the 3rd method are:
:: ============================
:InitColourPrint_2
:: @@@@ INITIALIZE THE MAIN ROUTINE "COR_AVANC_2"
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do set "DEL=%%a"
<NUL >"%temp%\x" set /p "=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%.%DEL%"
exit /b
:: ============================
::#################################### BEGINNING ##############################################
:: #### escolher 'COR_AVANC_2' ou 'COR_AVANC_2VAR' ####
:: *********** ***********
:: @@@@@@@@@@@ @@@@@@@@@@@
:: @@@@@@@@@@@@@@@@@@@@@@@@ IMPRIME STRINGS COM VÁRIAS CORES @@@@@@@@@@@@@@@@@@@@@@@@@@
:: ········@@@@@@@@@@ sem limites :) @@@@@@@@@@@········
:: @@@@@@@ @@@@@@@
:: @@@@@@@@@@@@@@@@@@@@
:: »»»»»» NECESSITA DE UM 'setlocal' LOGO A SEGUIR AO @ECHO OFF NO COMEÇO DO .BAT
:: »»»»»» ...E DE UM 'call :initColourPrint_2' **ANTES** DE CHAMAR QUALQUER COR
:: »»»»»» (SÓ PRECISA SER FEITA 1 VEZ NO .BAT)
:: »»»»»» EXEMPLOS:
:: ######## Tanto pode imprimir texto directo (acrescentar /n para mudar de linha)...
:: call :COR_AVANC_2 0a "bláblá"
:: call :COR_AVANC_2 2f "q:" /n
:: ######## ...como através de uma variável:
:: set "txt=^" & call :COR_AVANC_2VAR 0c txt
:: set complex="c:\hello world!/.\..\\a//^<%%>&|!" /^<%%^>^&^|!\
:: set complex="c:\hello world!"
:: call :COR_AVANC_2VAR 74 complex /n
:: »»»»» POR FIM, PARA LIMPAR AS VARIÁVEIS FAZER UM 'call :cleanupColorPrint'
::::::::::::::::::::::::: COMEÇA AQUI ::::::::::::::::::::::::::::::::::
:COR_AVANC_2 Color Str [/n]
setlocal
set "str=%~2"
call :COR_AVANC_2VAR %1 str %3
exit /b
:COR_AVANC_2VAR Color StrVar [/n]
if not defined %~2 exit /b
setlocal enableDelayedExpansion
set "str=a%DEL%!%~2:\=a%DEL%\..\%DEL%%DEL%%DEL%!"
set "str=!str:/=a%DEL%/..\%DEL%%DEL%%DEL%!"
set "str=!str:"=\"!"
pushd "%temp%"
findstr /p /A:%1 "." "!str!\..\x" nul
if /i "%~3"=="/n" echo(
exit /b
::######################################## END #################################################