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

后端 未结 1 362
慢半拍i
慢半拍i 2021-01-24 13:40

I had a very straight forward little batch script. The design outline is simple enough ... I want to touch every file \'dropped\'.

  1. There is a Windows sho
相关标签:
1条回答
  • 2021-01-24 14:24

    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.

    0 讨论(0)
提交回复
热议问题