CMD: failure of %~d0 when CALL quotes the name of the batch file

后端 未结 4 2187
遥遥无期
遥遥无期 2021-01-03 02:43

Why the following failure of %~d0 to return the batch file\'s drive letter S: when CALL quotes the name of the batch file?

S:\\!DJ DAP>type test.b         


        
4条回答
  •  谎友^
    谎友^ (楼主)
    2021-01-03 03:07

    EDIT - npocmaka, you are right. Strange.

    Original answer removed - I was wrong.

    But problem is not the call command. The problem are the quotes and cmd.

    After testing, it seems more a bug/feature in how filenames are processed and how cmd are handling some errors in api calls.

    With the following batch file (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
    

    placed in d:\temp\testCMD and current directory in drive c: is C:\Users, the results on execution are:

    1.- Calling without quotes from cmd directory: 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
    ---------------------------------------------------------
    

    Result: everything ok.

    2.- Calling with quotes from cmd directory "test.cmd" (no, no need for call command)

    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
    ---------------------------------------------------------
    

    Result: Failure to get correct value of %~d0 ONLY if directly get from main execution line of cmd. The same with subroutine call works as expected.

    All scenarios tested without quotes work without failure. With quotes, if the calling line include the drive (ej: "d:.\test.cmd") all values are correctly retrieved. If not drive included in batch call, (ej: "test.cmd" with batch directory in path, or "\temp\testCMD\test.cmd" from root of D:), incorrect values retrieved, but only from main line of execution in batch file. Subroutines always get correct values.

    Why? No idea. But when tracing cmd execution with procmon, in failure cases, when cmd.exe try to retrieve the information for the file, a QueryDirectory API call is made for C:\Users\test.cmd which is answered with NO SUCH FILE, but cmd ignores it and continues execution, showing the wrong values.

    So, no answer, sorry. But i had to "document" this. Some guru in the room?

    update: More information here

提交回复
热议问题