While working on my previous question, I faced a similar issue that I was solving initially.
Actually, I spent this month in attempts to create one universal .bat he
You can't solve it with normal percent expansion!
Proof:
The sample argument is "&"&
.
To call a batch file with this argument, you have to escape the second ampersand.
test.bat "&"^&
It's not possible to handle this with normal commands, as you always get one unquoted ampersand.
set arg=%1
set "arg=%1"
set arg=%~1
set "arg=%~1"
Each line will fail with an error message.
Is there any command that will not fail with %1
or %*
?
Yes, REM
can handle them proper.
This works without erros.
REM %1
...
Funny, but how do you have any benefits from using a REM
statement to get the content?
First you have to enable ECHO ON
to see that it really works.
echo on
REM %1
Nice now you see the debug output
c:\temp>REM "&"&
Now you only need to redirect the debug output to a file.
There are many ways that doesn't work.
@echo on
> arg.txt REM %1
( REM %1 ) > arg.txt
call :func > arg.txt
..
:func
REM %1
The call redirections itself works, but in the func itself you can't access the
%1anymore.
FOR` loop
But there is one solution to grab the output, with a
(
@echo on
for %%a in (42) do (
rem %1
)
) > arg.txt
Is it better to store the argument in a file instead of %1
?
Yes, as a file can be read in a safe way independent of the content.
There are still some gotchas left, like /?
, ^
or %%a
in the argument.
But that can all be solved.
@echo off
setlocal DisableDelayedExpansion
set "prompt=X"
setlocal DisableExtensions
(
@echo on
for %%a in (4) do (
rem #%1#
)
) > XY.txt
@echo off
echo x
endlocal
for /F "delims=" %%a in (xy.txt) DO (
set "param=%%a"
)
setlocal EnableDelayedExpansion
set param=!param:~7,-4!
echo param='!param!'
More about the topic at
SO:How to receive even the strangest command line parameters?
SO:Receive multiline arguments
And for Drag&Drop you need an even more complex solution SO:Drag and drop batch file for multiple files?
Edit: Solution for %*
The extensions has to be disabled, else arguments like %a--%~a
will be modified.
But without extensions the %*
expansion doesn't work anymore.
So the extensions are enabled just to expand the %*
but before the FOR
shows the content the extensions will be disabled.
@echo off
setlocal EnableExtensions DisableDelayedexpansion
set "prompt=-"
(
setlocal DisableExtensions
@echo on
for %%a in (%%a) do (
rem # %*#
)
) > args.tmp
@echo off
endlocal
set "args="
for /F "tokens=1* delims=#" %%G in (args.tmp) DO if not defined args set "args=%%H"
setlocal EnableDelayedExpansion
set "args=!args:~1,-4!"
echo('!args!'
This can fetch all arguments in a safe way, but for arguments from a drag&drop operations even this isn't enough, as windows have a bug (design flaw).
A file like Documents&More
can't be fetched this way.