0

我有一个批处理文件,在批处理文件中,它在一个特定的目录中查找并保存到一个变量中,即第一个目录/文件的名称。这大致是我在做什么:

FOR /d %%F IN (%INSTALL_DIR%\dir\*) DO (
    set NAME=%%~xnF
    set NAME_DIR=%INSTALL_DIR%\dir\%NAME%
    goto :break
)

当我从命令行运行它时,它工作得很好,并且 NAME_DIR 得到了正确的值。但是,当我双击该文件时,NAME 变量为空。NANE_DIR 因此设置为 %INSTALL_DIR%\dir。为什么会发生这种情况,我能做些什么来解决它?

为了更清楚地说明,在命令行中,这是 NAME 和 NAME_DIR 在回显时相等的内容:

NAME:      dir1.3.8
NAME_DIR:  D:\root\path\to\dir\dir1.3.8

这是双击时回显的内容:

NAME:      
NAME_DIR:  D:\root\path\to\dir
4

1 回答 1

2

RaymondChen 在评论中告诉我的内容奏效了!我需要使用延迟扩展。原因是windows将for循环作为一条指令执行,因此它在执行for循环之前一次填充所有变量。因为我从来没有在 for 循环之前设置过 NAME,所以它只会评估为空。因此 NAME_DIR 得到一个空字符串来代替 %NAME%。我注意到当我第一次在命令行上运行脚本时,它不起作用。我再次运行它并且它工作。我一直在运行它,并且每次都有效。那是因为在运行一次 for 循环后,变量被保存并且永远不会改变。所以下次我运行代码时,变量不再是空白,它具有正确的值。现在双击时,NAME 变量在开始时为空。for循环执行后,NAME 的值已更新。一旦脚本执行并且 cmd 窗口退出,变量的新值就会丢失,它会重新开始。这是延迟扩展的新代码:

setlocal ENABLEDELAYEDEXPANSION

FOR /d %%F IN (%INSTALL_DIR%\dir\*) DO (
    set NAME=%%~xnF
    set NAME_DIR=%INSTALL_DIR%\dir\!NAME!
    goto :break
)

我在 setlocal 语句中添加并更改%NAME%!NAME!

于 2013-05-07T13:50:08.353 回答