S h o r t S t o r i e s

// Tales from software development

Reading values in an XML configuration file from a batch file.

leave a comment »

The last couple of projects that I’ve worked on have included a couple of batch files as part of the deployment. These use some values such as file paths and database connection strings that are specific to the deployment environment and, ideally, should be configured by the installer. Although the WiX Util namespace includes a couple of tasks to modify an XML file it doesn’t offer any means to modify a text file such as a batch file.

So, I wondered, could I put the configurable values in an XML file and access them from the batch files ? It seemed unlikely but it’s actually surprisingly easy. It’s not pretty though…

In the following example the value to be retrieved is the text between a <connectionString> element and its matching end element in an XML file called config.xml:

FOR /f "tokens=2 delims=><  " %%a IN ('TYPE config.xml ^| FIND "<connectionString>"') DO SET CONNECTION_STRING=%%a

 
What isn’t obvious in the code above is that the delims argument is set to four characters – the greater than sign, less than sign, space, and tab.

The value is placed in an environment variable called CONNECTION_STRING.

It really is as simple as that!

This can be made a lot more sophisticated by using some of the features that Microsoft has added to batch processing over the past few iterations of Windows. For instance, put the code after a label and then call the label passing in a set of arguments such as the name of the file, the name of the value to be read, and the name of the environment variable to place the value in:

:GET_CONFIG_VALUE
REM Must be called using this syntax:
REM CALL :GET_CONFIG_VALUE cmd-filename config-filename config-value-name variable-name
REM where
REM   cmd-filename is the name of this file, e.g. use %~f0
REM   config-filename is the name of the XML config file
REM   config-value-name is the XML element name of the value in the config file
REM   variable-name is the name of the environment variable that should be set to the value found in the config file
SET GCV_CONFIG_FILE=%2
SET GCV_VALUE_NAME=%3
SET GCV_VARIABLE_NAME=%4
REM Note that the delims arguments used below include the tab and space characters.
FOR /f "tokens=2 delims=><  " %%a IN ('TYPE %GCV_CONFIG_FILE% ^| FIND "<%GCV_VALUE_NAME%>"') DO SET %GCV_VARIABLE_NAME%=%%a
GOTO :EOF

 
It’d be useful to have a generic routine for missing values too:

:MISSING_CONFIG_VALUE
ECHO ERROR: No value was found in the '%GCV_CONFIG_FILE%' file for '%GCV_VALUE_NAME%'.
GOTO EXIT

 
This code can now be called from the body of the batch file like this:

SETLOCAL
REM Get the configuration values from the config file:
SET CONFIG_FILE=%~f0.config
CALL :GET_CONFIG_VALUE "%~f0" "%CONFIG_FILE%" connectionString CONNECTION_STRING
IF "%CONNECTION_STRING%"=="" GOTO MISSING_CONFIG_VALUE
CALL :GET_CONFIG_VALUE "%~f0" "%CONFIG_FILE%" connectionTimeout CONNECTION_TIMEOUT
IF "%CONNECTION_TIMEOUT%"=="" GOTO MISSING_CONFIG_VALUE
REM Do some stuff here...
ENDLOCAL
GOTO :EOF

 
Most of this is obvious but it might be worth pointing out that %~f0 evaluates as the filename of the batch file that’s executing.

Advertisements

Written by Sea Monkey

December 2, 2009 at 10:00 am

Posted in Deployment, Development

Tagged with ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: