Handling ; (semi-colon) in filenames with this drag and drop routine

北城余情 提交于 2021-02-07 19:40:19

问题


Consider these filenames.

; f - Copy.txt
;f.txt
f - Copy ;- Copy.txt
f - Copy.txt

I've got this code which resolves the & symbol in any files with this answer: Drag and drop batch file for multiple files?

@echo off
title %~nx0
setlocal enabledelayedexpansion
rem Take the cmd-line, remove all until the first parameter
set "params=!cmdcmdline:~0,-1!"
set "params=!params:*" =!"
set count=0
rem Split the parameters on spaces but respect the quotes
for %%G IN (!params!) do (
  set /a count+=1
  set "item_!count!=%%~G"
  rem echo !count! %%~G
)
for /l %%c in (1,1,!count!) DO (
for /f "delims=;" %%A in ("!item_%%c!") do (
  echo path: %%~dpA
  echo file: %%~A
  )
)
pause
rem ** The exit is important, so the cmd.exe doesn't try to execute commands after ampersands
exit

If I drag the files to the batch file it uses ; as the delimiter resulting in undesired results.

To get around this with the for /f you can do the following below but I'm at a loss as to how to incorporate that fix into the drag and drop code above.


There's an issue with the for /f whereby it uses ; as the delimiter also but this can be resolved with (This trick can be found here) for /f tokens^=*^ delims^=^ eol^=^¬ %%A in ('dir "%cd%" /a-d /b') do ( echo %%~A )

Which results in:

; f - Copy.txt
;f.txt
f - Copy ;- Copy.txt
f - Copy.txt

as opposed to: for /f "tokens=* delims=" %%A in ('dir "%cd%" /a-d /b') do ( echo %%~A )

Which results in:

f - Copy ;- Copy.txt
f - Copy.txt

How can I fix this issue with the drag and drop code?

Edit: I'm getting kinda close with this.

@echo off
setlocal enabledelayedexpansion
for /f tokens^=*^ delims^=^ ^ eol^=^¬ %%A in (""!%*!"") do ( echo "%%~fA" )

Edit: (more examples) Another example that can extend the dropped items to any those at this link: Extended Filename syntax to %* with the following workaround. This also works in a half-hearted sort of way.

setlocal enabledelayedexpansion
for %%A in (%*) do ( call :FIX "%%~A" )
pause
:FIX
SET _params=!%*!
CALL :sub "%_params%"
GOTO :eof
:: Now display just the filename and extension (not path)
:sub
ECHO "%~nx1"
:: All of these returns are when each file (one at a time) is dragged to the batch file.
rem folder name , goes = here...        works      returns "folder name , goes = here..."
rem ; f - copy.txt                      works      returns "; f - copy.txt"
rem ;f.txt                              doesn't    returns "." ""
rem a.txt                               works      return  "a.txt"
rem b.txt                               works      return  "b.txt"
rem c.txt                               works      return  "c.txt"
rem cool&stuff.png                      doesn't    returns "Cool""
rem copy = copy.txt                     works      returns "copy = copy.txt"
rem f - copy - copy.txt                 works      returns "f - copy - copy.txt"
rem f - copy ,- copy - copy.txt         works      returns "f - copy ,- copy - copy.txt"
rem f - copy ;- copy.txt                works      returns "f - copy ;- copy.txt"
rem f - copy.txt                        works      returns "f - copy.txt "
rem f - copy1.txt                       works      returns "f - copy1.txt"
rem FILENAME WITH & IN IT!! - COPY.TXT  doesn't    returns "FILENAME WITH & IN IT - COPY.TXT""
rem FILENAME WITH & IN IT!!.TXT         doesn't    returns "FILENAME WITH & IN IT.TXT""

回答1:


I've found a thread here that addresses this issue and as far as I can see, works with any special characters.

Big thanks to user aGerman on that forum... All credit goes to him.

Link to that thread:

Solved How to escape special characters on InputFile with Drag and Drop ?

Other useful links:

Simplest loop to perform actions on x dragged files?

'Pretty print' windows %PATH% variable - how to split on ';' in CMD shell

Drag and drop batch file for multiple files?

@echo off &setlocal DisableDelayedExpansion

setlocal EnableDelayedExpansion
set "params=!cmdcmdline:~,-1!"
set "params=!params:*" =!"

if "!params!"=="" exit

