Как иметь несколько цветов в командном файле Windows? - PullRequest
70 голосов
/ 02 декабря 2010

Мне было интересно, возможно ли иметь разноцветный текст в одной и той же строке в командном файле Windows, например, если он говорит:

echo hi world

Я хочу, чтобы "привет" был одним цветом, а "Мир »будет другого цвета.Может быть, я мог бы установить команду COLOR в качестве переменной:

set color1= color 2
set color9= color A

, а затем развернуть их обоих в одной строке вместе с

echo hi world

, но я не знаю, как бы я это сделалчто.

Ответы [ 13 ]

0 голосов
/ 21 января 2016

Если ваша консоль поддерживает цветовые коды ANSI (например, ConEmu , Clink или ANSICON ), вы можете сделать это:

SET    GRAY=%ESC%[0m
SET     RED=%ESC%[1;31m
SET   GREEN=%ESC%[1;32m
SET  ORANGE=%ESC%[0;33m
SET    BLUE=%ESC%[0;34m
SET MAGENTA=%ESC%[0;35m
SET    CYAN=%ESC%[1;36m
SET   WHITE=%ESC%[1;37m

где переменная ESC содержит символ ASCII 27.

Я нашел способ заполнить переменную ESC здесь: http://www.dostips.com/forum/viewtopic.php?p=6827#p6827 и, используя tasklist, можно проверить, какие библиотеки DLL загружены в процесс.

Следующий скрипт получает идентификатор процесса cmd.exe, в котором выполняется этот скрипт. Проверяет, есть ли у него dll, в который будет добавлена ​​поддержка ANSI, а затем устанавливает переменные цвета, чтобы они содержали escape-последовательности или были пустыми.в зависимости от того, поддерживается цвет или нет.

@echo off

call :INIT_COLORS

echo %RED%RED %GREEN%GREEN %ORANGE%ORANGE %BLUE%BLUE %MAGENTA%MAGENTA %CYAN%CYAN %WHITE%WHITE %GRAY%GRAY

:: pause if double clicked on instead of run from command line.
SET interactive=0
ECHO %CMDCMDLINE% | FINDSTR /L %COMSPEC% >NUL 2>&1
IF %ERRORLEVEL% == 0 SET interactive=1
@rem ECHO %CMDCMDLINE% %COMSPEC% %interactive%
IF "%interactive%"=="1" PAUSE
EXIT /B 0
Goto :EOF

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
: SUBROUTINES                                                          :
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

::::::::::::::::::::::::::::::::
:INIT_COLORS
::::::::::::::::::::::::::::::::

call :supportsANSI
if ERRORLEVEL 1 (
  SET GREEN=
  SET RED=
  SET GRAY=
  SET WHITE=
  SET ORANGE=
  SET CYAN=
) ELSE (

  :: If you can, insert ASCII CHAR 27 after equals and remove BL.String.CreateDEL_ESC routine
  set "ESC="
  :: use this if can't type ESC CHAR, it's more verbose, but you can copy and paste it
  call :BL.String.CreateDEL_ESC

  SET    GRAY=%ESC%[0m
  SET     RED=%ESC%[1;31m
  SET   GREEN=%ESC%[1;32m
  SET  ORANGE=%ESC%[0;33m
  SET    BLUE=%ESC%[0;34m
  SET MAGENTA=%ESC%[0;35m
  SET    CYAN=%ESC%[1;36m
  SET   WHITE=%ESC%[1;37m
)

exit /b

::::::::::::::::::::::::::::::::
:BL.String.CreateDEL_ESC
::::::::::::::::::::::::::::::::
:: http://www.dostips.com/forum/viewtopic.php?t=1733
::
:: Creates two variables with one character DEL=Ascii-08 and ESC=Ascii-27
:: DEL and ESC can be used  with and without DelayedExpansion
setlocal
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
  ENDLOCAL
  set "DEL=%%a"
  set "ESC=%%b"
  goto :EOF
)

::::::::::::::::::::::::::::::::
:supportsANSI
::::::::::::::::::::::::::::::::
:: returns ERRORLEVEL 0 - YES, 1 - NO
::
:: - Tests for ConEmu, ANSICON and Clink
:: - Returns 1 - NO support, when called via "CMD /D" (i.e. no autoruns / DLL injection)
::   on a system that would otherwise support ANSI.

if "%ConEmuANSI%" == "ON" exit /b 0

call :getPID PID

setlocal

for /f usebackq^ delims^=^"^ tokens^=^* %%a in (`tasklist /fi "PID eq %PID%" /m /fo CSV`) do set "MODULES=%%a"

set MODULES=%MODULES:"=%
set NON_ANSI_MODULES=%MODULES%

:: strip out ANSI dlls from module list:
:: ANSICON adds ANSI64.dll or ANSI32.dll
set "NON_ANSI_MODULES=%NON_ANSI_MODULES:ANSI=%"
:: ConEmu attaches ConEmuHk but ConEmu also sets ConEmuANSI Environment VAR
:: so we've already checked for that above and returned early.
@rem set "NON_ANSI_MODULES=%NON_ANSI_MODULES:ConEmuHk=%"
:: Clink supports ANSI https://github.com/mridgers/clink/issues/54
set "NON_ANSI_MODULES=%NON_ANSI_MODULES:clink_dll=%"

if "%MODULES%" == "%NON_ANSI_MODULES%" endlocal & exit /b 1
endlocal

exit /b 0

::::::::::::::::::::::::::::::::
:getPID  [RtnVar]
::::::::::::::::::::::::::::::::
:: REQUIREMENTS:
::
:: Determine the Process ID of the currently executing script,
:: but in a way that is multiple execution safe especially when the script can be executing multiple times
::   - at the exact same time in the same millisecond,
::   - by multiple users,
::   - in multiple window sessions (RDP),
::   - by privileged and non-privileged (e.g. Administrator) accounts,
::   - interactively or in the background.
::   - work when the cmd.exe window cannot appear
::     e.g. running from TaskScheduler as LOCAL SERVICE or using the "Run whether user is logged on or not" setting
::
:: https://social.msdn.microsoft.com/Forums/vstudio/en-US/270f0842-963d-4ed9-b27d-27957628004c/what-is-the-pid-of-the-current-cmdexe?forum=msbuild
::
:: http://serverfault.com/a/654029/306
::
:: Store the Process ID (PID) of the currently running script in environment variable RtnVar.
:: If called without any argument, then simply write the PID to stdout.
::
::
setlocal disableDelayedExpansion
:getLock
set "lock=%temp%\%~nx0.%time::=.%.lock"
set "uid=%lock:\=:b%"
set "uid=%uid:,=:c%"
set "uid=%uid:'=:q%"
set "uid=%uid:_=:u%"
setlocal enableDelayedExpansion
set "uid=!uid:%%=:p!"
endlocal & set "uid=%uid%"
2>nul ( 9>"%lock%" (
  for /f "skip=1" %%A in (
    'wmic process where "name='cmd.exe' and CommandLine like '%%<%uid%>%%'" get ParentProcessID'
  ) do for %%B in (%%A) do set "PID=%%B"
  (call )
))||goto :getLock
del "%lock%" 2>nul
endlocal & if "%~1" equ "" (echo(%PID%) else set "%~1=%PID%"
exit /b
0 голосов
/ 18 августа 2012

Все описанные альтернативы используют любые временные файлы.Это плохо, не всегда возможно использовать временные файлы.Этот скрипт ниже не использует временный файл и может писать текст на любой позиции экрана.Лучший сценарий для этой цели - this

0 голосов
/ 03 декабря 2010

Если вы не используете более старую операционную систему, я считаю, что это невозможно сделать с помощью доступных вам команд.

Однако еще не все потеряно, посмотрите на эту страницу:

http://www.mailsend -online.com / блог / установка текстовый цвет-в-партии-file.html

Это, вероятно, даст вам то, что вам нужно, но недостатком является то, что вам нужно добавить утилиты на этой странице.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...