14

How can I pass more than nine parameters to bach file.
I tried another SO question How do you utilize more than 9 arguments when calling a label in a CMD batch-script? but not working for me.

I am trying to give the runtime values of a url kept inside batch.
My batch:

start iexplore http://example.com?firstName=%1^&middleName=%2^&lastName=%3^&country=%4^&address=%5^&address2=%6^&address3=%7^&mobileNo=%8^&landlineNo=%9SHIFT SHIFT SHIFT SHIFT SHIFT SHIFT SHIFT SHIFT ^&emailAddress=%1^&hobby1=%2^&hobby2=%3^&hobby3=%4^&hobby4=%5^&hobby5=%6

When using It is taking the previous values of %1, %2, %3,.....etc and the values of 10th,11th,12th.... parameters

Please help !

Community
  • 1
  • 1
iAmLearning
  • 1,153
  • 3
  • 15
  • 28
  • When your looking at that many parameters, would it possibly be better to read from a well formatted configuration file instead? Only asking in case you hadn't thought of it yet. – TheOneWhoPrograms Feb 11 '14 at 06:39
  • @TheOneWhoPrograms... I have to pass it from java to batch and no other way...thanks – iAmLearning Feb 11 '14 at 06:48
  • ...can store into file from java, then read in from batch, but I guess thats inefficient... good luck with the answer! Will give +1 for a good question. – TheOneWhoPrograms Feb 11 '14 at 06:50

11 Answers11

12

save the first nine args in a variable. THEN call shift multiple times and only then use the rest:

set "v=http://example.com?firstName=%1&middleName=%2&lastName=%3&country=%4&address=%5&address2=%6&address3=%7&mobileNo=%8&landlineNo=%9"
shift
shift
shift
shift
shift
shift
shift
shift
shift
start iexplore %v%&emailAddress=%1&hobby1=%2&hobby2=%3&hobby3=%4&hobby4=%5&hobby5=%6
basin
  • 3,949
  • 2
  • 27
  • 63
  • @Stephan `shift /n` means that it should start at the nth arguments, i.e. don't shift the argments before _n_. `shift /9` is invalid and would have no effect anyway. http://technet.microsoft.com/en-us/library/bb491002.aspx – kapex Feb 11 '14 at 10:49
  • how can I pass blank....i.e., the value of %6="" or " "......if I pass using "" or " ", it doesn't detect the value and takes the next one as the value of %6 – iAmLearning Feb 11 '14 at 13:54
6

Here's an even easier solution that assumes you merely want to pass the values to another program. This example allows passing up to 27 parameters to zip...

@echo OFF
set ZipArgs=%1 %2 %3 %4 %5 %6 %7 %8 %9
for /L %%i in (0,1,8) do @shift
set ZipArgs=%ZipArgs% %1 %2 %3 %4 %5 %6 %7 %8 %9
for /L %%i in (0,1,8) do @shift
set ZipArgs=%ZipArgs% %1 %2 %3 %4 %5 %6 %7 %8 %9
"C:\Program Files\WinZip\wzzip.exe" %ZipArgs%

The first line merely turns off echoing each line to the screen. The lines that start with set ZipArgs build the environment variable ZipArgs with the next 9 parameters from the command line. The "for" lines use the SHIFT command to discard the first 9 parameters bringing the next 9 "up front". The last line executes zip passing to it the assembled parameter values.

You could complicate things by adding code to check for the number of parameters on the command line and act appropriately, but this does the trick just fine for me.

Floern
  • 33,559
  • 24
  • 104
  • 119
DinosaurCoder
  • 61
  • 1
  • 2
4

Here is a simple answer: shift is the key and then loop values and assign them into variables. setup counter to indicate which variable is each parameter.

Example gets alphabets into batch file and sets them into arg1, arg2 etc variables.

batchfile test.bat example:

@echo off

set /a counter=1
:ARGLBEG
if "%1"=="" goto ARGLEND
set arg%counter%=%1
goto ARGNEXT 

