<!-- 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 call
ing 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.