dragdrop file named with ampersand problem

Microsoft Windows
Post Reply
User avatar
MigrationUser
Posts: 336
Joined: 2021-Jul-12, 1:37 pm
Contact:

dragdrop file named with ampersand problem

Post by MigrationUser »

10 Jan 2011 12:50
allal

a file was dragged and dropped on a batch script
this dragged file contain Ampersand and here what can happen:

Code: Select all

IF NOT [%1]==[] (set testdragged=%1 &goto ampersand_test) else (goto wrk_var)

:ampersand_test
IF NOT EXIST %testdragged% (
     echo no such a file or directory
     what's that??? a file was dragged to a batch as a result nothing exist
     echo no doubt but this dragged file is named by ampersand  
     echo.
     echo filename with ampersand dragged 
     echo AND no space exist in the fullpath 
     echo SO the dragged item will not be quoted automatically
     ECHO.
     echo WHAT A NASTY CMD BUG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


)

:wrk_var
echo no issue was detected and it's whether the filename is not named with ampersand or the fullpath contain space
EXAMPLE :
draggedfile is allal&cdft.txt
fullpath is d:\test\allal&cdft.txt
dragresult is d:\test\allal

output is 'cdft.txt' is not recognized as internal or external command or executable program or a batch file

please is there a way to fix this bug or to make cmd quote automatically any dragged file to a batch script
whether the fullpath CONTAIN SPACE or NOT.

Last edited by allal (12 Jan 2011 13:50)

----------------------------

#2 10 Jan 2011 21:56
jeb


You could use "%~1", the quotes escapes the ampersands and spaces,
the %~1 removes potential quotes around the filename.

Code: Select all

IF NOT "%~1"=="" (set "testdragged=%~1" &goto ampersand_test) else (goto wrk_var)

IF NOT EXIST "%testdragged%" (
...

Last edited by jeb (10 Jan 2011 21:57)

----------------------------

#3 12 Jan 2011 13:42
allal


here is a detailed explanation for the problem:

when you drag a file to a script,the cmd will not give you the chance to put double quotes on the fullpath of the dragged file
cmd automatically uses its default behaviour,so if the file fullpath passed to the batch,script file contain space,cmd will put
double quotes on it otherwise it will not put double quotes on it because the fullpath don't contain space so there is no need
to put double quotes on it unfortunately if the dragged file fullpath contain ampersand putting automatically double quotes
is required for the complete file fullpath to be preserved or the cmd will try to run it as a command preceded by ampersand

test it yourself
example1:

dragging a file in opened cmd shell.
open a cmd prompt and ask for user input and drag a file to cmd shell

1-dragging a fullpath which contain space

Code: Select all

set /p src="C:\Documents and Settings\Administrateur\Bureau\allal&mohfile.txt"
have you noticed the double quotes in the fullpath,i'm not the one who put them
it is how the cmd behave when space are detected.

2-dragging a fullpath which doesn't contain space

Code: Select all

set /p src=d:\allal&mohfile.txt
as you have noticed again no double quotes when dragging allal&mohfile.txt
cmd don't put double quotes when no space are detected in the file passed to it
and if you try to work with this input it will fail because double quotes is required
when ampersand exist in the filename

this example is easy to handle yes you are allowed and have time to do it just put double quotes like that:

Code: Select all

set /p src="d:\allal&mohfile.txt"
example 2:
dragging a file to a closed cmd shell and it's our concern.

and yes there is no way that i know you will be able to have the chance
to put double quotes if the cmd don't do it for you, in our 'ampersand no space
in fullpath' case, when d:\allal&mohfile.txt dragged it will be whether you like or not d:\allal
even if you put double quotes on the parameters as "%1" or "%~1" it will be too late because
as we know the cmd assign passed items as %1,%2,%3 and in this assignement operation the double quote must be put
so here only cmd can do it while assigning passed items to %1,%2,%3 and so on

main cmd operation:
1-if item contain space put double quote else don't .
2-assign %1 to first item,assign second item to %2 ....
yes when d:\allal&mohfile.txt is passed the cmd will not double quote it
after cmd detects the ampersand in filename as a result cmd will assign %1 to d:\allal
and once you begin working with this parametre you will get the error:

Code: Select all

'mohfile.txt'  is not recognized as internal or external command or executable program or a batch file 
 REM you understand now the cmd will run what after the ampersand as command. 
i think this bug is really frustrating unless you know a hack that can solve the issue
dragging and dropping items to a script is really flexible and fast,i prefer it than oppening
the shell and dragging items which will require you to seperate every items manually
or writing every fullpath in the prompt which will take time
dragging and dropping on a closed batch file is really something very useful.

hope this help to understand the issue and hope there is a solution.

Last edited by allal (12 Jan 2011 16:59)

----------------------------

#4 12 Jan 2011 16:35
jeb


Ok, you are right it is a problem of windows, I checked it and see it like you.

But it isn't a problem, the solution is obviously :-)

Code: Select all

@echo off
SETLOCAL EnableDelayedExpansion
set "param1=!cmdcmdline:~0,-1!"
set "param1=!param1:*" =!"
echo Your drag file is #!param1!#
echo ENDE
pause > nul
exit
The code use two tricks
1. Use the cmdcmdline variable to access the complete filename and remove the "CMD /C "blabla.bat" part

2. use EXIT at the end so that the ampersand can't executed any more

hope it helps
jeb

----------------------------

#5 12 Jan 2011 17:09
allal


ok thanks, yes the output was complete
i have never known of the existence of cmdcmdline variable
and if we use exit then we will exit and we can't continue as we have done nothing
actually i just understand nothing but that was helpful indeed

----------------------------

#6 13 Jan 2011 10:38
allal

Code: Select all

@echo off
setlocal ENABLEDELAYEDEXPANSION
set count=0

for %%G IN ("!cmdcmdline!" ) do (
  set item_!count!="%%G"
  set item_1="%%G"
  set /a count+=1
  call echo item_!count!
  echo !item_1!
  pause

)
when i try to work with multiple items the array item_!count! do not
expand correctly instead of expanding to file fullpath it will be expanded to item_1, item_2 , item_3 etc...
whereas creating one variable like set item_1="%%G" will work but it will be overwriten when looping back

please help on how to expand the set item_!count!="%%G" so it will result in a valid array in the end.

Last edited by allal (13 Jan 2011 12:41)

----------------------------

#7 13 Jan 2011 15:07
jeb


Hi allal,

OK the problem is bigger than expected, but it can be solved.

Code: Select all

@echo off
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
  rem Or you can access the parameter with, but this isn't secure with special characters like ampersand
  rem call echo %%item_!count!%%
)

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

exit
hope it helps
jeb

----------------------------

#8 13 Jan 2011 17:33
allal


that solved the issue, great job
Post Reply