バッチファイル:(この時点では予想外だった

こんなエラーが出ます:

(この時点では予期していませんでした

このような問題を引き起こす可能性のあるNULL値がないか、試行錯誤しましたが、うまくいきませんでした。

echo off
cls
title ~USB Wizard~
echo What do you want to do?
echo 1.Enable/Disable USB Storage Devices.
echo 2.Enable/Disable Writing Data onto USB Storage.
echo 3.~Yet to come~.

set "a=%globalparam1%"
goto :aCheck
:aPrompt
set /p "a=Enter Choice: "
:aCheck
if "%a%"=="" goto :aPrompt
echo %a%

IF %a%==2 (
title USB WRITE LOCK
echo What do you want to do?
echo 1.Apply USB Write Protection
echo 2.Remove USB Write Protection
::param1
set "param1=%globalparam2%"
goto :param1Check
:param1Prompt
set /p "param1=Enter Choice: "
:param1Check
if "%param1%"=="" goto :param1Prompt

if %param1%==1 (
REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\StorageDevicePolicies\ /v WriteProtect /t REG_DWORD /d 00000001 
echo USB Write is Locked!
)
if %param1%==2 (
REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\StorageDevicePolicies\ /v WriteProtect /t REG_DWORD /d 00000000
echo USB Write is Unlocked! 
)
)
pause
質問へのコメント (1)
ソリューション

param1`のif文が評価されるとき、paramは遅延展開のないスコープ変数であるため、常にnullであるため、このようなエラーが発生するのです。

括弧が使用されると、その括弧内のすべてのコマンドと変数が展開されます。 そのとき、param1 には値がないため、if 文は無効になります。 遅延展開を使用すると、変数が展開されるのはコマンドが実際に呼び出されたときだけです。

また、変数が設定されているかどうかを判断するには、if not definedコマンドを使うことをお勧めする。

@echo off
setlocal EnableExtensions EnableDelayedExpansion
cls
title ~USB Wizard~
echo What do you want to do?
echo 1.Enable/Disable USB Storage Devices.
echo 2.Enable/Disable Writing Data onto USB Storage.
echo 3.~Yet to come~.

set "a=%globalparam1%"
goto :aCheck
:aPrompt
set /p "a=Enter Choice: "
:aCheck
if not defined a goto :aPrompt
echo %a%

IF "%a%"=="2" (
    title USB WRITE LOCK
    echo What do you want to do?
    echo 1.Apply USB Write Protection
    echo 2.Remove USB Write Protection

    ::param1
    set "param1=%globalparam2%"
    goto :param1Check
    :param1Prompt
    set /p "param1=Enter Choice: "
    :param1Check
    if not defined param1 goto :param1Prompt
    echo !param1!

    if "!param1!"=="1" (
        REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\StorageDevicePolicies\ /v WriteProtect /t REG_DWORD /d 00000001 
        echo USB Write is Locked!
    )
    if "!param1!"=="2" (
        REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\StorageDevicePolicies\ /v WriteProtect /t REG_DWORD /d 00000000
        echo USB Write is Unlocked! 
    )
)
pause
endlocal
解説 (0)

ああ、やれやれ。ちょっとした問題が...。

他の人が指摘しているように、空白やスペースを含むエントリーを防ぐために引用符で囲む必要がある。

その他、注意すべき点が2つある:

まず、set/pはユーザーが入力した値を変数に代入する。安全な方法は次のとおりです:

 set "var="
 set /p var=

もちろん、enterで既存の値を繰り返したくなければの話ですが。
別の便利な形式は

 set "var=default"
 set /p var=

または

 set "var=default"
 set /p "var=[%var%]"

(デフォルト値でプロンプトが表示されます。delayedexpansion を使用するブロック文の場合は !var!)

2つ目の問題は、Windowsのバージョンによっては(W7ではこの問題は修正されているようですが)、:: comment(broken-labelです)を含むどんなラベルでも 'block'を終了してしまうということです。)

解説 (4)

例えば、3つのif文のすべてに二重引用符が必要だ:

IF "%a%"=="2" (

@echo OFF &SETLOCAL ENABLEDELAYEDEXPANSION
cls
title ~USB Wizard~
echo What do you want to do?
echo 1.Enable/Disable USB Storage Devices.
echo 2.Enable/Disable Writing Data onto USB Storage.
echo 3.~Yet to come~.

set "a=%globalparam1%"
goto :aCheck
:aPrompt
set /p "a=Enter Choice: "
:aCheck
if "%a%"=="" goto :aPrompt
echo %a%

IF "%a%"=="2" (
    title USB WRITE LOCK
    echo What do you want to do?
    echo 1.Apply USB Write Protection
    echo 2.Remove USB Write Protection
    ::param1
    set "param1=%globalparam2%"
    goto :param1Check
    :param1Prompt
    set /p "param1=Enter Choice: "
    :param1Check
    if "!param1!"=="" goto :param1Prompt

    if "!param1!"=="1" (
         REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\StorageDevicePolicies\ /v WriteProtect /t REG_DWORD /d 00000001
         USB Write is Locked!
    )
    if "!param1!"=="2" (
         REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\StorageDevicePolicies\ /v WriteProtect /t REG_DWORD /d 00000000
         USB Write is Unlocked!
    )
)
pause
解説 (0)