0

これはコードです:

@echo off

cls
echo.
echo Hello, %username%.
echo This program will enable the sound service.
echo.

:case_1
call:print "Attempting to start Windows Audio..."
call:check_audio "sc start AudioSrv" "case_2"

:case_2
call:print "Attempting to start Windows Audio again..."
call:check_audio "C:\Windows\System32\svchost.exe -k LocalServiceNetworkRestricted" "case_3"

:case_3
echo.
echo Attempting to start dependencies...
echo.
call:print "Starting Multimedia Class Scheduler..."
call:check_active "MMCSS" "sc start MMCSS" "case_4" "Multimedia Class Scheduler"
call:print "Starting Remote Procedure Call (RPC)..."
call:check_active "RpcSs" "sc start RpcSs" "case_4" "Remote Procedure Call (RPC)"
call:print "Starting Windows Audio Endpoint Builder..."
call:check_active "AudioEndpointBuilder" "sc start AudioEndpointBuilder" "case_4" "Windows Audio Endpoint Builder"

call:print "Attempting to start Windows Audio again..."
call:check_audio "sc start AudioSrv" "case_4"

:case_4
echo.
echo Attempting to start dependencies again...
echo.
call:print "Starting Multimedia Class Scheduler..."
call:check_active "MMCSS" "C:\Windows\system32\svchost.exe -k netsvcs" "error" "Multimedia Class Scheduler"
call:print "Starting Remote Procedure Call (RPC)..."
call:check_active "RpcSs" "C:\Windows\system32\svchost.exe -k rpcss" "error" "Remote Procedure Call (RPC)"
call:print "Starting Windows Audio Endpoint Builder..."
call:check_active "AudioEndpointBuilder" "C:\Windows\System32\svchost.exe -k LocalSystemNetworkRestricted" "error" "Windows Audio Endpoint Builder"

call:print "Attempting to start Windows Audio again..."
call:check_audio "C:\Windows\System32\svchost.exe -k LocalServiceNetworkRestricted" "error"

:print
echo %1
echo.

:check_audio
:: Checking if Windows Audio is active. If it is unable to be activated, GOTO <label>.
:: If it has already been activated, GOTO exit.
for /f "tokens=3 delims=: " %%H in ('sc query "AudioSrv" ^| findstr "        STATE"') do (
    :: Tokenises line containing service's state, pulls out third token.
    :: Tests resulting state against the string, "RUNNING".
    if /i "%%H" NEQ "RUNNING" (
        %1 || goto %2
    ) else (
        goto exit
    )
)

:check_active
:: Checking if service is active. If it is unable to be activated, GOTO <label>.
:: If it has already been activated, state that it is already running.
for /f "tokens=3 delims=: " %%H in ('sc query "%1" ^| findstr "        STATE"') do (
    if /i "%%H" NEQ "RUNNING" (
        %2 || goto %3
    ) else (
        echo %4 is already running.
    )
)

:error
:: States what error the program failed with and exits.
echo Program failed with error #%errorlevel%.
exit /b %errorlevel%

:exit
call:print "The program was successful. Windows Audio is running."
pause
exit

少しスパゲッティ風ですが、うまくいきます... 並べ替え。通常モードで実行すると、無限ループに入り、CTRL-C で終了するまで常にラベル「:exit」を呼び出します。どうしてこれなの?

4

1 に答える 1

0

フォールスルーしているコールと、コール チェーン内を上下に移動しているコールがあります。

この問題を示す非常に簡単な例を次に示しCtrl+Cます (無限ループから抜け出すには、 を使用する必要があります (数回の試行が必要になる場合があります)。画面上の出力を確認して、何が起こったかを確認してください)。

@echo off
:callit
call:print "Callit"

:print                              :: Start execution
echo %1
echo.                               :: Fall through to :error

:error                              
echo "In Error"                     :: Continue execution (fall through)

:exit
call:print "Loop from exit"         :: Loop back upward to :print and start again
pause
exit

次のような出力が表示されます (小さな抜粋、実行の開始と終了 - 簡潔にするために途中で切り取られた大きな繰り返しのチャンク):

"Callit"

"In Error"
"Loop from exit"

"In Error"
"Loop from exit"

"In Error"
"Loop from exit"

"In Error"
"Loop from exit"

"In Error"
"Loop from exit"

"In Error"
"Loop from exit"

"In Error"
"Loop from exit"

"In Error"
^CTerminate batch job (Y/N)?
于 2014-01-17T16:33:34.640 に答える