<!-- language: lang-dos -->
@ECHO OFF
SETLOCAL
rem SET SERVICES[#][0]="Window Title"
rem SET SERVICES[#][1]="Relative .bat path"
SET SERVICES[0][0]="Hello World!"
SET SERVICES[0][1]="service/hello.bat"
SET SERVICES[1][0]="Hello World! 2"
SET SERVICES[1][1]="service/hello 2.bat"
for /f "tokens=2,3*delims=[]=" %%a in ('set SERVICES[') do IF %%b==0 CALL call q44506472_s.bat %%services[%%a][0]%% %%services[%%a][1]%%
for /f "tokens=2,3*delims=[]=" %%a in ('set SERVICES[') do IF %%b==0 CALL call q44506472_s.bat %%c %%services[%%a][1]%%
GOTO :EOF
Where q44506472_s.bat is a dummy demo file containing
@ECHO OFF
SETLOCAL
ECHO parameter1=%1
ECHO parameter2=%2
ECHO ----------------
(just to show the parameters being transmitted)
So - the hieroglypics do this:
Perform a set services[ command, which lists all variables that start services[ in the format services[0][1]=somestring.
The for /f tokenises each line that the set produces, using the three characters [,] and = as delimiters. So, with services[0][1]=somestring, we get
services as token1 - unassigned
0 as token2 - assigned to %%a as 2 is the first token number nominated
1 as token3 - assigned to %%b as 3 is the next token number nominated
somestring as token* (remainder after highest-nominated token) - assigned to %%c
The tokens are separated by any sequence of any of the chosen delimiters.
So, choosing %%b==0 will select the second array dimension = 0, and we then execute the call by calling for example %%services[%%a][0]%% which is resolved as the contents of services[0][0]. Since %%a is an active metavariable at this time, it gets substituted first and the parser then resolves remaining %% as % (% escapes %).
The first call does the parsing party-trick; the second executes the actual subroutine with the parameters resolved.
Since %%c gratuitously contains the contents required for the first parameter, you could also use that if you prefer.
Your development from there - well, cmd isn't the brightest - I think you're getting a little too clever for it. There are two problems - the first is that the windowtitle... is quoted, causing havoc and the second is that you are "quoting strings" as variable-values. Personally, I apply quotes as necessary, and I use the cmd characteristic syntax SET "var=value" (where value may be empty) which is used to ensure that any stray trailing spaces are NOT included in the value assigned.
I'd change
for /f "tokens=2,3*delims=[]=" %%a in ('set SERVICES[') do IF %%b==0 CALL for /f "Delims=:" %%A in ('tasklist /v /fi "WINDOWTITLE eq %%services[%%a][0]%%"') do if %%A==INFO SET errorinfo=1
to
(note that cmd is quite happy with line-breaks directly before/after the single-quotes in a for/f command - just makes the lines easier to edit...)
for /f "tokens=2,3*delims=[]=" %%a in ('set SERVICES['
) do IF %%b==0 CALL :seterrorinfo %%services[%%a][0]%%
ECHO errorinfo="%errorinfo%"
GOTO :EOF
:seterrorinfo
for /f "Delims=:" %%A in ('tasklist /v /fi "WINDOWTITLE eq %~1"') do ECHO ***%%A***&if %%A==INFO SET errorinfo=1
GOTO :eof
:seterrorinfo is now a subroutine, supplied with the quoted-value from the array as a parameter.
Within the subroutine, %~1 get substituted by the value of the first parameter, with the ~ operator removing any enclosing quotes.
I'll not comment on whether the detection of INFO is appropriate (but I'd suggest that errorinfo be cleared at the start of the routine. Consider what will happen if the routine is called more than once - the value from the previous call will remain in errorinfo if %%A is not INFO on the next call.) I've left the echo %%A in the subroutine for easy analysis.
Note that if you read some of the articles about delayed expansion on SO, you may be able to use it to avoid the call set kludge. Your original data included ! so I avoided it as ! then becomes a special character.