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
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"
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
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"
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.
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
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
)
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
jeb
----------------------------
#8 13 Jan 2011 17:33
allal
that solved the issue, great job