:ARGNEXT
shift
set /a counter=%counter%+1
goto ARGLBEG

:ARGLEND
echo "List values."
set arg

echo "Just one value, arg9."
echo %arg9%
goto end

:end

How to use test.bat and how results looks:

test.bat A B c d e F G H i J k L M N O P Q R S t u v x y z

Results.

"List values."
arg1=A
arg10=J
arg11=k
arg12=L
arg13=M
arg14=N
arg15=O
arg16=P
arg17=Q
arg18=R
arg19=S
arg2=B
arg20=t
arg21=u
arg22=v
arg23=x
arg24=y
arg25=z
arg3=c
arg4=d
arg5=e
arg6=F
arg7=G
arg8=H
arg9=i
"Just one value, arg9."
i
AHu
  • 41
  • 1
  • This is the best solution I have found yet since it allows for an arbitrary number of arguments to be passed, and then saved to be used later. Thanks! – Gigamosh57 Aug 15 '23 at 16:02
2

Use %*. Command Line arguments (Parameters)

People who looking for how to passthrough any number of params to an executable:

@ECHO OFF
SET "EXECUTABLE=C:\PATH\TO\MY\EXECUTABLE.EXE"
CALL %EXECUTABLE% %*

Answering the question (openurl.bat):

@ECHO OFF
SETLOCAL EnableDelayedExpansion

SET URL=
SET /A BASECONCATENATED=0
FOR %%A IN (%*) DO (
    SET PARAM=%%A
    SET PARAM=!PARAM:"=!

    IF !BASECONCATENATED! EQU 0 (
        SET "URL=!URL!!PARAM!^?"
        SET /A BASECONCATENATED=1
    ) ELSE (
        SET "URL=!URL!!PARAM!^&"
    ) 
)

SET URL=!URL:~0,-1!

CALL "%SYSTEMDRIVE%\Program Files\Internet Explorer\iexplore.exe" "!URL!"

REM EXAMPLE cmd.exe "openurl.bat" http://www.example.com/addPerson.php "firstName=Juan" "lastName=Cerezo" "hobby1=Coding" "hobby2=Learning" "hobby3=Play Videogames"
  • There is no such limit of 255 arguments. It's only limited by the line length limit of 8191 characters, I tested and get therefore a limit of 4094 args, `A A A A A ...` – jeb Jan 15 '20 at 08:55
  • Yes it's TRUE!! Thank you!! :D – Juan Cerezo Jan 16 '20 at 09:18
  • Using `%*` to transfer parameters doesn't work in all cases. Think of a simple `myBatch.bat C:\Docs^&Music` – jeb Jan 16 '20 at 09:23
2

You can use the shift command which shifts the arguments back 1 step, for example %9 would be stored in %8 and %8 would be stored in %7 etc, so if that happened there would be room for a 10th argument in the 9th argument if that makes sense, here is an example:

@echo off
set arg1=%~1
set arg2=%~2
set arg3=%~3
set arg4=%~4
set arg5=%~5
set arg6=%~6
set arg7=%~7
set arg8=%~8
set arg9=%~9
shift
set arg10=%~9
shift
set arg11=%~9
shift
set arg12=%~9

and instead of using %~1 use %arg1% etc, and to use the 10th, 11th, 12th argument you will use %arg10%, %arg11%, %arg12%.

Hayz
  • 176
  • 4
1
:: set PARAMn and count parameters
SET /a paramcount=1
:paramloop
SET "param%paramcount%=%~1"
IF DEFINED param%paramcount% SET /a paramcount+=1&shift&GOTO paramloop
SET /a paramcount -=1

This routine should set param1..paramn for you, with a count.

Unfortunately, your posted code appears indecipherable, so actually using the values - that's up to you.

Magoo
  • 77,302
  • 8
  • 62
  • 84
0

You could make it less error prone by adding one parameter at a time. This way, if you have to add a new one in the middle or take one parameter out, you don't need to renumber the rest: it will just be a two line change. Hopefully there aren't spaces in your parameters but that is another story.

