views:

1159

answers:

1

Some batch files on Windows use an IF syntax with multiple lines, as below:

if var==rule (
  some comands
) else (
  else commands
)

Now, Windows Vista x64 decided to put all 32 bits files under "C:\Program Files (x86)". Unfortunately, whenever you use an environment variable (such as PATH) inside a multiple line IF without quotes, the parenthesis inside the variable's value confuses IF, aborting the batch file. For example:

if "%OS%"=="Windows_NT" (
  @setlocal
  call :set_home
  set _ARGS=%*
) else (
  set _SCALA_HOME=%SCALA_HOME%
  rem The following line tests SCALA_HOME instead of _SCALA_HOME, because
  rem the above change to _SCALA_HOME is not visible within this block.
  if "%SCALA_HOME%"=="" goto error1
  call :set_args
)

A batch file with this will fail even though the line where %SCALA_HOME% appears does not get executed. This is rather annoying. Is there a solution for this?

+2  A: 

Change all instances of %SCALA_HOME% to !SCALA_HOME!, and add the following near the top of the file:

setlocal enableextensions enabledelayedexpansion

The latter turns on "delayed variable expansion", which means that variables written in the form !VAR! are not expanded until they are used, rather than when the statement itself is parsed. (In my limited experience, and certainly in this case, this means that variable expansions are less likely to be misinterpreted as actual batch file syntax constructs.) Thanks to Patrick Cuff for pointing out this better way of doing it in a comment.

P.S.: As you are discovering, the cmd.exe batch file language is horribly broken in many ways. If you can't use a genuine scripting language (e.g. if your task needs to be performed on other computers), I would seriously recommend knocking out a quick C/C++ "script" that does the job, and compile it to .EXE.

j_random_hacker
If delayed expansion indeed solves this problem, you wouldn't need a second batch script, just put `setlocal enableextensions enabledelayedexpansion` at the top of your script.
Patrick Cuff
I did not know that, thanks Patrick! Much nicer.
j_random_hacker
I'll try using setlocal enableextensions enabledelayedexpasion. If it works, I'll need another answer to set as accepted.
Daniel
Hope it works for you. Is there some technicality preventing you from marking my answer as accepted? If so don't worry about it.
j_random_hacker
enabledelayedexpansion only works for !! variables. This solution works, kinda. It certainly fixes it on Vista, but am I wrong in assuming it will be incompatible with non-"%OS%" = "Windows_NT" systems?
Daniel
It should work on any system using cmd.exe. Systems that still use command.com (e.g. Win9x) don't have multiline IF statements in their batch language anyway.
j_random_hacker