endlocal&set "params=%params:"=""%"
set "params=%params:^=^^%"
set "params=%params:&=^&%"
set "params=%params: =^ ^ %"
set params=%params:""="%
set "params=%params:"=""Q%"
set "params=%params:  ="S"S%"
set "params=%params:^ ^ = %"
set "params=%params:""="%"

setlocal EnableDelayedExpansion
set "params=!params:"Q=!"

for %%i in ("!params:"S"S=" "!") do (
  if "!!"=="" endlocal
  REM only files ...
  if not exist "%%~i\" (
  set "file_folder=%%~i"
  call :proc
  )
  )

echo ready.
pause
exit

:proc
echo process "%file_folder%" here ...
goto :eof



回答2:


As jeb noted, the main problem comes from a file such as ;f.txt not being enclosed in double-quotes. Ste's answer is probably better, since it doesn't involve "eating" chunks of params, but as I was most of the way through revising my original attempt when that was posted, I decided to finish it and offer it as another approach.

@echo off
title %~nx0
setlocal enabledelayedexpansion
rem Take the cmd-line, remove all until the first parameter
set "params=!cmdcmdline:~0,-1!"
set "params=::!params:*" =!"
set count=0
:loop
  for /f usebackq^ tokens^=1^ delims^=^" %%A in ('!params:~2!') do (
    REM The second test below tests if "params" started with a double-quote.
    REM Taken from https://ss64.org/viewtopic.php?pid=850#p850
    if "%%A" == " " (
      set "params=::!params:~3!"
    ) else if [!params:~2^,1!]==[^"] (
      call :proc "%%A"
      set "params=::!params:::"%%A"=!"
    ) else (
      set "spaces=%%A"
      set "spaces=^"!spaces: =^" ^"!^""
      for %%B in (!spaces!) do if not "%%~B" == "" (
        call :proc "%%~B"
      )
      set "params=::!params:::%%A=!"
    )
  )
  if not "!params!" == "::" goto :loop
  pause
  exit

:proc
    echo process "%~1" here ...
    goto :eof

Dropping the above four files (plus f ; & ; f.txt and a few others for good measure) into this script produces:

process "C:\X\Dev\Semicolons\q" here ...
process "C:\X\Dev\Semicolons\q q q" here ...
process "C:\X\Dev\Semicolons\; f - Copy.txt" here ...
process "C:\X\Dev\Semicolons\;f.txt" here ...
process "C:\X\Dev\Semicolons\f - Copy ;- Copy.txt" here ...
process "C:\X\Dev\Semicolons\f - Copy.txt" here ...
process "C:\X\Dev\Semicolons\f ; & ; f.txt" here ...
process "C:\X\Dev\Semicolons\f.safe.txt" here ...
process "C:\X\Dev\Semicolons\f.safe2.txt" here ...
Press any key to continue . . .

Notes

  • The drag-and-drop interface wraps some unsafe filenames in double-quotes (e.g. those containing spaces) but not all (e.g. those containing ;), Thus we cannot just use for %%a in (!params!) to process all files.

  • Instead, the basic idea is to split the params variable at the first double-quote (if present), process that "chunk", then remove it from params and repeat.

  • If the chunk is a space (" ") then we simply remove it (this can happen as part of processing the other chunks).

  • If params started with a double-quote when the current chunk was extracted, then it represents a single file and it is processed (call :proc). That filename (with its surrounding double-quotes) is then removed from params and we loop back.

  • If params didn't start with a double-quote, then we have one or more filenames in the current chunk. We know that none of them contain spaces (because otherwise they would be wrapped in double-quotes), but they might contain other "problem" characters such as ;. Therefore, we wrap each space-delimited component of the chunk in double-quotes (turning aaa bbb ccc into "aaa" "bbb" "ccc") and use a simple for loop to process each one. (The "" test is because there can be stray spaces at the beginning or end of the chunk). After all file(s) have been processed, the original chunk is removed from params and we loop back.

  • The :: prefix prepended to params (and skipped in the main for command) is to catch a particular issue if one file name is a prefix of another (e.g. C:\Files\Q and C:\Files\Q Q). Without the ::s, when removing C:\Files\Q from params, the replace-all-occurrences nature of CMD means the second file's name is mangled. Keeping params prefixed with :: (which can never occur in a valid file) stops this from happening.

  • The script should work for any number of files (up to the roughly 8,192-character limit for the original command-line).