set v=http://example.com
rem first parameter is ?: subsequent ones are &
set sep=?
call :add firstName %1
shift
call :add middleName %1
shift
call :add lastName %1
shift
...
start iexplore "%v%"
goto :eof
:add
    rem add a parameter
    set v=%v%%sep%%1=%2
    set sep=&
    goto :eof
cup
  • 7,589
  • 4
  • 19
  • 42
0

The solution by basin should work. To address the problem with the code in the question: You can't just put multiple commands in a single line and you can't use the shift command in the middle of another command's arguments. Basically you have to split everything up, like shown in the other answer. To make it more concise and readable I would do it like this:

set "ieargs=http://example.com?firstName=%1^&middleName=%2^&lastName=%3^&country=%4^&address=%5^&address2=%6^&address3=%7^&mobileNo=%8^&landlineNo=%9"

@for /L %%i in (0,1,8) do shift
set "ieargs=%ieargs%^&emailAddress=%1^&hobby1=%2^&hobby2=%3^&hobby3=%4^&hobby4=%5^&hobby5=%6"

start iexplore %ieargs%

The first nine arguments are saved in the string. Then it loops and shifts nine times, so that %1 will be the thenth argument.

If you need even more arguments you can just repeat this as often as you need:

set "ieargs=http://example.com?firstName=%1^&middleName=%2^&lastName=%3^&country=%4^&address=%5^&address2=%6^&address3=%7^&mobileNo=%8^&landlineNo=%9"

@for /L %%i in (0,1,8) do shift
set "ieargs=%ieargs%^&emailAddress=%1^&hobby1=%2^&hobby2=%3^&hobby3=%4^&hobby4=%5^&hobby5=%6^&hobby6=%7^&hobby7=%8^&hobby8=%9"

@for /L %%i in (0,1,8) do shift
set "ieargs=%ieargs%^&hobby9=%1^&hobby10=%2^&hobby11=%3^&hobby12=%4"

start iexplore %ieargs%
kapex
  • 28,903
  • 6
  • 107
  • 121
0
@echo off
set /a a=0
:9
set CustomVar%a%=%1
@shift
set /a a=%a%+1
if %a%==300 goto :8
goto :9
:8
@echo on
  • Please avoid posting two answers to the same question, without any explanation to differentiate between the two. I have deleted your older answer. – Matt Sep 17 '16 at 08:42
0

My alternative allows you skip any number of arguments and requires no shifting

SETLOCAL
  SET /a SKIP=3
  CALL :SkipAndExec SKIP THESE VARS echo numbers: 1 2 3 4 5 6 7 8 9 0 11 12 13 14
ENDLOCAL
GOTO:eof

:SkipAndExec
SETLOCAL
SET /a n=0
FOR %arg IN (%*) DO (
  SET /a n=n+1
  IF %n% GT %SKIP% (
    :: here you could compose a string to use later
    SET _CMD_=%_CMD_% %arg%
  )
)
:: here you could call another function and pass in %_CMD_%
CALL %_CMD_%
GOTO:eof

If you execute that script, it will print:

numbers: 1 2 3 4 5 6 7 8 9 0 11 12 13 14
Marcel Valdez Orozco
  • 2,985
  • 1
  • 25
  • 24
0

Dealing with * in parameters examples:

@ECHO OFF
SETLOCAL DISABLEDELAYEDEXPANSION

CALL testLIMIT.bat 3 4 2 1 2 3 4 5 3 2 1 2 3 4 5 6 5 4 3 2 1 2 3 4 5 6 7 6 5 4 3 2 1 A Star * is Born twice * now

ECHO HOME
Pause
exit
@ECHO OFF
SETLOCAL EnableDelayedExpansion

REM :: Used to define the Array Index values and Range
set _I=0

REM :: The Core piece in recieving Large numbers of Parameters.
REM :: Processes all Parameters. Tested to over 2500 Parameters.

