how to get batch file parameters from Nth position on? - windows

Further to How to Pass Command Line Parameters in batch file how does one get the rest of the parameters with specifying them exactly? I don't want to use SHIFT because I don't know how many parameters there might be and would like to avoid counting them, if I can.
For example, given this batch file:
#echo off
set par1=%1
set par2=%2
set par3=%3
set therest=%???
echo the script is %0
echo Parameter 1 is %par1%
echo Parameter 2 is %par2%
echo Parameter 3 is %par3%
echo and the rest are %therest%
Running mybatch opt1 opt2 opt3 opt4 opt5 ...opt20 would yield:
the script is mybatch
Parameter 1 is opt1
Parameter 2 is opt2
Parameter 3 is opt3
and the rest are opt4 opt5 ...opt20
I know %* gives all the parameters, but I don't wan't the first three (for example).

Here's how you can do it without using SHIFT:
#echo off
for /f "tokens=1-3*" %%a in ("%*") do (
set par1=%%a
set par2=%%b
set par3=%%c
set therest=%%d
)
echo the script is %0
echo Parameter 1 is %par1%
echo Parameter 2 is %par2%
echo Parameter 3 is %par3%
echo and the rest are %therest%

#echo off
setlocal enabledelayedexpansion
set therest=;;;;;%*
set therest=!therest:;;;;;%1 %2 %3 =!
echo the script is %0
echo Parameter 1 is %1
echo Parameter 2 is %2
echo Parameter 3 is %3
echo and the rest are: %therest%
This works with quoted arguments and with arguments that have equal signs or commas, as long as first three arguments didn't have these special delimiter chars.
Sample output:
test_args.bat "1 1 1" 2 3 --a=b "x y z"
Parameter 1 is "1 1 1"
Parameter 2 is 2
Parameter 3 is 3
and the rest are: --a=b "x y z"
This works by replacing %1 %2 %3 in original command line %*. The first five semicolons are there just to make sure that only the first occurrence of these %1 %2 %3 is replaced.