回答3:


My own version to solve all drag&drop problems:

Can handle any filenames, like

d1_;,=
d2_four spaces
d3_One&Amp
d4_Amp&with space

But there is still a strong problem, filenames like a&() can't be handled by the drag.bat, because the filename creates a syntax error even before the batch file is called.

But with a nasty hack it can be solved, then even the hard ones works!

d5_syntax&()error

cmd.exe can start an AutoRun (batch) command, if registered.
This AutoRun batch file gets no arguments, but the complete command in cmdcmdline.
I simply parse that data and if necessary I rebuild new quoted arguments (only 300 lines).
For modifying the registry entry use

AutoRun --show
AutoRun --install
AutoRun --remove

drag.bat


@echo off

setlocal ENABLEDELAYEDEXPANSION
rem *** Take the cmd-line, remove all until the first parameter
rem *** Copy cmdcmdline without any modifications, as cmdcmdline has some strange behaviour
set "params=!cmdcmdline!"
set "params=!params:~0,-1!"
set "params=!params:*" =!"
call :fn_$arg_parser params

REM ** FOR /L %%# in (0 1 !arg#-1!) DO (
REM **  echo arg%%# = '!arg%%#!'
REM ** )

set count=0

rem Split the parameters on spaces but respect the quotes
set "params=!params:^;^=""S!"
for %%G IN (!params:^;^=""S!) do (
  set /a count+=1
  set "_item=%%~G"
  set "item_!count!=!_item:""=;!"
  rem echo !count! %%~G
)

rem list the parameters
for /L %%n in (1,1,!count!) DO (
  echo arg%%n #!item_%%n!#
)
pause > NUL

REM ** The exit is important, so the cmd.exe doesn't try to execute commands after ampersands
exit


:fn_$arg_parser arg_line
REM *** @TODO: ENDLOCAL all arg-... variables
::: Output arg0, ..., arg and arg#
::: arg0 ... arg contains unquoted arguments
::: an argument that contains only one quote (last character in line) is treated as quoted  arg=" -> arg=, arg.quoted=1
::: arg0.quoted contains 1 if the argument was quoted
::: \ escapes the next character (also inside quotes), can escape delimiters outside quotes, can escape quotes
::: Only \" is replaced to a single quote ", all other \ are unchanged

(set^ arg_line=!%1!)
call :strlen arg_len arg_line
set /a arg_len-=1

set "quoted="
rem set "escapeChar="   --- "Say: \"Hello\" to frank\n"
set /a arg#=0
set "arg0="
for /L %%I in (0 1 !arg_len!) DO (
    for %%# in (!arg#!) DO  (
        set "char=!arg_line:~%%I,1!"
        set "isDelim="

        if "!escapeChar!!char!" == ^""" set "quoted=!quoted:~,0!"

        REM echo %%I: "!char!" quote: !quote!
        %= only outside quotes =%
        %= check if char is a delim =%
        FOR /F "tokens=1,2 delims= " %%D in ("isDelim!char!NO") DO (
            if "%%D" == "isDelim" (
                set isDelim=1
            )
        )

        REM *** Split arguments by not escaped delimiter
        if "!isDelim!,!quoted!,!escapeChar!" == "1,," (
            REM *** Finalize arg, test if arg is quoted
            if defined arg%%# (
                set arg%%#.quoted=
                REM echo    #in %%# "!arg%%#:~,1!!arg%%#:~-1!"
                if "!arg%%#:~,1!!arg%%#:~-1!" == """" (
                    if "!arg%%#:~-2,-1!" NEQ "\" (
                        set arg%%#.quoted=1
                        set "arg%%#=!arg%%#:~1,-1!"
                    )
                )
                if defined arg%%# (
                    set ^"arg%%#=!arg%%#:"\"="!"
                )
                set /a arg#+=1
            )
        )

        if defined escapeChar (
            set "escapeChar="
            if "!char!" EQU ^""" (
                REM *** Replace escaped quotes with "\" that can be safely detected and replaced later
                set "char="\""
            ) ELSE IF defined isDelim (
                set "isDelim="
            ) ELSE (
                set "char=\!char!"
            )
        ) ELSE if "!char!" == "\" set "escapeChar=\"

        if defined quoted set "isDelim="

        REM *** Append char to arg
        if "!isDelim!!escapeChar!" == "" (
            set "arg%%#=!arg%%#!!char!"
        )
    )
)

for %%# in (!arg#!) DO (
    REM *** Last character is \
    if defined escapeChar (
        set "arg%%#=!arg%%#!\"
    )

    REM *** Duplicated code
    REM *** Finalize arg, test if arg is quoted
    if defined arg%%# (
        set arg%%#.quoted=
        REM echo out %%# "!arg%%#:~,1!!arg%%#:~-1!"
        if "!arg%%#:~,1!!arg%%#:~-1!" == """" (
            if "!arg%%#:~-2,-1!" NEQ "\" (
                set arg%%#.quoted=1
                set "arg%%#=!arg%%#:~1,-1!"
            )
        )
        if defined arg%%# (
            set ^"arg%%#=!arg%%#:"\"="!"
        )
        set /a arg#+=1
    )
)
REM *** Create a helper variable with name "arg#-1"
set /a tmp=!arg#!-1
set "arg#-1=!tmp!"

