2

I'm not much of a Windows user, but I have need to write a simple .bat script to automate building a folder from a file and a couple of other folders. I want to drag and drop a folder onto the .bat script to execute the script.

The problem is that many of the folder names will have the "^" sign in the name for the folder, and when I drag and drop such folders onto the .bat script the '%1" in the script has the folder name, but the '^' character is stripped out for some reason.

Is there a way to get the literal folder name without losing the '^' characters ?

I'm adding more info with the example. My .bat file is like:

@echo off
echo %~1
mkdir USB
xcopy /s radiantUSB USB
move "%~1" USB\
echo "FINISHED"
@pause

and the name of the folder I am dropping on the .bat file is:

Duck^Donald^Quack

and the path that it is extracting is:

C:\Users\sscotti\Desktop\DuckDonaldQuack

The '^' is removed and move "%~1" USB\ fails because it the path to the folder to move is incorrect.

SScotti
  • 2,158
  • 4
  • 23
  • 41
  • Are you sure that `%1` is absent of that character? For instance, if you `Echo` it then the `Echo` command itself will remove it... How have you determined that the drag and drop has removed it? Do any of your folder names, by any chance, have multiple carets in succession? and do any other possibly problematic characters exist in your folder names? – Compo Oct 18 '22 at 19:05
  • Dragging-and-dropping onto batch files is problematic with several characters, because paths become quoted only when they contain spaces, but other problematic characters (like `^` and `,`, `;`, `&`, e. g.) do not cause quotation. So even if you read arguments by `"%~1"` in your script, which is recommended, error will arise. Type `echo(%*` (with delayed expansion **dis**abled) in your script to maybe see the unedited argument string… – aschipfl Oct 19 '22 at 06:10

2 Answers2

1

You can't fetch a single caret ^ with %1 nor %*, if it isn't quoted. That's because, cmd.exe use the caret as an escape character and remove it from the arguments.

But in the hidden variable cmdcmdline all characters are present.

This works with nearly all special characters.
Tested with Donald^Duck, Dagobert ^Duck, Cat&Dog

It only fails for filenames like Cat&dog(). To be bullet proof, you need an additional AutoRun batch file, that fixes the drag&drop handling.

@echo off
setlocal DisableDelayedExpansion
set index=0
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:*" =!"
echo params: !params!
rem Split the parameters on spaces but respect the quotes
for %%G IN (!params!) do (
    for %%# in (!index!) do (
        endlocal
        set /a index+=1
        set "item_%%#=%%~G"
        setlocal EnableDelayedExpansion
    )
)

set /a max=index-1

rem list the parameters
for /L %%n in (0,1,!max!) DO (
  echo %%n #!item_%%n!#
)
pause

REM ** The exit is important, so the cmd.exe doesn't try to execute commands after ampersands
exit
jeb
  • 78,592
  • 17
  • 171
  • 225
  • That is helpful: echo %CMDCMDLINE% returns: C:\Windows\system32\cmd.exe /c ""C:\Users\sscotti\Desktop\test.bat" C:\Users\sscotti\Desktop\Duck^Donald^Quack". Is there a simpler way to extract the target file from that in the .bat using %CMDCMDLINE% ? – SScotti Oct 19 '22 at 16:27
  • @SScotti The example shows how to split the line into items. Btw. `echo %cmdcmdline%` works only if there is no space in the filename – jeb Oct 19 '22 at 16:30
0

Use %~1, not %1.

Dealing with the special meaning of characters within your batch is another question. Since you don't show us your batch, just how long is a piece of string?

Here's my test batch

@ECHO OFF
ECHO ----%~nx0--%*
SETLOCAL

ECHO "%1"
ECHO "%~1"
ECHO "%*"
pause
GOTO :EOF

And the test filename was U:\Test space^caret&ampersand!exclam%percent.bat

Here's the result

----qcifn.bat--"U:\Test space^caret&ampersand!exclam%percent.bat"
""U:\Test spacecaret
'ampersand!exclam%percent.bat""' is not recognized as an internal or external command,
operable program or batch file.
"U:\Test space^caret&ampersand!exclam%percent.bat"
""U:\Test spacecaret
'ampersand!exclam%percent.bat""' is not recognized as an internal or external command,
operable program or batch file.
Magoo
  • 77,302
  • 8
  • 62
  • 84
  • Just to mention that when a file or directory is dragged and dropped, essentially from Windows Explorer, the dropped item is generally doublequoted where necessary. Therefore `%1` is often sufficient, depending upon how it is processed beyond that. – Compo Oct 18 '22 at 20:53
  • 1
    @Compo It's only quoted when the filename contains spaces, not when it is necessary! This results into many nearly unsolvable problems – jeb Oct 18 '22 at 21:43
  • @jeb, I'm aware of that, perhaps I did not make that clear enough. My comment however was aimed more in response to `%1` vs `%~1`, (as used in the opening of the answer body text above), which essentially deals only with the enclosing doublequotes, `"%~1"` is clearly a better option, for non space problematic characters, when used with the `Echo` command. – Compo Oct 18 '22 at 23:10