The following code uses shift, but it avoids to parse the command line using for and lets the command line interpreter do this job (regard that for does not parse double-quotes properly, for instance argument set A B" "C is interpreted as 3 arguments A, B", "C by for, but as 2 arguments A, B" "C by the interpreter; this behaviour prevents quoted path arguments like "C:\Program Files\" from being handled correctly):
#echo off
set "par1=%1" & shift /1
set "par2=%1" & shift /1
set "par3=%1" & shift /1
set therest=
set delim=
:REPEAT
if "%1"=="" goto :UNTIL
set "therest=%therest%%delim%%1"
set "delim= "
shift /1
goto :REPEAT
:UNTIL
echo the script is "%0"
echo Parameter 1 is "%par1%"
echo Parameter 2 is "%par2%"
echo Parameter 3 is "%par3%"
echo and the rest are "%therest%"
rem.the additional double-quotes in the above echoes^
are intended to visualise potential whitespaces
The remaining arguments in %therest% might not look like the way they were originally concerning the delimiters (remember the command line interpreter also treats TABs, ,, ;, = as delimiters as well as all combinations), because all delimiters are replaced by a single space here. However, when passing %therest% to some other command or batch file, it will be parsed correctly.
The only limitation I encountered so far applies to arguments containing the caret character ^. Other limitations (related to <, >, |, &, ") apply to the command line interpreter itself.

#ECHO OFF
SET REST=
::# Guess you want 3rd and on.
CALL :SUBPUSH 3 %*
::# ':~1' here is merely to drop leading space.
ECHO REST=%REST:~1%
GOTO :EOF
:SUBPUSH
SET /A LAST=%1-1
SHIFT
::# Let's throw the first two away.
FOR /L %%z in (1,1,%LAST%) do (
SHIFT
)
:aloop
SET PAR=%~1
IF "x%PAR%" == "x" (
GOTO :EOF
)
ECHO PAR=%PAR%
SET REST=%REST% "%PAR%"
SHIFT
GOTO aloop
GOTO :EOF
I like to use subroutines instead of EnableDelayedExpansion. Above is extract from my dir/file pattern processing batch. Don't say this cannot handle arguments with =, but at least can do quoted path with spaces, and wildcards.

One more alternative :-)
some of the other answers did not deal with quotes, or with extra spaces between parameters. Disclaimer: I have not tested this extremely well.
This is all just a workaround for %* not being updated after a shift ugg!
I implemented it as a POP starting from the technique by #Pavel-P.
It relies on the batch parser to remove extra spaces
It depends on a global variable 'Params'
~ removes quotes -- leaving it up to you to re-quote as desired. Remove the ~ if you don't want that.
:PopFirstParam
#set varname=%~1
#set %varname%=%~2
#rem #echo %varname% = '!%varname%!'
#if '%3' equ '' set Params=&goto :eof
#call :popone %Params%
#goto :eof
:popone
#set Params=;;;%*
#set Params=!Params:;;;%1 =!
#goto :eof
Usage:
#setlocal enabledelayedexpansion
#set Params=%*
#call :PopFirstParam P1 %Params%
#call :PopFirstParam P2 %Params%
#call :PopFirstParam P3 %Params%
#call :PopFirstParam P4 %Params%
#rem etc . . .
Specifically I use it to optionally run commands asynchronously:
#setlocal enabledelayedexpansion
#rem set variables that decide what to be run . . . .
#call :RunIfDefined doNum1 "Title 1" mycmd1.exe some "params" here
#call :RunIfDefined doNum2 "MyTitle 2" mylongcmd2.exe some "params" here
#call :RunIfDefined doNum3 "Long Title 3" mycmd3.exe some "params" here
#goto :eof
:RunIfDefined
#set Params=%*
#call :PopFirstParam DefineCheck %Params%
#if not defined %DefineCheck% goto :eof
#call :PopFirstParam WindowTitle %Params%
#call :PopFirstParam Command %Params%
#rem %Params% should now be the remaining params (I don't care about spaces here)
#echo start "%WindowTitle%" "%Command%" %Params%
#start "%WindowTitle%" "%Command%" %Params%
#goto :eof
C:\test> set doNum1=yes
C:\test> set doNum3=yes
C:\test> call dothings.bat
start "Title 1" "mycmd1.exe" some "params" here
start "Long Title 3" "mycmd3.exe" some "params" here
too bad DOS doesn't have a #include

Related

Is it possible to pass unprocessed parameters in a CALL command?

Take for instance the following example files a.bat and b.bat:
a.bat
#echo off
echo in a: %*
call b %*
b.bat
#echo off
echo in b: %*
and consider this invocation and output:
c:\>a 1 2 3 %% %%%%
in a: 1 2 3 %% %%%%
in b: 1 2 3 % %%
Is there a way to pass the parameters from the command line to b.bat such that it sees the same parameters that a.bat saw? Is it possible to prevent the system from processing the parameters, i.e. removing the escaping % character?
Because this looks so simple, I assume that I must have missed something, but from what you've posted, this looks like all you should need:
C:\a.cmd
#Echo In %~n0: %*
#Call "b.cmd" %%*
C:\b.cmd
#Echo In %~n0: %*
Example:
C:\>a 1 2 3 %% %%%%
In a: 1 2 3 %% %%%%
In b: 1 2 3 %% %%%%
Yes you can do that, but instead of removing a character, you need to add more escape characters.
But to solve it for any (or at least most) parameter you need to escape all problematic characters &|<>"^
This can handle even parameters like:
a.bat Bob^&Alice say: "Cat & dog"
#echo off
REM *** Fetch all arguments
goto :init :initCallBack
:initCallBack
REM *** Prepare the arguments for a secure CALL
call :prepareArgument allArgs arg
REM *** b.bat will see the same arguments like this file
call b.bat %%allArgs%%
exit /b
:init
::: Get all arguments with minimal interference
::: Only linefeeds and carriage returns can't be fetched
::: Only linefeeds can create a syntax error
::: return arg=All arguments, arg1..arg<n>=A single argument
setlocal EnableDelayedExpansion
set "argCnt="
:getArgs
>"%temp%\getArg.txt" <"%temp%\getArg.txt" (
setlocal DisableExtensions
(set prompt=#)
echo on
if defined argCnt (
for %%a in (%%a) do rem . %1.
) ELSE (
for %%a in (%%a) do rem . %*.
)
echo off
endlocal
set /p "arg%argCnt%="
set /p "arg%argCnt%="
set "arg%argCnt%=!arg%argCnt%:~7,-2!"
if defined arg%argCnt% (
if defined argCnt (
shift /1
)
set /a argCnt+=1
goto :getArgs
) else set /a argCnt-=1
)
del "%temp%\getArg.txt"
goto :initCallBack
:prepareArgument
::: Convert a string, so it can be used as an argument for calling a program
set "var=!%~2!"
if defined var (
set "var=!var:^=^^!"
set "var=!var:"=^^"!"
set "var=!var:&=^&!"
set "var=!var:|=^|!"
set "var=!var:>=^>!"
set "var=!var:<=^<!"
)
set "%~1=!var!"
exit /b

Windows Batch, passing arguments with spaces

I'm busy writing a Windows batch script and I'm having some problem with arguments.
My batch script is the following
#echo off
setlocal EnableDelayedExpansion
:: RETRIEVE ARGS WITH SPACES
set VAR01=%~1
set VAR02=%~2
set VAR03=%~3
:: CONFIRM IT WORKED
echo %VAR01%
echo %VAR02%
echo %VAR03%
endlocal
exit /b
And I am trying to pass it arguments that include spaces.
run_batch.bat "arg var 01" "arg var 02" "arg var 03"
But when it runs I am getting the output
arg var 01
ECHO is off
ECHO is off
Why is it only working correctly for the first argument and how can it be fixed?
NOTE
There was never anything wrong with the code, it seems there were invisible special characters that there causing issues. Must have been the text editor or something along those lines. How do I remove this question?
This should work:
#echo off
setlocal EnableDelayedExpansion
:: RETRIEVE ARGS WITH SPACES
set VAR01=%~1
set VAR02=%~2
set VAR03=%~3
:: CONFIRM IT WORKED
echo %VAR01%
echo %VAR02%
echo %VAR03%
endlocal
exit /b
The wrong part was:
set VAR01=%~1
set VAR01=%~2
set VAR01=%~3
but should be:
set VAR01=%~1
set VAR02=%~2
set VAR03=%~3
A small example script for your perusal.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
REM EXIT IF NO ARGS RECEIVED
IF "%~1"=="" EXIT
REM SET MINIMUM NUMBER OF ARGS
SET "i=1"
REM RETRIEVE ALL ARGS
:ARGS
SET "VAR0%i%=%~1"
SHIFT
IF NOT "%~1"=="" (
SET/A i+=1
GOTO :ARGS
)
REM INFORM NUMBER OF ARGS
CLS
ECHO=THERE WERE %i% ARGS
REM CONFIRM IT WORKED
ECHO=
SET VAR0
REM ALTERNATIVE CONFIRMATION
ECHO=
FOR /L %%A IN (1,1,%i%) DO IF DEFINED VAR0%%A ECHO=!VAR0%%A!
TIMEOUT -1
ENDLOCAL
EXIT
I think there was no problem aside from a typo. A quite tricky way to show the args and put them to numbered vars I learned from DosTips.org (but can't find the exact link) is:
:: Expand-Args.cmd
#Echo off
Set Args=,1=%~1,2=%~2,3=%~3,4=%~4,5=%~5,6=%~6,7=%~7,8=%~8,9=%~9
Set "Args=%*%Args:,="&Set "Arg%"
Set Arg
The batch will have this output run with:
Expand-Args one "2 2" three 4 five 6 "7 7" 8 9
Arg1=one
Arg2=2 2
Arg3=three
Arg4=4
Arg5=five
Arg6=6
Arg7=7 7
Arg8=8
Arg9=9
Args=one "2 2" three 4 five 6 "7 7" 8 9
Edit To not interfere with content in double quotes the delimiter comma might be replaced with an uncommon char like ALT+0127

Echo a long string with specified start column for new lines

I am writing a small console application. This app should print a help when -h is passed. This is what I'm trying to get:
Program that prints help.
Usage:
prg [OPTIONS]
Options:
-h - print help.
-x - some very very very very very very very very very very very very very very
very very very very long parameter description.
-y - another very very very very very very very very very very very very very
very very very very long parameter description.
I'm using echo. -x - {long description here} to print parameter description. And of course when the string is too long it is printed like this:
-x - some very very very very very very very very very very very very
very very very very long parameter description.
So the question is how can I print a long string with something like left border specified?
#ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION
for /f %%I in ('powershell ^(Get-Host^).UI.RawUI.WindowSize.width') do set width=%%I
SET "spaces= "
:splp
IF "!spaces:~%width%!"=="" SET spaces=%spaces%%spaces%&GOTO splp
CALL :display 0 "Program that prints help."
CALL :display 0 "Usage:"
CALL :display 2 "prg [OPTIONS]"
CALL :display 0
CALL :display 0 "Options:"
CALL :display 2 "-x" 5 "- some very very very very very very very very very very very very very very very very very very long parameter description."
CALL :display 2 "-y" 5 "- another very very very very very very very very very very very very very very very very very long parameter description."
GOTO :EOF
:display
SET "remainder="
SET "line=!spaces:~0,%1!"
IF "%~2"=="" GOTO write
IF "%3"=="" SET "line=%line%%~2"&GOTO write
SET /a indent=%1+%3
SET "remainder=%~2%spaces%"
SET "line=%line%!remainder:~0,%3!
SET "remainder=%~4"
:remainlp
SET /a eol=width-indent-1
:seteollp
SET "eolchar=!remainder:~%eol%,1!"
IF NOT DEFINED eolchar SET "line=%line%%remainder%"&set "remainder="&goto write
IF NOT "%eolchar%"==" " set /a eol-=1&GOTO seteollp
SET "line=%line%!remainder:~0,%eol%!
SET /a eol+=1
set "remainder=!remainder:~%eol%!"
:write
ECHO(%line%
IF NOT DEFINED remainder GOTO :EOF
SET "line=!spaces:~0,%indent%!"
GOTO remainlp
I'll claim no originality for the magic powershell line - it came from Rojo's response here
Have you tried using tabs?
For example:
echo.^ -x - some very very very very very very very very very very
echo.^ ^ very very very very very very very
echo.^ ^ very long parameter description.
I've used the '^' character to show where the tabs are and had to split the message over a few lines to stop the word wrapping.
Here is the script I just tried (option x uses tabs and option y does not)
#echo OFF
echo. Usage:
echo. prg [OPTIONS]
echo.
echo. Options:
echo. -h - print help.
echo. -x - some very very very very very very very very very very
echo. very very very very very very very
echo. very long parameter description.
echo. -y - another very very very very very very very very very very very very very
echo. very very very very long parameter description.
And I get the following output (option x uses tabs and option y does not)
C:\Temp>usage.bat
Usage:
prg [OPTIONS]
Options:
-h - print help.
-x - some very very very very very very very very very very
very very very very very very very
very long parameter description.
-y - another very very very very very very very very very very very
very very
very very very very long parameter description.
echo off
setlocal enabledelayedexpansion
set "textx=some very very very very very very very very very very very very very very very very very very long parameter description."
REM find screen widht (subtract 8 for a leading tab and two for a right "border" :
for /f "tokens=2 delims=: " %%i in ('mode^|find "Columns"') do set /a colums=%%i-10
call :wrap "-x" "%textx%"
call :wrap "-y" "another quite quite quite quite quite quite quite quite quite quite quite quite quite quite quite quite quite long parameter description."
exit /b
:wrap <option> <text>
set "text=%~2"
set /p ".=%~1"<nul
for /l %%i in (0,%colums%,1000) do echo. !text:~%%i,%colums%!|findstr ".."
goto :eof
NOTE: there is a between the echo. and !text....
You may have to replace Columns in find "Columns" with the correct string (it's language dependent)
I subtracted 10 from the screen width: 8 for the leading and two to end the line two chars before the windows ends.
1000 is the max length of the string. Adapt as needed. (the higher the value, the slower the output)
|findstr ".." supresses the output of empty lines
This has a few disadvantages:
there is no space in front of -x (set does not support it)
It will wrap at the end of the line even if it's in the middle of a word. Doing a "word wrap" could be done, but with a lot more code.
It has problems with special chars (for example &, !, |)

How to get the rest of arguments in windows batch file?

I know I can get first argument with %0, second with %1, and so on.. And I can also get all arguments with %*.
Can I get all arguments from the second arguments? For example, if I run
foo.bat bar1 bar2 bar3 bar4
How can I get only bar2 bar3 bar4?
#ECHO OFF
SETLOCAL
SET allargs=%*
IF NOT DEFINED allargs echo no args provided&GOTO :EOF
SET arg1=%1
CALL SET someargs=%%allargs:*%1=%%
ECHO allargs %allargs%
ECHO arg1 %arg1%
ECHO someargs %someargs%
This will leave SOMEARGS with at least one leading separator (if it is set)
With SHIFT command. But with every shift you'll lose the first.
This will not change the %* but you'll be able to get all argument ,but the first:
#echo off
shift
set "arg_line= "
:parse_args
if "%~1" NEQ "" (
arg_line=%argline% "%~1"
goto :parse_args
)
now you'll have all arguments but the first stored in %arg_line%
You need to use SHIFT. It moves the apparent position of the parameters, then %* will get all parameters from the position shifted to. You should get the first parameters before using SHIFT.
More information on SHIFT.

Batch files - number of command line arguments

Just converting some shell scripts into batch files and there is one thing I can't seem to find...and that is a simple count of the number of command line arguments.
eg. if you have:
myapp foo bar
In Shell:
$# -> 2
$* -> foo bar
$0 -> myapp
$1 -> foo
$2 -> bar
In batch
?? -> 2 <---- what command?!
%* -> foo bar
%0 -> myapp
%1 -> foo
%2 -> bar
So I've looked around, and either I'm looking in the wrong spot or I'm blind, but I can't seem to find a way to get a count of number of command line arguments passed in.
Is there a command similar to shell's "$#" for batch files?
ps. the closest i've found is to iterate through the %1s and use 'shift', but I need to refernece %1,%2 etc later in the script so that's no good.
Googling a bit gives you the following result from wikibooks:
set argC=0
for %%x in (%*) do Set /A argC+=1
echo %argC%
Seems like cmd.exe has evolved a bit from the old DOS days :)
You tend to handle number of arguments with this sort of logic:
IF "%1"=="" GOTO HAVE_0
IF "%2"=="" GOTO HAVE_1
IF "%3"=="" GOTO HAVE_2
etc.
If you have more than 9 arguments then you are screwed with this approach though. There are various hacks for creating counters which you can find here, but be warned these are not for the faint hearted.
The function :getargc below may be what you're looking for.
#echo off
setlocal enableextensions enabledelayedexpansion
call :getargc argc %*
echo Count is %argc%
echo Args are %*
endlocal
goto :eof
:getargc
set getargc_v0=%1
set /a "%getargc_v0% = 0"
:getargc_l0
if not x%2x==xx (
shift
set /a "%getargc_v0% = %getargc_v0% + 1"
goto :getargc_l0
)
set getargc_v0=
goto :eof
It basically iterates once over the list (which is local to the function so the shifts won't affect the list back in the main program), counting them until it runs out.
It also uses a nifty trick, passing the name of the return variable to be set by the function.
The main program just illustrates how to call it and echos the arguments afterwards to ensure that they're untouched:
C:\Here> xx.cmd 1 2 3 4 5
Count is 5
Args are 1 2 3 4 5
C:\Here> xx.cmd 1 2 3 4 5 6 7 8 9 10 11
Count is 11
Args are 1 2 3 4 5 6 7 8 9 10 11
C:\Here> xx.cmd 1
Count is 1
Args are 1
C:\Here> xx.cmd
Count is 0
Args are
C:\Here> xx.cmd 1 2 "3 4 5"
Count is 3
Args are 1 2 "3 4 5"
Try this:
SET /A ARGS_COUNT=0
FOR %%A in (%*) DO SET /A ARGS_COUNT+=1
ECHO %ARGS_COUNT%
If the number of arguments should be an exact number (less or equal to 9), then this is a simple way to check it:
if "%2" == "" goto args_count_wrong
if "%3" == "" goto args_count_ok
:args_count_wrong
echo I need exactly two command line arguments
exit /b 1
:args_count_ok
Avoids using either shift or a for cycle at the cost of size and readability.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set /a arg_idx=1
set "curr_arg_value="
:loop1
if !arg_idx! GTR 9 goto :done
set curr_arg_label=%%!arg_idx!
call :get_value curr_arg_value !curr_arg_label!
if defined curr_arg_value (
echo/!curr_arg_label!: !curr_arg_value!
set /a arg_idx+=1
goto :loop1
)
:done
set /a cnt=!arg_idx!-1
echo/argument count: !cnt!
endlocal
goto :eof
:get_value
(
set %1=%2
)
Output:
count_cmdline_args.bat testing more_testing arg3 another_arg
%1: testing
%2: more_testing
%3: arg3
%4: another_arg
argument count: 4
EDIT: The "trick" used here involves:
Constructing a string that represents a currently evaluated command-line argument variable (i.e. "%1", "%2" etc.) using a string that contains a percent character (%%) and a counter variable arg_idx on each loop iteration.
Storing that string into a variable curr_arg_label.
Passing both that string (!curr_arg_label!) and a return variable's name (curr_arg_value) to a primitive subprogram get_value.
In the subprogram its first argument's (%1) value is used on the left side of assignment (set) and its second argument's (%2) value on the right. However, when the second subprogram's argument is passed it is resolved into value of the main program's command-line argument by the command interpreter. That is, what is passed is not, for example, "%4" but whatever value the fourth command-line argument variable holds ("another_arg" in the sample usage).
Then the variable given to the subprogram as return variable (curr_arg_value) is tested for being undefined, which would happen if currently evaluated command-line argument is absent. Initially this was a comparison of the return variable's value wrapped in square brackets to empty square brackets (which is the only way I know of testing program or subprogram arguments which may contain quotes and was an overlooked leftover from trial-and-error phase) but was since fixed to how it is now.
A reasonably robust solution is to delegate counting to a subroutine invoked with call; the subroutine uses goto statements to emulate a loop in which shift is used to consume the (subroutine-only) arguments iteratively:
#echo off
setlocal
:: Call the argument-counting subroutine with all arguments received,
:: without interfering with the ability to reference the arguments
:: with %1, ... later.
:: NOTE: See comments re /? below.
call :count_args %* >NUL || (echo Usage: ... & exit /b 0)
:: Print the result.
echo %ReturnValue% argument(s) received.
:: Exit the batch file.
exit /b
:: Subroutine that counts the arguments given.
:: Returns the count in %ReturnValue%
:count_args
set /a ReturnValue = 0
:count_args_for
if %1.==. goto :eof
set /a ReturnValue += 1
shift
goto count_args_for
Limitations:
/? among the arguments - except if passed as "/?" - is not supported, because call invariably interprets it as a request to show its command-line help.
The code above detects this case (curiously, call signals failure via its exit code after showing its help) and interprets this case as wanting to show the current batch file's help instead of counting arguments.
Arguments with metacharacters (special characters) are supported, if enclosed in "..." (as is typical), but character-individual ^-escaping in an unquoted argument does not work (because the ^ is already stripped by the time the batch file sees the arguments, and expanding %* then causes the metacharacters to act as such):
:: OK - arguments with special chars. are "..."-enclosed.
:: -> "3 argument(s) received."
test.cmd hi "you & me" "a<b"
:: !! FAILS
:: The last argument uses character-individual ^-escaping.
:: -> error "The system cannot find the file specified."
test.cmd hi "you & me" a^<b
A syntactically invalid argument list is not supported (which is arguably not a problem):
:: !! FAILS
:: Syntactically invalid argument list
:: -> error "The syntax of the command is incorrect."
test.cmd a"
The last answer was two years ago now, but I needed a version for more than nine command line arguments. May be another one also does...
#echo off
setlocal
set argc_=1
set arg0_=%0
set argv_=
:_LOOP
set arg_=%1
if defined arg_ (
set arg%argc_%_=%1
set argv_=%argv_% %1
set /a argc_+=1
shift
goto _LOOP
)
::dont count arg0
set /a argc_-=1
echo %argc_% arg(s)
for /L %%i in (0,1,%argc_%) do (
call :_SHOW_ARG arg%%i_ %%arg%%i_%%
)
echo converted to local args
call :_LIST_ARGS %argv_%
exit /b
:_LIST_ARGS
setlocal
set argc_=0
echo arg0=%0
:_LOOP_LIST_ARGS
set arg_=%1
if not defined arg_ exit /b
set /a argc_+=1
call :_SHOW_ARG arg%argc_% %1
shift
goto _LOOP_LIST_ARGS
:_SHOW_ARG
echo %1=%2
exit /b
The solution is the first 19 lines and converts all arguments to variables in a c-like style. All other stuff just probes the result and shows conversion to local args. You can reference arguments by index in any function.

Resources