exit /b
::: detector line %~* *** FATAL ERROR: missing parenthesis or exit /b
:strlen  
(   
    setlocal EnableDelayedExpansion
    (set^ tmp=!%~2!)
    if defined tmp (
        set "len=1"
        for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
            if "!tmp:~%%P,1!" NEQ "" ( 
                set /a "len+=%%P"
                set "tmp=!tmp:~%%P!"
            )
        )
    ) ELSE (
        set len=0
    )
)
( 
    endlocal
    set "%~1=%len%"
    exit /b
)

AutoRun.bat


@echo off
REM *** To enable this script, call it by  --install

REM *** To see the current values
REM *** reg query "HKEY_CURRENT_USER\Software\Microsoft\Command Processor" /v AutoRun
REM *** reg query "HKEY_LOCAL_MACHINE\\Software\Microsoft\Command Processor" /v AutoRun

REM *** To delete the keys
REM *** reg DELETE "HKEY_CURRENT_USER\Software\Microsoft\Command Processor" /v AutoRun /f
REM *** reg DELETE "HKEY_LOCAL_MACHINE\\Software\Microsoft\Command Processor" /v AutoRun /f

setlocal EnableDelayedExpansion
REM *** ALWAYS make a copy of the complete CMDCMDLINE, else you destroy the originial!!!
set "_ccl_=!cmdcmdline!"
echo(>CON

REM *** %1 contains only data, when the script itself was called from the command line
if "%~1" NEQ "" (
    goto :direct_call
)
REM echo #0 '!_ccl_!' > CON
REM *** The check is necessary to distinguish between a new cmd.exe instance for a user or for a "FOR /F" sub-command
if "!_ccl_:~1,-2!" == "!comspec!" (
    REM ***** INTERACTIVE ****

    echo %DATE% %TIME% comspec >> "%~dp0\started.log"
    FOR %%M in ("%~dp0\cmdMacros.mac") DO (
        endlocal    
        echo ********************************************************************
        echo * AutoRun executed from "%~f0"
        if exist "%%~M" (
            doskey /macrofile="%%~M"
            echo * Macros loaded from "%%~M"
        ) ELSE (
            echo * Macrofile missing at "%%~M"
        )
        echo ********************************************************************
    )
    REM set "path=%path%;%~dp0"

    SET "BATLIB=C:\Project\BatchLibrary"

    call cd /D "%%BATLIB%%"
) ELSE (
    REM *** This is a FOR command, a call by an explorer click or a drag & drop operation

    REM *** Try to detect a PROBLEMATIC Drag&Drop operation, if it has the format `%comspec% /c ""`
    REM *** It's only problematic when there is one & in the data
    REM *** But it's not bullet proof, FOR /F in ('""C:\temp\myfile.bat" C:\temp\file&second.bat"') can't be distinguished

    REM *** First check, that the cmdline starts with `%comspec% /c ""....`
    if "!_ccl_!" NEQ "!_ccl_:*/c ""=#!" if "!comspec! /c ""!_ccl_:*/c ""=!" == "!_ccl_!" (
        REM *** Only handle it, if there is at least one & and no pipe |
        if "!_ccl_!" NEQ "!_ccl_:&=!" if "!_ccl_!" EQU "!_ccl_:|=!" (
            call :DRAG_and_drop
            %DEBUG_DRAG% echo # BACK from DRAG_and_drop
        )
    )
    REM *** Leaving now
    REM *** This is a "FOR /F" sub-command 
    REM *** or a "harmless" drag&drop 
    REM *** or the second run of a problematic drag&drop
    REM echo %DATE% %TIME% internal "!_ccl_!" >> "%~dp0\started.log"
    endlocal
)

exit /b

:DRAG_and_drop
REM *** This results into recursive execution of this script
REM *** Be sure, that it's not an endless recursion

REM *** Remove the front 
REM set "_ccl_=!_ccl_:&=+!"
set "_ccl_=!_ccl_:~0,-1!"
set "_ccl_=!_ccl_:*/c "=!"
set "DEBUG_DRAG=REM " 

%DEBUG_DRAG% echo #A '!_ccl_!' > CON

call :arg_parser argv _ccl_ 

REM *** Check if there is at least one unquoted, problematic &
REM *** This arg must not have spaces
set "isDragAndDrop="

if defined argv.onlySingleSpace (
    set "isDragAndDrop=1"
    set "problematic="
    set "args="
    FOR /L %%# in (0 1 !argv#-1!) DO (
        set "arg=!argv[%%#]!"
        REM *** Check if it's an absolute path
        FOR /F "tokens=1,*" %%1 in (": !arg!") DO (
            if "%%~f2" NEQ "%%~2" (
                set "isDragAndDrop="
                %DEBUG_DRAG% echo *** 'NO PATH' !arg! NEQ %%~f2 > CON
                exit /b
            )
        )

        if defined argv[%%#].quoted (
            set "arg="!arg!""
        ) ELSE (
            REM *** If not quoted but contains a &

            if "!arg!" NEQ "!arg:&=!" (
                if "!arg:~1,2!" EQU ":\" (
                    set "arg="!arg!""
                    set "problematic=1"             
                ) ELSE (
                    REM *** This can't be drap&drop, because arg doesn't begin with ":\"
                    set "isDragAndDrop="
                    %DEBUG_DRAG% echo *** NO DRIVE '!arg!' > CON
                    exit /b
                )
            )
        )
        set "args=!args!!arg! "
    )
    set "args=!args:~,-1!"
)

