If statement 批处理文件:(此时意外)

If statement 批处理文件:(此时意外),if-statement,batch-file,cmd,If Statement,Batch File,Cmd,我得到这个错误: (这在当时是出乎意料的 在接受a的值后发生错误。我尝试并检查了可能导致此问题的空值,但未成功 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=%global

我得到这个错误:

(这在当时是出乎意料的

在接受
a
的值后发生错误。我尝试并检查了可能导致此问题的空值,但未成功

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

在所有三个
if
语句中都需要双引号,例如:

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


之所以会出现此错误,是因为在计算
param1
if语句时,param始终为null,因为它是范围变量,没有延迟扩展

当使用括号时,括号内的所有命令和变量都会展开。此时,param1没有值使if语句无效。当使用延迟展开时,只有在实际调用命令时才会展开变量

另外,我建议使用
如果未定义
命令来确定是否设置了变量

@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

哦,天哪。有几个小问题

正如其他人所指出的,您需要引用以防止包含条目的空/空格,并使用!delayed_expansion!工具

您应注意的另外两个事项:

首先,
set/p
将为变量分配一个用户输入值。这不是新闻-但问题是,按
enter
作为响应将保持变量不变-它不会为变量分配零长度字符串(因此从环境中删除变量)。安全方法是:

 set "var="
 set /p var=
当然,也就是说,如果您不想
输入
重复现有值。
另一种有用的形式是

 set "var=default"
 set /p var=

(如果在带有delayedexpansion的块语句中,则提示使用默认值;
!var!


第二个问题是,在某些Windows版本上(尽管W7似乎“修复”了此问题),任何标签(包括
::comment
(这是一个断开的标签)都将终止任何“块”——即括号中的复合语句)

如果If语句中出现此错误,请检查是否使用了double equals来比较变量

例如

此时抛出“=1”是意外的

要更正此错误,请添加另一个等号

IF [%checkresult%]==1 GOTO INVALID

如果打开echo(第一行),你看到什么有用的东西了吗?+1关于hack标签注释的要点。这里有一个关于奇怪标签注释行为的有趣讨论:@David有趣的讨论,但我不认为
是一个失败的日志驱动器开关。如果是,它应该在一个块之外发现一个错误令人遗憾的是,关于标签定位的规则和规定可能很有趣,评论超出了当今普通或临时配料员的注意范围,维护过程中可能出现的破损使其变得“聪明”使用对我来说太危险了。我也不确定这种情况是否取决于版本。为了理智起见,我将坚持无标签/:-comments-in-a-block哲学。我同意你的观点。由于未定义的行为,黑客标签评论应该始终避免放在括号内。讨论只针对那些想阅读更多内容的人关于这些行为以及为什么使用它们不好。::for循环中的注释是我的问题。这是我搜索中出现的第一项。谢谢!%var%“==”期望“是的,这是一个很好的答案!@endro你的答案解决了我的问题,花了我很多时间。谢谢!
 set "var=default"
 set /p "var=[%var%]"
IF [%checkresult%]=1 GOTO INVALID
IF [%checkresult%]==1 GOTO INVALID