How do I get Windows cmd FOR to 'play-nice' with drag-n-drop

▼魔方 西西 提交于 2019-12-02 05:18:51
MC ND

Getting a batch file handle dropped files can be sometimes difficult. Any dragged file with spaces in its name will be quoted, but a file with special characters (&) but without spaces will not be quoted. This will lead to problems with the parser handling the arguments to the file using %*.

But taking the code from jeb' answer and polished by @dbenham to solve the problem of "Pretty print windows %path% variable" (thank you both), and retrieving the arguments from %* only when called from command line (where arguments "should" be well formed) or from %cmdcmdline% (that hold the command line used to start the current cmd instance) when dropped, we can do something like

@echo off
    setlocal enableextensions disabledelayedexpansion
    set "var="

    rem Determine call origin
    setlocal enabledelayedexpansion
    call :detectDrop !cmdcmdline!
    endlocal
    if not errorlevel 1 goto :dropped

:commandLine
    rem Invoked from command line
    set "dropped="
    if "%~1"=="" goto done
    set var=%*
    set "var=%var:"=""%"
    goto :process

:dropped
    rem Invoked from explorer
    set "dropped=1"
    set "var=%cmdcmdline:"=""%"
    set "var=%var:*/c """"=%"
    set "var=%var:*"" =%"
    set "var=%var:~0,-2%"

:process
    if not defined var goto :done

    rem Adapted from dbenham's answer at [https://stackoverflow.com/a/7940444/2861476]

    set "var=%var:^=^^%"
    set "var=%var:&=^&%"
    set "var=%var:|=^|%"
    set "var=%var:<=^<%"
    set "var=%var:>=^>%"
    set "var=%var: =^ ^ %"
    set var=%var:""="%
    set "var=%var:"=""Q%"
    set "var=%var:  ="S"S%"
    set "var=%var:^ ^ = %"
    set "var=%var:""="%"
    setlocal enabledelayedexpansion
    set "var=!var:"Q=!"
    for %%a in ("!var:"S"S=" "!") do ( 
        if "!!"=="" endlocal

        rem Here we have a reference to the passed/dropped element
        if %%a neq "" echo "%%~fa"

    )
    goto :done

:detectDrop cmdcmdline
    if /i "%~1"=="%comspec%" if /i "%~2"=="/c" exit /b 0
    exit /b 1

:done    
    if defined dropped ( pause & exit )

note: sorry, not thoroughly tested. Maybe there is some case that will make it fail.

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