if not defined problematic (
    set "isDragAndDrop="
    REM echo *** 'problematic = 0' > CON
)

if defined isDragAndDrop (
REM ECHO *** HANDLE isDragAndDrop *** > CON
REM echo *** '!args!' > CON
    REM *** The TWO SPACES between comspec and /c are essential!
    REM *** The AutoRun script detects the recursion call by this difference
    (
        endlocal
        %comspec%  /c ^"%args%"
    )

    REM *** Back from the dragDrop script
    REM *** EXIT to avoid a second call
    exit
)

REM *** This is the path for unproblematic content
REM *** Or it was detected, that this isn't a drap&drop operation
exit /b

:direct_call
if "%~1" == "--install" (
    reg add "HKEY_CURRENT_USER\Software\Microsoft\Command Processor" /v "AutoRun" /t REG_SZ /d "%~f0"
    exit /b
) 

if "%~1" == "--show" (  
    reg query "HKEY_CURRENT_USER\Software\Microsoft\Command Processor" /v AutoRun
    exit /b
)

if "%~1" == "--remove" (
    reg DELETE "HKEY_CURRENT_USER\Software\Microsoft\Command Processor" /v AutoRun /f
)
exit /b

:arg_parser  arg_line
REM *** @TODO: ENDLOCAL all arg-... variables
::: Output arg0, ..., arg and arg#
::: arg0 ... arg contains unquoted arguments
::: an argument that contains only one quote (last character in line) is treated as quoted  arg=" -> arg=, arg.quoted=1
::: arg0.quoted contains 1 if the argument was quoted
::: \ escapes the next character (also inside quotes), can escape delimiters outside quotes, can escape quotes
::: Only \" is replaced to a single quote ", all other \ are unchanged

set "var=%1"
(set^ arg_line=!%2!)
call :strlen arg_len arg_line
set /a %var%_len-=1