Set StarTest=0
FOR %%a in (%*) DO (
    IF EXIST "%%~a" Call :StarTest
    IF NOT EXIST "%%~a" (
    CALL Set /a _I+=1
    CALL Set "arg[!_I!]=%%a"
    CALL Set StarTest=0
    )
)


REM :: Loops through the Array to display Parameter Values.

FOR /L %%a in (1,1,!_I!) DO (
ECHO !arg[%%a]!
)

echo %_I% Arguments received.
Pause
GOTO :EOF

:StarTest
IF %StarTest% GTR 0 GOTO :EOF
Set /a StarTest+=1
Set /a _I+=1
Set "arg[!_I!]=*"
GOTO :EOF

Processing parameters with Shift is Entirely Unneccesary, not to mention messy.

The following approach, Similar to Marcels Answer, will process Exceptionally large numbers of parameters without any requirement to know how many Arguments will be recieved.

It uses A basic For loop with the * wildcard to process all tokens and Assigns them to an Array, also giving a Value to how many arguments the File recieved to enable processing.


@ECHO OFF
SETLOCAL EnableDelayedExpansion

REM :: Used to define the Array Index values and Range
set _I=0

REM :: The Core piece in recieving Large numbers of Parameters.
REM :: Processes all Parameters. Tested to over 2500 Parameters.

FOR %%a in (%*) DO (
Set /a _I+=1
Set "arg[!_I!]=%%a"
)

REM :: Loops through the Array to display Parameter Values. Modify as needed to Process Parameters.

FOR /L %%a in (1,1,!_I!) DO (
ECHO !arg[%%a]!
)

echo %_I% Arguments received.
Pause
GOTO :EOF

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
T3RR0R
  • 2,747
  • 3
  • 10
  • 25
  • This doesn't work if you call your batch with `A star * is born`. Btw. It's the same solution as the one of [Marcel Valdez Orozco](https://stackoverflow.com/a/40838667/463115) – jeb Jan 15 '20 at 08:01
  • With regards to Marcels answer, I made a point of mentioning his answer and the similarity of mine- However perhaps I didn't stress the value/ application of the Array element within my Answer. With Regards to the Impact of Calling with "A Star * is Born", That's quite an interesting learning. I ran a test using * with the Call, and was somewhat Surprised by the Result- All filenames, including extensions, within the current Directory were picked up and included in the Array. This is a behaviour that for certain applications could be manipulated to advantage. – T3RR0R Jan 15 '20 at 08:29
  • Assuming the other parameters being passed aren't filepaths, the tokens resulting from inclusion of * within the call can be passed over using an IF Not Exist "%%~a" () Check prior to setting the parameters to the Array. Now I'm curious about how (If at all possible) to escape the star during Call or Processing to prevent this output and retain the original string/parameter. HiHo HiHo it's Experimenting and Researching I go. "\" or "^" will escape the symbol, but not include it. – T3RR0R Jan 15 '20 at 08:55
  • The `*` and `?` are not *expanded* by the CALL, they are expanded by the simple `FOR`, that can't be escaped. You can use a `FOR /F` but then it's not possible to split the arguments by quotes/white spaces. You would have to write a full featured argment parser then – jeb Jan 15 '20 at 08:58
  • I'm aware it's expanded during the loop, however I'm looking to determine if, at the time it's sent as a parmeter, there is a way to modify a string including * in a way the string can be subsequently processed. Initial thoughts on the simplest approach would be to substitute the symbol with another string and detect such substitution during the loop to rebuild the original string. – T3RR0R Jan 15 '20 at 09:03
  • Even that is tricky, as `?` can be replaced easily, but `*` can't – jeb Jan 15 '20 at 09:33
  • Next trick is to adapt the method to deal with * as part of a string. – T3RR0R Jan 15 '20 at 09:37
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/205993/discussion-between-jeb-and-t3rr0r). – jeb Jan 15 '20 at 09:42