batch-file - CMD: 当 CALL 引用批处理文件的名称时 %~d0 失败

标签 batch-file cmd windows-xp

为什么以下 %~d0 返回批处理文件的驱动器号 S 失败:当 CALL 引用批处理文件的名称时?

S:\!DJ DAP>type test.bat
R:
%~d0

S:\!DJ DAP>call test.bat

S:\!DJ DAP>R:

R:\>S:

S:\!DJ DAP>call "test.bat"

S:\!DJ DAP>R:

R:\>R:

R:\>

编辑以下 Jerry 和 MC 的回复:这是一个非 CALL 示例,显示相同:
R:\>s:

S:\!DJ DAP>type test.bat
R:
%~d0

S:\!DJ DAP>test.bat

S:\!DJ DAP>R:

R:\>S:

S:\!DJ DAP>"test.bat"

S:\!DJ DAP>R:

R:\>R:

R:\>

最佳答案

编辑 - npocmaka,你是对的。奇怪的。

原始答案已删除 - 我错了。

但问题不是call命令。问题是引号和 cmd。

经过测试,在文件名的处理方式以及 cmd 如何处理 api 调用中的一些错误方面,它似乎更像是一个错误/功能。

使用以下批处理文件(test.cmd)

@echo off
    setlocal enableextensions

    echo Calling subroutine from drive d:
    call :getInfo
    echo.

    c:
    echo Calling subroutine from drive c:
    call :getInfo
    echo.

    echo Getting data directly without subroutine

:getInfo
    echo ---------------------------------------------------------
    echo cd    : %cd%
    echo d0    : %~d0
    echo dp0   : %~dp0
    echo f0    : %~f0
    echo ---------------------------------------------------------
    echo.
    goto :EOF

放在d:\temp\testCMD,c盘当前目录为C:\Users,执行结果为:

1.- 不带引号的调用 从 cmd 目录:test.cmd
Calling subroutine from drive d:
---------------------------------------------------------
cd    : D:\temp\testCMD
d0    : D:
dp0   : D:\temp\testCMD\
f0    : D:\temp\testCMD\test.cmd
---------------------------------------------------------


Calling subroutine from drive c:
---------------------------------------------------------
cd    : C:\Users
d0    : D:
dp0   : D:\temp\testCMD\
f0    : D:\temp\testCMD\test.cmd
---------------------------------------------------------


Getting data directly without subroutine
---------------------------------------------------------
cd    : C:\Users
d0    : D:
dp0   : D:\temp\testCMD\
f0    : D:\temp\testCMD\test.cmd
---------------------------------------------------------

结果:一切正常。

2.- 用引号调用 从 cmd 目录 "test.cmd" (不,不需要 call 命令)
Calling subroutine from drive d:
---------------------------------------------------------
cd    : D:\temp\testCMD
d0    : D:
dp0   : D:\temp\testCMD\
f0    : D:\temp\testCMD\test.cmd
---------------------------------------------------------


Calling subroutine from drive c:
---------------------------------------------------------
cd    : C:\Users
d0    : D:
dp0   : D:\temp\testCMD\
f0    : D:\temp\testCMD\test.cmd
---------------------------------------------------------


Getting data directly without subroutine
---------------------------------------------------------
cd    : C:\Users
d0    : C:
dp0   : C:\Users\
f0    : C:\Users\test.cmd
---------------------------------------------------------

结果:仅当直接从 cmd 的主执行行获取时,才无法获取正确的 %~d0 值。与子程序调用相同,按预期工作。

没有引号测试的所有场景都可以正常工作。使用引号,如果调用行包含驱动器 (ej: "d:.\test.cmd" ),则所有值都将被正确检索。如果驱动器不包含在批处理调用中,(ej:"test.cmd" 路径中包含批处理目录,或来自 D: 根目录的 "\temp\testCMD\test.cmd"),检索到不正确的值,但仅来自批处理文件中的主执行行。子程序总是得到正确的值。

为什么?不知道。但是当使用 procmon 跟踪 cmd 执行时,在失败的情况下,当 cmd.exe 尝试检索文件的信息时,会为 C:\Users\test.cmd 调用 QueryDirectory API。回答为 NO SUCH FILE , 但是cmd忽略它并继续执行,显示错误的值 .

所以,没有答案,对不起。但我必须“记录”这一点。房间里有什么大师?

更新 : 更多信息here

关于batch-file - CMD: 当 CALL 引用批处理文件的名称时 %~d0 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19781569/

相关文章:

batch-file - 如何制作批处理文件以运行热键

windows - 只需知道MAC地址即可获取IP

c# - 如何在 C# 中运行静默安装程序

cmd - 每天生成日志

java - 自动执行带有args的程序

python - 我所有的 python windows 服务都停止工作

windows - 从 Emacs 运行 Windows 批处理文件

git - git 分支名称中的 Powershell 和德语变音符号

performance - WatiN Dispose() 真的很慢

windows-xp - 我怎样才能强制刷新哪些端口有监听器