set "quoted="
rem set "escapeChar="   --- "Say: \"Hello\" to frank\n"
set /a %var%#=0
set "%var%[0]="
set "%var%.onlySingleSpace=1"
for /L %%I in (0 1 !arg_len!) DO (
    for %%# in (!%var%#!) DO  (
        set "char=!arg_line:~%%I,1!"
        set "isDelim="

        if "!escapeChar!!char!" == ^""" set "quoted=!quoted:~,0!"

        REM echo %%I: "!char!" quote: !quote!
        %= only outside quotes =%
        %= check if char is a delim =%
        if not defined quoted (
            FOR /F "tokens=1,2 delims= " %%D in ("isDelim!char!NO") DO (
                if "%%D" == "isDelim" (
                    set isDelim=1
                    if "!arg_line:~%%I,2!" == "  " (
                        %DEBUG_DRAG% echo ##### NOT onlySingleSpace > CON
                        set "%var%.onlySingleSpace="
                    )
                )
            )
        )

        REM *** Split arguments by not escaped delimiter
        if "!isDelim!,!quoted!,!escapeChar!" == "1,," (
            REM *** Finalize arg, test if arg is quoted
            if defined %var%[%%#] (
                set %var%[%%#].quoted=
                REM echo    #in %%# "!%var%[%%#]:~,1!!%var%[%%#]:~-1!"
                if "!%var%[%%#]:~,1!!%var%[%%#]:~-1!" == """" (
                    if "!%var%[%%#]:~-2,-1!" NEQ "\" (
                        set %var%[%%#].quoted=1
                        set "%var%[%%#]=!%var%[%%#]:~1,-1!"
                    )
                )
                REM * NOT USED HERE * if defined %var%[%%#] (
                REM * NOT USED HERE *   set ^"%var%[%%#]=!%var%[%%#]:"\"="!"
                REM * NOT USED HERE * )
                set /a %var%#+=1
            )
        )

        REM * NOT USED HERE * if defined escapeChar (
        REM * NOT USED HERE *   set "escapeChar="
        REM * NOT USED HERE *   if "!char!" EQU ^""" (
        REM * NOT USED HERE *       REM *** Replace escaped quotes with "\" that can be safely detected and replaced later
        REM * NOT USED HERE *       set "char="\""
        REM * NOT USED HERE *   ) ELSE IF defined isDelim (
        REM * NOT USED HERE *       set "isDelim="
        REM * NOT USED HERE *   ) ELSE (
        REM * NOT USED HERE *       set "char=\!char!"
        REM * NOT USED HERE *   )
        REM * NOT USED HERE * ) ELSE if "!char!" == "\" set "escapeChar=\"

        if defined quoted set "isDelim="

        REM *** Append char to arg
        if "!isDelim!!escapeChar!" == "" (
            set "%var%[%%#]=!%var%[%%#]!!char!"
        )
    )
)

for %%# in (!%var%#!) DO (
    REM *** Last character is \
    if defined escapeChar (
        set "%var%[%%#]=!%var%[%%#]!\"
    )

    REM *** Duplicated code
    REM *** Finalize arg, test if arg is quoted
    if defined %var%[%%#] (
        set %var%[%%#].quoted=
        if "!%var%[%%#]:~,1!!%var%[%%#]:~-1!" == """" (
            if "!%var%[%%#]:~-2,-1!" NEQ "\" (
                set %var%[%%#].quoted=1
                set "%var%[%%#]=!%var%[%%#]:~1,-1!"
            )
        )
        REM * NOT USED HERE * if defined %var%[%%#] (
        REM * NOT USED HERE *   set ^"%var%[%%#]=!%var%[%%#]:"\"="!"
        REM * NOT USED HERE * )
        set /a %var%#+=1
    )
)
REM *** Create a helper variable with name "arg#-1"
set /a tmp=!%var%#!-1
set "%var%#-1=!tmp!"

exit /b
::: detector line %~* *** FATAL ERROR: missing parenthesis or exit /b
:strlen  
(   
    setlocal EnableDelayedExpansion
    (set^ tmp=!%~2!)
    if defined tmp (
        set "len=1"
        for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
            if "!tmp:~%%P,1!" NEQ "" ( 
                set /a "len+=%%P"
                set "tmp=!tmp:~%%P!"
            )
        )
    ) ELSE (
        set len=0
    )
)
( 
    endlocal
    set "%~1=%len%"
    exit /b
)


来源:https://stackoverflow.com/questions/59930635/handling-semi-colon-in-filenames-with-this-drag-and-drop-routine

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!