Function 如何使用命令行参数控制打印多色文本的批处理程序?
我有一个批处理脚本,可以在命令提示符的同一行上显示两种或更多颜色的文本。(下文) 或 或者一些简单的东西,我可以提供颜色(最好是字符串而不是颜色代码)和文本(带或不带引号)Function 如何使用命令行参数控制打印多色文本的批处理程序?,function,colors,batch-file,command,Function,Colors,Batch File,Command,我有一个批处理脚本,可以在命令提示符的同一行上显示两种或更多颜色的文本。(下文) 或 或者一些简单的东西,我可以提供颜色(最好是字符串而不是颜色代码)和文本(带或不带引号) 我不知道这对您是否有用,但可以保存脚本的这一部分: echo off <nul set /p ".=%DEL%" > "%~2" findstr /v /a:%1 /R "^$" "%~2" nul del "%~2" > nul 2>&1 goto :eof 将其更改为: call Co
我不知道这对您是否有用,但可以保存脚本的这一部分:
echo off
<nul set /p ".=%DEL%" > "%~2"
findstr /v /a:%1 /R "^$" "%~2" nul
del "%~2" > nul 2>&1
goto :eof
将其更改为:
call ColorText
(省略冒号)
并将该脚本另存为“C:\windows\system32”中的colors.bat。然后打开命令提示符并键入“colors”。这就是我希望它发挥作用的方式;没有其他命令、设置脚本、文件路径;仅仅是一个简单的一两个单词的函数,所有这些乱七八糟的代码都在后台进行(看不见)。但是,上述想法仍然不允许我从命令提示符指定自己的文本或颜色。。。。有什么想法吗?编辑:拿3个 创建文件夹
C:\Utilities
。将此文件夹添加到Path环境变量中,以便Windows在其中查找其他脚本和命令
不要把接下来的步骤搞砸了强>
;C:\Utilities
,包括分号。不要删除任何其他文本再次放松呼吸。
:ColorText
标签后面的脚本,并将其保存到C:\Utilities\cecho.bat
。将@
放在echo off
前面,以防止脚本执行期间出现echo off
CEcho.bat
@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"
)
<Nul Set /p ".=%DEL%" > "%~2"
FindStr /v /a:%1 /R "^$" "%~2" Nul
Del "%~2" > Nul 2>&1
EndLocal
编辑:回应您的评论:
通过插入以下行并替换FindStr
行,可以使用颜色词:
Set Color=%1
If %1==blue Set Color=9
If %1==red Set Color=C
etc...
FindStr /v /a:%Color% /R "^$" "%~2" Nul
现在您可以键入:
CEcho red "apple"
CEcho blue "water"
CEcho A "grass"
CEcho 6 "dirt"
CEcho 26 "tree"
请注意,颜色词区分大小写。您可以使用批处理参数%1、%2、%n作为颜色和内容的参数
cecho 0a“你好,世界!”
如果要使用颜色名称,必须将它们转换为相应的数字
cecho blue“你好”
自Windows XP以来,通过使用PowerShell作为通过命名管道链接到控制台输出的子进程,使用cmd batch高效地替代color。FindStr也可以实现这一点,但PowerShell提供了更多选项,而且似乎速度更快
将PowerShell保持为子流程(使用管道进行通信)的主要兴趣在于,对于要显示的每一行,显示速度要比启动PowerShell或FindStr快得多
其他优点:
- 不需要临时文件
- 通过管道的回音可以显示完整的ASCII表格,而不必费心转义
- 可以很好地处理fd重定向。例如,仅为stderr着色,或重定向到文件/其他进程
::
:: 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
@ECHO关闭
setLocalEnableExtensions
如果错误级别为1(
回声扩展不适用
退出/B 1
)
::
SETLOCAL ENABLEDELAYEDEXPANSION
如果错误级别为1(
回声膨胀不适用
退出/B 1
)
调用:启动PowerShellSubProcess
如果不是错误级别0退出/B 1
呼叫:青色“我用青色写这个”
呼叫:蓝色“我用蓝色写这个”
呼叫:绿色“这是绿色的”
呼叫:红色-非WLINE“和混合红色”
呼叫:黄色“带黄色”
CALL:Green“并且不需要为()&|;、%“^等问题而烦恼…”
退出/b0
:颜色
ECHO-foregroundcolor%*>\\.\pipe\PowerShellCon\!LOCALV_-PID!
回声[|设置/P=>NUL
后藤:EOF
:蓝色
ECHO-foregroundcolor Blue%*>\\.\pipe\PowerShellCon\\!LOCALV\\ PID!
回声[|设置/P=>NUL
后藤:EOF
:绿色
ECHO-foregroundcolor绿色%*>\\.\pipe\PowerShellCon\\!LOCALV\\ PID!
回声[|设置/P=>NUL
后藤:EOF
:红色
ECHO-foregroundcolor红色%*>\\.\pipe\PowerShellCon\\!LOCALV\\ PID!
回声[|设置/P=>NUL
后藤:EOF
:黄色
ECHO-foregroundcolor Yellow%*>\\.\pipe\PowerShellCon\\!LOCALV\\ PID!
回声[|设置/P=>NUL
后藤:EOF
::
::在后台启动链接到控制台的PowerShell子进程,然后
::正在通过命名管道PowerShellCon_u%PID%进行搜索
::
::参数:
::[PID]:控制台进程ID用作命名管道的标识符,默认情况下为启动器PID。
:[超时]:子进程的最大生存时间(秒),默认为300。如果为-1,则子进程
::进程%PID%仍处于活动状态时,将不会终止。
::返回:
::0如果子PowerShell已成功启动且命名管道可用。
::1如果失败。
::2如果我们不能得到PID。
::3如果PowerShell不存在或不工作。
::
:LaunchPowerShellSubProcess
设置本地v_PID=
设置LOCALV_TIMEOUT=300
如果不是“%~1”==”,则设置LOCALV_PID=%~1
如果不是“%~2”==”,则设置本地V_超时=%~2
powershell-命令“$\u2>&1>NUL
如果不是“!ERRORLEVEL!”==“0”退出/B 3
如果“!LOCALV_PID!”==”(
对于('powershell-命令“$parentId=(Get-WmiObject Win32_进程-Filter ProcessId=$PID)。ParentProcessId;写入主机(Get-WmiObject Win32_进程-Filter ProcessId=$parentId)。ParentProcessId;”)执行以下操作(
设置LOCALV_PID=%%P
)
)
如果“!LOCALV_PID!”==“退出/B 2
启动/B powershell-命令“$cmdPID=$PID;启动作业-ArgumentList$cmdPID-ScriptBlock{$ProcessActive=$true;$timeout=!LOCALV_timeout!;而(!LOCALV_timeout!-eq-1-或$timeout-gt 0)-和$ProcessActive){启动睡眠-s1;$timeout-=1;$ProcessActive=Get-
CEcho color "text"
Set Color=%1
If %1==blue Set Color=9
If %1==red Set Color=C
etc...
FindStr /v /a:%Color% /R "^$" "%~2" Nul
CEcho red "apple"
CEcho blue "water"
CEcho A "grass"
CEcho 6 "dirt"
CEcho 26 "tree"
@echo off
call :ColorText %1 "%~2"
...
@echo off
if "%1"=="red" set color=0c
if "%1"=="blue" set color=0b
if ...
call :ColorText %color% "%~2"
::
:: 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