どのようにコードスピナーのための待合プロセスバッチファイルとは何ですか?

StackOverflow https://stackoverflow.com/questions/368041

  •  21-08-2019
  •  | 
  •  

質問

良野の落合にて設立されましたのユーザにピると思うので、それを何とか背景がいなかったこの作品にbatchfile.

なら仕方ないか?

役に立ちましたか?

解決

これは実際に純粋なネイティブコマンドで非常に簡単に行うことができます、あなたはちょうどそれらのより多くのトリッキーを使用する方法を知っている必要があります。 VBScriptのような外部ツールや画面をクリアするような厄介な副作用のない使用する必要はありません。

あなたが探しているのは、改行なしで行を出力bashの「echo -n」コマンドと同等です。

:XPバッチでは、これは次のように空の入力と(プロンプトと応答をユーザに尋ねる)「set /p」を使用することによって達成されます
<nul (set /p junk=Hello)
echo. again.

意志出力文字列「こんにちは再び。」介在しない改行でます。

はトリック(とCTRL-H、バックスペース文字の使用が開始され、次のテストスクリプト(次々に)20秒のタイムアウトと10秒のサブタスクおよび15-に見ることができます10秒のタイムアウトを有する第2サブタスク

ペイロードスクリプトが実走行スクリプトによって作成され、その唯一の要件は、モニタ機能がそれを検出することができますように、それは、それが終了したときにフラグファイルを削除しないために持って仕事をするということです。

|

^、このスクリプトでは^ Hの文字列は、実際にCTRL-Hの文字であることに留意してください二つの別々の文字がパイプ記号をエスケープするために使用されます。

@echo off

:: Localise environment.
setlocal enableextensions enabledelayedexpansion

:: Specify directories. Your current working directory is used
:: to create temporary files tmp_*.*
set wkdir=%~dp0%
set wkdir=%wkdir:~0,-1%

:: First pass, 10-second task with 20-second timeout.
del "%wkdir%\tmp_*.*" 2>nul
echo >>"%wkdir%\tmp_payload.cmd" ping 127.0.0.1 -n 11 ^>nul
echo >>"%wkdir%\tmp_payload.cmd" del "%wkdir%\tmp_payload.flg"
call :monitor "%wkdir%\tmp_payload.cmd" "%wkdir%\tmp_payload.flg" 20

:: Second pass, 15-second task with 10-second timeout.
del "%wkdir%\tmp_*.*" 2>nul:
echo >>"%wkdir%\tmp_payload.cmd" ping 127.0.0.1 -n 16 ^>nul
echo >>"%wkdir%\tmp_payload.cmd" del "%wkdir%\tmp_payload.flg"
call :monitor "%wkdir%\tmp_payload.cmd" "%wkdir%\tmp_payload.flg" 10

goto :final

:monitor
    :: Create flag file and start the payload minimized.
    echo >>%2 dummy
    start /min cmd.exe /c "%1"

    :: Start monitoring.
    ::    i is the indicator (0=|,1=/,2=-,3=\).
    ::    m is the number of seconds left before timeout.
    set i=0
    set m=%3
    <nul (set /p z=Waiting for child to finish: ^|)

    :: Loop here awaiting completion.
    :loop
        :: Wait one second.
        ping 127.0.0.1 -n 2 >nul

        :: Update counters and output progress indicator.
        set /a "i = i + 1"
        set /a "m = m - 1"
        if %i% equ 4 set i=0
        if %i% equ 0 <nul (set /p z=^H^|)
        if %i% equ 1 <nul (set /p z=^H/)
        if %i% equ 2 <nul (set /p z=^H-)
        if %i% equ 3 <nul (set /p z=^H\)

        :: End conditions, complete or timeout.
        if not exist %2 (
            echo.
            echo.   Complete.
            goto :final
        )
        if %m% leq 0 (
            echo.
            echo.   *** ERROR: Timed-out waiting for child.
            goto :final
        )
        goto :loop
:final
endlocal

他のヒント

これを試してください:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
CALL :BACKSPACE $BS
SET /A FULL_COUNT=60
SET /A MAX_COUNT=160
SET /A Spin_Delay=50
SET "_MSG=Process running..."
SET /A CTR=0
SET /A TCT=0
IF NOT [%1]==[] SET _MSG=%~1
IF NOT [%2]==[] SET /A FULL_COUNT=%2
IF NOT [%3]==[] SET /A SPIN_DELAY=%3
IF %FULL_COUNT% GTR %MAX_COUNT% SET FULL_COUNT=%MAX_COUNT%
(SET/P=%_MSG%*)<nul
FOR /L %%A IN (1,1,%FULL_COUNT%) DO (
  CALL :DELAY %SPIN_DELAY%
  IF !CTR! EQU 0 (set/p=%$BS%³)<nul
  IF !CTR! EQU 1 (set/p=%$BS%/)<nul
  IF !CTR! EQU 2 (set/p=%$BS%Ä)<nul
  IF !CTR! EQU 3 (set/p=%$BS%\)<nul
  SET /A CTR=%%A %% 4
)
(SET/P=%$BS%*)<nul
ENDLOCAL & EXIT /B %CTR%

:BackSpace
setlocal
for /f %%a in ('"prompt $H$S &echo on &for %%b in (1) do rem"') do set "Bs=%%a"
endlocal&call set %~1=%BS%&exit /b 0

:Delay msec
setlocal enableextensions
set/a correct=0
set/a msecs=%1+5
if /i %msecs% leq 20 set /a correct-=2
set time1=%time: =%
set/a tsecs=%1/1000 2>nul
set/a msecs=(%msecs% %% 1000)/10
for /f "tokens=1-4 delims=:." %%a in ("%time1%") do (
  set hour1=%%a&set min1=%%b&set sec1=%%c&set "mil1=%%d"
)
if /i %hour1:~0,1% equ 0 if /i "%hour1:~1%" neq "" set hour1=%hour1:~1% 
if /i %min1:~0,1% equ 0 set min1=%min1:~1% 
if /i %sec1:~0,1% equ 0 set sec1=%sec1:~1%
if /i %mil1:~0,1% equ 0 set mil1=%mil1:~1% 
set/a sec1+=(%hour1%*3600)+(%min1%*60)
set/a msecs+=%mil1%
set/a tsecs+=(%sec1%+%msecs%/100)
set/a msecs=%msecs% %% 100
::    check for midnight crossing
if /i %tsecs% geq 86400 set /a tsecs-=86400
set/a hour2=%tsecs% / 3600
set/a min2=(%tsecs%-(%hour2%*3600)) / 60
set/a sec2=(%tsecs%-(%hour2%*3600)) %% 60
set/a err=%msecs%
if /i %msecs% neq 0 set /a msecs+=%correct%
if /i 1%msecs% lss 20 set msecs=0%msecs%
if /i 1%min2% lss 20 set min2=0%min2%
if /i 1%sec2% lss 20 set sec2=0%sec2%
set time2=%hour2%:%min2%:%sec2%.%msecs%
:wait
  set timen=%time: =%
  if /i %timen% geq %time2% goto :end
goto :wait
:end
for /f "tokens=2 delims=." %%a in ("%timen%") do set num=%%a
if /i %num:~0,1% equ 0 set num=%num:~1%
set/a err=(%num%-%err%)*10
endlocal&exit /b %err%

大きな画面を清算します:

@ECHO OFF

SETLOCAL ENABLEDELAYEDEXPANSION
SET COUNT=1

START CALC

:BEGIN
  CLS
  IF !COUNT! EQU 1 ECHO \
  IF !COUNT! EQU 2 ECHO -
  IF !COUNT! EQU 3 ECHO /
  IF !COUNT! EQU 4 ECHO -
  IF !COUNT! EQU 4 (
    SET COUNT=1
  ) ELSE (
    SET /A COUNT+=1
  )
  PSLIST CALC >nul 2>&1
  IF %ERRORLEVEL% EQU 1 GOTO END
GOTO BEGIN

:END

編集:このサンプルが始ま計算して表示"スピナー"ましくは、こちらをご覧ください。電卓.使ってい pslist チェックの存在CALC.EXE.の >nul2>&1 リダイレクトSTDOUTおよびSTDERRにnulいものからPSLISTが表示されます。

私はあなたが実行しているいくつかの操作が時間を割いているので、あなたがスピナーをしたいあなたの質問を理解し、あなたは、何かが起こっているユーザーに表示したい場合は、右?

その場合は、私の知る限り、その可能性はないネイティブコマンドを持ちます。

(あなたは長い時間がかかる操作を実行しながら、スピナーを示したプログラムを持っていた場合、それは可能かもしれません)

そして、それは、ANSIエスケープシーケンスをサポートしていませんエコーのように見えます(あなたがANSI.SYSロードしていなければならなかった昔のを、それがまだ存在するかどうかわからない)ので、あなたはカーソルを制御するために、ANSIを使用することはできませんます。

スピナーの CAN のバッチスクリプトで行うことが、あなただけのいくつかの変数が必要になります:

@echo off

:spinner
set mSpinner=%mSpinner%.
if %mSpinner%'==..............................' set mSpinner=.
cls
echo %mSpinner%

rem Check if the process has finished via WMIC and/or tasklist.

goto spinner


:exit

BAT自体は/終了を実行しているプロセスを検出するために。あなたは行うことができWMIコマンドラインインターフェイスnoreferrer">

あなたがWindowsのバッチスクリプト内で意味場合は、

、あなたはネイティブにそれを行うことはできません。コンソールに印刷するために使用されるエコー文は常に改行を出力します、そしてあなたは、カーソルを移動することはできません。

これは、ハッキングのビットだが、あなたは、VBScriptおよびバッチスクリプトの組み合わせでこれを行うことができます。

このVBScriptのは、それが引数だ、バックスペースを出力します。

WScript.StdOut.Write(chr(8) & WScript.Arguments(0))

そして、あなたのバッチスクリプトからこのスクリプトを呼び出して、ファイル、vbsEcho.vbsでこれを入れてください。以下のバッチスクリプトを使用すると、CTRL-Cを押すまでスピナーを表示し続けます。

@echo off

:LOOP
cscript //nologo vbsEcho.vbs "\"
cscript //nologo vbsEcho.vbs "|"
cscript //nologo vbsEcho.vbs "/"
cscript //nologo vbsEcho.vbs "-"
goto :LOOP

EDIT:aphoriaの回答からいくつかのアイデアを使用して、このスクリプトは、Windowsの電卓を起動し、電卓が閉じるまで、スピナーが表示されます。

@ECHO OFF

SETLOCAL ENABLEDELAYEDEXPANSION
SET COUNT=1

START CALC

cscript //nologo vbsEcho.vbs "Calculating: \"
:LOOP
IF !COUNT! EQU 1 cscript //nologo vbsEcho.vbs "|"
IF !COUNT! EQU 2 cscript //nologo vbsEcho.vbs "/"
IF !COUNT! EQU 3 cscript //nologo vbsEcho.vbs "-"
IF !COUNT! EQU 4 (
    cscript //nologo vbsEcho.vbs "\"
    set COUNT=1
) else (
    set /a COUNT+=1
)

pslist CALC >nul 2>&1
if %ERRORLEVEL% EQU 1 goto :end

goto :LOOP

:END
cscript //nologo vbsEcho.vbs ". Done."

あなたが与えられたセットから別の文字を印字カウンタを使用することができます(のように「\ | / - 」)とあなたは「カウンタ・モジュロ4」等に応じて文字を変更します。とにかく、あなたはより正確には少し難しいです、あなたがで作業しているどの言語で言うことはありません。

編集:今、私たちは、あなたがプレーしているその環境の中で知っていることを、私はBAT / CMD言語は、タスクまでは本当にないことを言うと思います...私はRubyは私のお気に入りであること、任意のスクリプト言語をお勧めしますます。

私は、最も簡単な方法は、タイトル更新することで見つける - 。あなたはCLSにすべての時間を行う必要はありませんそのように

のping -nの二行の理由は、それが2秒の単一のpingに対して、各第二の二重のpingを実行するためのpingのための迅速であるということです。

また、知らない人のために、::はコメントはパーサの初めに(私はこれは正しい言葉だと思います)の代わりに、最後に無視されることを除いて、REMと同じです。簡単に言えば、その行は無視されます。

:: begin spin.cmd
@echo off
setlocal

set COUNT=0
set MAXCOUNT=10
set SECONDS=1

:LOOP
title "\"
call :WAIT
title "|"
call :WAIT
title "/"
call :WAIT
title "-"
if /i "%COUNT%" equ "%MAXCOUNT%" goto :EXIT
set /a count+=1
echo %COUNT%
goto :LOOP

:WAIT
ping -n %SECONDS% 127.0.0.1 > nul
ping -n %SECONDS% 127.0.0.1 > nul
goto :EOF

:EXIT
title FIN!
endlocal
:: end spin.cmd

paxdiablosは、驚くべき答えを持っていますが、ペイロードファイルにあなたのコマンドをエコーすることは迷惑です。これは読みにくいとデバッグが困難です。私は彼のコードを取り、それを私自身の使用のためのビットを変更します:

@echo off

:: Localise environment.
setlocal enableextensions enabledelayedexpansion

set wkdir=%~dp0%
set wkdir=%wkdir:~0,-1%
set done_flag="%wkdir%\tmp_payload.flg"
set timeout=7


:controller

IF (%1)==() (
    call :monitor step1 "Getting stuff from SourceSafe: "
    call :monitor step2 "Compiling some PHP stuff: "
    call :monitor step3 "Finishing up the rest: "
) ELSE ( goto %1 )

goto final


:step1
::ping for 5 seconds
    ping 127.0.0.1 -n 6 >nul
    del "%wkdir%\tmp_payload.flg"
goto final

:step2
::ping for 10 seconds
    ping 127.0.0.1 -n 11 >nul
    del "%wkdir%\tmp_payload.flg"
goto final

:step3
::ping for 5 seconds
    ping 127.0.0.1 -n 6 >nul
    del "%wkdir%\tmp_payload.flg"
goto final

:monitor
:: Create flag file and start the payload minimized.
:: echo the word "dummy" to the flag file (second parameter)
    echo >>%done_flag% dummy
:: start the command defined in the first parameter
    start /min cmd.exe /c "test2.bat %1"

:: Start monitoring.
::    i is the indicator (0=|,1=/,2=-,3=\).
::    m is the number of seconds left before timeout.
set i=0
set m=%timeout%
set str=%2
for /f "useback tokens=*" %%a in ('%str%') do set str=%%~a

<nul (set /p z=%str%^|)

:: Loop here awaiting completion.
:loop
    :: Wait one second.
    ping 127.0.0.1 -n 2 >nul

    :: Update counters and output progress indicator.
    set /a "i = i + 1"
    set /a "m = m - 1"
    if %i% equ 4 set i=0
    if %i% equ 0 <nul (set /p z=^|)
    if %i% equ 1 <nul (set /p z=/)
    if %i% equ 2 <nul (set /p z=-)
    if %i% equ 3 <nul (set /p z=\)

    :: End conditions, complete or timeout.
    if not exist %done_flag% (
        ::echo.
        echo Complete
        goto :final
    )
    if %m% leq 0 (
        echo.
        echo.   *** ERROR: Timed-out waiting for child.
        goto :final
    )
    goto :loop

:final
endlocal

このルーチンでは、CMDからのスタートプロセスのためのタスクリストの出力を調べます。
パラメータとしてそれをexeファイルの名前を渡し例えば
呼び出し:スピナーCALC.EXE
それは報告します
経過:001秒
exeファイルのプロセスが終了するまで、秒をインクリメントします。
経過001秒のメッセージはECHO.exe -n \ rで秒ごとに上書きされます
これは改行せずにCRをエコー表示。
Echo.exeは、提供されています
http://www.paulsadowski.com/wsh/cmdprogs.htmする

 @echo off
 start calc
 call :spinner calc.exe
 pause

 :spinner       
 SET COUNT=1
 :BEGIN
 set "formattedValue=000000%count%"
 ECHO.exe -n Elapsed: %formattedValue:~-3% seconds
 ECHO.exe -n \r    %= -n (suppress crlf) \r output a cr =%

 SET /A COUNT+=1

 set EXE=%1    %= search output of tasklist for EXE =%
 set tl=tasklist /NH /FI "IMAGENAME eq %EXE%"
 FOR /F %%x IN ('%tl%') DO IF %%x == %EXE% goto FOUND
 set result=0
 goto FIN
 :FOUND
 set result=1
 :FIN
 IF %result% EQU 0 GOTO END

 PING -n 2 127.0.0.1 > nul    %= wait for about 1 second =%

 GOTO BEGIN
 :END

ロードするのを待つ、アプリケーションを起動します。

@echo off & setlocal enabledelayedexpansion
start application.exe
:1
for %%a in (^| ^/ ^- ^\ ^| ^/ ^- ^\) do (
for %%b in (^| ^/ ^- ^\ ^| ^/ ^- ^\) do (
for %%c in (^| ^/ ^- ^\ ^| ^/ ^- ^\) do (
cls &echo processing..%%c%%b%%a
sleep -m 20
IF EXIST "result file" (exit)
)))
goto 1

:LOOP   ECHOX -n "〜R%で処理..."   %CTR%EQU 4 SET / A CTR = 0 IF   IF%CTR%== 0(セット/ PのDOT =³)     

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top