¿Por qué la subcadena CMD no funciona cuando BAT llama desde SENDTO?

¿Por qué la subcadena CMD no funciona cuando BAT llama desde SENDTO?

Escribí un archivo BAT para quitar la '@' inicial de un nombre de archivo. (¡Por favor, no preguntes por qué! ...por qué Windows, por qué CMD...) :)

Aquí está el archivo BAT:

IF EXIST "%~1" (

    FOR /F %%F IN ("%~1") DO (

        CD /D "%%~dpF"
        IF ERRORLEVEL 1 (
            ECHO.  Failed to CD to folder: %%~dpF
        ) ELSE (
            SETLOCAL ENABLEEXTENSIONS
            SET A=%%~nxF

            IF "%A:~0,1%"=="@" (

                ECHO.   RENAME "%A%" "%A:~1%"
                    RENAME "%A%" "%A:~1%"
                REM   RENAME "%%A%" "%%A:~1%"
            ) ELSE (
                ECHO.   File does not start with @:  %A%
            )
            ENDLOCAL
        )
    )
) ELSE (
    ECHO.    File not found:  %1
)

pause

Cuando lo ejecuto desde la línea de comando en una ventana de DOS, parece funcionar:

18:54:04.97>dir /b *foo*
@foo.txt

18:54:07.97>test@ "%cd%\@foo.txt"

18:54:18.75>IF EXIST "C:\Users\me\lbin\@foo.txt" (FOR /F %F IN ("C:\Users\me\lbin\@foo.txt") DO (
CD /D "%~dpF"
 IF ERRORLEVEL 1 (ECHO.  Failed to CD to folder: %~dpF )  ELSE (
SETLOCAL ENABLEEXTENSIONS
 SET A=%~nxF
 IF "@" == "@" (
ECHO.   RENAME "@foo.txt" "foo.txt"
 RENAME "@foo.txt" "foo.txt"
 REM   RENAME "%Afoo.txt"
)  ELSE (ECHO.   File does not start with @:  @foo.txt )
 ENDLOCAL
)
) )  ELSE (ECHO.    File not found:  "C:\Users\me\lbin\@foo.txt" )

18:54:18.77>(
CD /D "C:\Users\me\lbin\"
 IF ERRORLEVEL 1 (ECHO.  Failed to CD to folder: C:\Users\me\lbin\ )  ELSE (
SETLOCAL ENABLEEXTENSIONS
 SET [email protected]
 IF "@" == "@" (
ECHO.   RENAME "@foo.txt" "foo.txt"
 RENAME "@foo.txt" "foo.txt"
 REM   RENAME "%Afoo.txt"
)  ELSE (ECHO.   File does not start with @:  @foo.txt )
 ENDLOCAL
)
)
   RENAME "@foo.txt" "foo.txt"

18:54:18.80>pause
Press any key to continue . . .
18:54:20.74>

pero cuando ejecuto el archivo BAT desde un acceso directo en el menú ENVIAR A, la substringoperación no se expande correctamente - específicamente, "SI" no se expande correctamente ( IF "%A:~0,1%"=="@" () - ¿ves?...

C:\Users\me\lbin>IF EXIST "C:\Users\me\lbin\@foo.txt" (FOR /F %F IN ("C:\Users\me\lbin\@foo.txt") D
O (
CD /D "%~dpF"
 IF ERRORLEVEL 1 (ECHO.  Failed to CD to folder: %~dpF )  ELSE (
SETLOCAL ENABLEEXTENSIONS
 SET A=%~nxF
 IF "~0,1" == "@" (
ECHO.   RENAME "" "~1"
 RENAME "" "~1"
 REM   RENAME "%A~1"
)  ELSE (ECHO.   File does not start with @:   )
 ENDLOCAL
)
) )  ELSE (ECHO.    File not found:  C:\Users\me\lbin\@foo.txt )

C:\Users\me\lbin>(
CD /D "C:\Users\me\lbin\"
 IF ERRORLEVEL 1 (ECHO.  Failed to CD to folder: C:\Users\me\lbin\ )  ELSE (
SETLOCAL ENABLEEXTENSIONS
 SET [email protected]
 IF "~0,1" == "@" (
ECHO.   RENAME "" "~1"
 RENAME "" "~1"
 REM   RENAME "%A~1"
)  ELSE (ECHO.   File does not start with @:   )
 ENDLOCAL
)
)
   File does not start with @:

C:\Users\me\lbin>pause
Press any key to continue . . .

¿Ideas?

Respuesta1

Expansión retrasadahará que las variables se expandan en el momento de la ejecución en lugar de en el momento del análisis, esta opción se activa con el SETLOCALcomando. Cuando la expansión retrasada está en vigor, se puede hacer referencia a las variables usando !variable_name!(además del normal %variable_name%)

Por lo tanto, use !A!, !A:~0,1!y !A:~1!en lugar de %A%, %A:~0,1%y %A:~1%respectivamente de la siguiente manera:

        SETLOCAL ENABLEEXTENSIONS
        SET A=%%~nxF

        IF "!A:~0,1!"=="@" (

            ECHO.   RENAME "!A!" "!A:~1!"
                    RENAME "!A!" "!A:~1!"
        ) ELSE (
            ECHO.   File does not start with @:  !A!
        )
        ENDLOCAL

información relacionada