Search code examples
batch-filewmic

Find the version of a installed program from batch file


We have a batch file that installs several programs as part of the developers setup. This is ran periodically when we get new versions of used components. So it would be nice only to install if the versions are different.

At the command prompt I can run this and get back the version installed:

wmic datafile where name='C:\\Program Files (x86)\\Common Files\\Company\\Product\\Version12\\Product.exe' get version /format:list

Which gives the output Version=12.1.369.0.

However when I put this into a batch file like this and try to extract the version:

echo off
FOR /F "tokens=2 delims==" %%I in ('"wmic datafile where^(name^="C:\\Program Files (x86)\\Common Files\\Company\\Product\\Version12\\Product.exe" get version /format:list"') DO (SET "RESULT=%%I")
ECHO %RESULT%

I get the response \\Common was unexpected at this time.

Some parts may be redundant as I've been trying stuff off the 'Net to correct this.

What have I missed?


Solution

  • You have a set of misplaced double quotes, as well as an extra (.

    WMIC uses SQL syntax, and strings are enclosed in single quotes.The internal single quotes do not interfere with the command enclosing single quotes.

    You can put double quotes around the WHERE clause (not including the WHERE keyword) to avoid some escape issues within the FOR DO() clause.

    @echo off
    FOR /F "tokens=2 delims==" %%I IN (
      'wmic datafile where "name='C:\\Program Files (x86)\\Common Files\\Company\\Product\\Version12\\Product.exe'" get version /format:list'
    ) DO SET "RESULT=%%I"
    ECHO %RESULT%
    

    But this may not quite be the whole solution. You can't see it with the above code, but RESULT actually contains a trailing carriage return (0x0D). This is due to a quirk with how FOR /F handles WMIC unicode output. Every line of WMIC output will have the extra trailing carriage return.

    As long as you always access RESULT using %RESULT% (normal expansion), then you will not have any problems. But if you should ever need delayed expansion, then you can have problems, as demonstrated below.

    @echo off
    setlocal enableDelayedExpansion
    FOR /F "tokens=2 delims==" %%I IN (
      'wmic datafile where "name='C:\\Program Files (x86)\\Common Files\\Company\\Product\\Version12\\Product.exe'" get version /format:list'
    ) DO SET "RESULT=%%I"
    ECHO %RESULT%xxx
    ECHO !RESULT!xxx
    

    One convenient method to strip the unwanted carriage return is to use an extra level of FOR.

    @echo off
    setlocal enableDelayedExpansion
    FOR /F "tokens=2 delims==" %%I IN (
      'wmic datafile where "name='C:\\Program Files (x86)\\Common Files\\Company\\Product\\Version12\\Product.exe'" get version /format:list'
    ) DO FOR /F "delims=" %%A IN ("%%I") DO SET "RESULT=%%A"
    ECHO %RESULT%xxx
    ECHO !RESULT!xxx