我正在下载 MingW,并注意到有一段时间安装程序会产生一个控制台窗口并下载文件。有趣的部分是它以某种方式在控制台窗口中创建下载栏并覆盖百分比数字。我想知道这是如何实现的?
注意:我几乎 100% 确定控制台没有写出'\n'
,实际上正在覆盖控制台。
我看到谷歌坏了。
http://ss64.org/viewtopic.php?id=1499
编码:
@echo off
:: *****************************************************************************
:: * Script Name: DetectMSI_v1.0.cmd *
:: * Author: Gustaaf von Pickartz. *
:: * Date Created: 19th July, 2012. *
:: * Internal Version: Version 1.0 *
:: * ------------------------------------------------------------------------- *
:: * Notice: *
:: * This program is provided as is and for fair use distribution. *
:: * Give credit where credit is due to the author in your own script. *
:: * ------------------------------------------------------------------------- *
:: * Purpose: *
:: * Detect current active MSIEXEC instances using a function for repeatable *
:: * calls within a script and display a progress bar... *
:: * ------------------------------------------------------------------------- *
:: * Updated by: ------- *
:: * Date: 19-07-2012 *
:: * Change1: "Initial script version." *
:: * ------------------------------------------------------------------------- *
:: *****************************************************************************
SETLOCAL ENABLEDELAYEDEXPANSION
SET PRG0=[* ]
SET PRG1=[#* ]
SET PRG2=[##* ]
SET PRG3=[###* ]
SET PRG4=[####* ]
SET PRG5=[#####* ]
SET PRG6=[######* ]
SET PRG7=[#######* ]
SET PRG8=[########* ]
SET PRG9=[#########*]
SET PRG10=[##########]
:: Please note there are special ASCII insertions in the SET BKSPC= declaration below. 80x backspace characters are inserted. ASCII Value 08=[BS]
:: Be sure to verify they are still there when you cut and paste from the web with your text editor (Notepad++ or PsPad). Insert them if missing, otherwise this script will not work...
SET BKSPC=
:Begin_Main
:: For the sake of the demonstration, start MSIEXEC minimized.
START /MIN MSIEXEC
:: Call our function.
CALL :Fnc_Msi
:: Waste a little time...
PING -n 7 localhost >nul
ECHO Exited the FIRST MSIEXEC detection function and progress bar demo.
ECHO.
ECHO.
ECHO A function can't be a function if it cannot be re-used right?
:: For the sake of the demonstration, start MSIEXEC minimized.
START /MIN MSIEXEC
:: Call our function.
CALL :Fnc_Msi
ECHO Exited the SECOND MSIEXEC detection function and progress bar demo.
echo.
echo.
pause
GOTO :EOF
:: -----------------------------------------------------------------------------
:: Below code is setup to run as a Function to be called anywhere in your script.
:: It will wait 10 loops at 7 sec intervals anytime it is called. Primarily written to detect active MSI installers.
:: The Menu counter and Progress bar is in the function for fun.
::
:: Usage: CALL :Fnc_Msi
2
:Fnc_Msi
CALL ECHO [.....] %%date%% %%time%% Testing for active MSI instances.
:catchit
IF NOT DEFINED CatchMSI SET CatchMSI=0
IF %CatchMSI% EQU 5 (
ECHO Waited 5 loops {15sec.} to detect MSI activities. Now resuming further MSI evaluation.
goto evalmsi
)
FOR /F "TOKENS=2* DELIMS=:" %%I IN ('TASKLIST /V /FI "IMAGENAME EQ MSIEXEC.EXE" /FO LIST 2^>NUL ^|FIND /I /V "N/A" ^|FIND /I "WINDOW TITLE:"') DO (SET MSI=%%I)
IF DEFINED MSI SET MSI_APP=%MSI:~1%
IF DEFINED MSI_APP goto msi_active
>NUL PING -n 3 localhost
SET /A CatchMSI+=1
goto :catchit
:evalmsi
IF NOT DEFINED MSI_APP (
ECHO [OKAY.] No active MSIEXEC installer running. It is safe to continue.
SET CatchMSI=
SET MSI_APP=
SET CNT=
SET COUNT=
SET TIC=
GOTO :EOF
)
:msi_active
SET CNT=0
ECHO [ALERT] Installer "%MSI_APP%" is active. Waiting maximum 10 counts.
:loop
IF NOT DEFINED COUNT SET COUNT=0
IF %COUNT% LEQ 9 (SET TIC=0%COUNT%) ELSE (SET TIC=%COUNT%)
IF %count% EQU 10 (
<NUL (SET/P Z=[%tic%/10] PROGRESS: !PRG%CNT%!)
:: Feel free to adjust the PING -n 3 value to say 30sec waits.
>NUL PING -n 3 localhost
TASKKILL /F /FI "WINDOWTITLE eq %MSI_APP%*" >>myprogress.log
<NUL SET/P Z=%BKSPC%
SET MSI_APP=
SET CatchMSI=
SET MSI_APP=
SET CNT=
SET COUNT=
SET TIC=
GOTO :EOF
)
<NUL (SET/P Z=[%tic%/10] PROGRESS: !PRG%CNT%!)
:: Feel free to adjust the PING -n 3 value to say 30sec waits.
>NUL PING -n 3 localhost
<NUL SET/P Z=%BKSPC%
:: Here we write to a log file and call tasklist.exe to do interval checks on the MSIEXEC status.
:: Demonstrated is that the progress bar is not affected when code is run in the loop.
:: Do keep in mind to "suppress to >nul 2>nul" any output that may disrupt the progress bar activty.
ECHO [%tic%/10] Waiting for "%MSI_APP%" to complete. >>myprogress.log
TASKLIST.EXE /V | FIND /I "%MSI_APP%">NUL 2>NUL
IF %ERRORLEVEL% EQU 1 (
>NUL PING -n 7 localhost
SET CatchMSI=
SET MSI_APP=
SET CNT=
SET COUNT=
SET TIC=
GOTO :EOF
)
SET /A CNT+=1
SET /A COUNT+=1
goto loop
GOTO :EOF
:: -----------------------------------------------------------------------------
显然归功于原作者。