MAKEMSI quickly and reliably creates MSI files in a non-programmatic way
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
[Bottom][Contents][Prev]: How to Post Process MSIDIFF Output[Next]: MSI (Windows Installer) Platform SDK
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
\->Tips and Tricks->Tools->MSIDIFF.VBS->UpgradeCode, Simple Tool to dump MSI codes

UpgradeCode, Simple Tool to dump MSI codes

The batch file shown below has a simple command line:

  1. You can pass nothing on the comamnd line in which case all msis found in the current directory will be processed.

  2. You can pass a single msi name in which case it will be processed.

  3. You can pass "?" in which case you will be prompted for msi names.

    You can drag msi files from explorer anywhere onto the window and the filename will be entered into the prompt. Any double quotes will be completely ignored.

    If the filename begins with a "@" then its a text file that contains a list of msi files to be processed. If the line is blank or begins with ";", a space or tab then the line is ignored (a comment line).

All filenames are relative to the current directory. A tab delimited file will be generated for output.

DumpMsiUpgradeCodes.cmd

@echo off
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
set PgmVersion=11.254
cls
call :SetChar TAB  9
for /F "tokens=1,2,3,4 delims=/ " %%i in ('date /T') do set YYYYMMDD=%%l-%%k-%%j&set Day3=%%i
set HHMMSSSS=%time::=_%
set HHMMSSSS=%HHMMSSSS: =0%
set   HHMMSS=%HHMMSSSS:~0,8%
set     HHMM=%HHMMSSSS:~0,5%
set Randomish=%time::=_%-%RANDOM%
set    RootDir=.\$RESULTS$
set  ResultDir=%RootDir%\%YYYYMMDD% (%DAY3%) @ %HHMMSSSS%
set     TmpDir=%ResultDir%\$PROPERTIES$
set Pause=Y
md "%RootDir%" > nul 2>&1
echo []------------------------------------------------[]
echo ^| DumpMsiUpgradeCodes.CMD By Dennis Bareis v%PgmVersion% ^|
echo []------------------------------------------------[]
echo.
if not "%MSIDIFF_DIR%" == "" goto MSIDIFF_INSTALLED
   echo ERROR: The "MSIDIFF" tool must be installed
   echo        You can download from: http://dennisbareis.com/msidiff.htm
   if "%Pause%" == "Y" pause
   goto :EOF
:MSIDIFF_INSTALLED
set MsiDiffVbs=%MSIDIFF_DIR%MsiDiff.VBS



if "%~1" == ""  goto NotOnCmdLine
if "%~1" == "?" goto WILL_ASK
    @rem *** ONE MSI ON COMMAND LINE *****************************************
    set   Pause=N
    set TsvFile=
    echo Looking at "%~1"
    call :GetUpgradeCode "%~1"
    echo %TAB%UpgradeCode = %UpgradeCode%
    goto :EOF
:NotOnCmdLine
if exist "*.msi" goto FOUND_MSI
    @rem *** USER PROMPTED FROM MSI ******************************************
    :WILL_ASK
    set TsvFile=%ResultDir%\User Specified.tsv
    echo No "*.msi" files found at:
    echo    "%CD%"
    echo.
    echo We will ask for the names of msis (you can drag an drop from explorer).
    echo.
    :ASK
        set    MSI=
        set /p MSI=Dump which msi (BLANK=exit) ==^> &rem
        set    MSI=%MSI:"=%
        if "%MSI%" == "" goto EndBatch
        if not "%MSI:~0,1%" == "@" call :GetUpgradeCode      "%MSI%"
        if     "%MSI:~0,1%" == "@" call :GetUcForListedFiles "%MSI:~1%"
        echo.
        echo.
    goto ASK
:FOUND_MSI
    @rem *** PROCESS ALL MSIs in CURRENT DIRECTORY ***************************
    set TsvFile=%ResultDir%\All MSIs in Directory.tsv
    for %%m in (*.msi) do call :GetUpgradeCode "%%m"
    goto EndBatch



:EndBatch
    echo.
    echo Finished...
    @rem *** NOTE: The Following directories only removed if EMPTY ************
    rd "%TmpDir%"    >nul 2>&1
    rd "%ResultDir%" >nul 2>&1
    rd "%RootDir%" > nul 2>&1
    if "%Pause%" == "Y" pause
    goto :EOF


@rem ++++++++++++++++++++++++++++++++++
:GetUcForListedFiles
@rem *** Get Upgrade Code for all msis listed in the file
@rem ++++++++++++++++++++++++++++++++++
    set ListFile=%~1
    @echo Processing all msis listed in the file...
    echo LIST: "%ListFile%"
    for /F "usebackq delims=" %%m in ("%ListFile%") do (
        set ListLine=%%m
        if  "!ListLine!" == "" set ListLine=;
                               set ListLine=!ListLine:"=!
        call :Helper4GetUcForListedFiles "!ListLine!"
    )
    goto :EOF

@rem ++++++++++++++++++++++++++++++++++
:Helper4GetUcForListedFiles
@rem ++++++++++++++++++++++++++++++++++
    set LstLine=%~1
    if "%LstLine:~0,1%" == ";"     goto :EOF
    if "%LstLine:~0,1%" == " "     goto :EOF
    if "%LstLine:~0,1%" == "%TAB%" goto :EOF
    call :GetUpgradeCode "%LstLine%"
    goto :EOF


@rem ++++++++++++++++++++++++++++++++++
:GetUpgradeCode
@rem *** Get Upgrade Code for single MSI
@rem ++++++++++++++++++++++++++++++++++
    set UpgradeCode=?
    md "%TmpDir%" >nul 2>&1
    set TmpFile=$PROPERTY-TABLE-%Randomish%.txt
    for %%f in ("%~1") do set TmpFile=%%~nf%%~xf.properties.txt
    set TmpFile=%TmpDir%\%TmpFile%
    cscript.exe //NoLogo "%MsiDiffVbs%" "%~1" +Property > "%TmpFile%"
    @rem notepad "%TmpFile%"

    set FndProperty=N
    for /F "usebackq delims=" %%l in ("%TmpFile%") do (
        set LINE=%%l
        set LINE=!LINE:"='!
        set LINE=!LINE: =!
        if "!FndProperty!" == "Y" call :ExtractUpgradeCode !LINE!& set FndProperty=YY
        if "!LINE!" == "Property='UpgradeCode'" set FndProperty=Y&set UpgradeCode={nextline}
        rem echo !FndProperty!: !LINE!
    )
    call :UpdateTsv "%UpgradeCode%" "%~1"
    goto :EOF


@rem ++++++++++++++++++++++++++++++++++
:UpdateTsv
@rem ++++++++++++++++++++++++++++++++++
    set TheMsi=%~2
    if  "%TsvFile%" == "" goto :EOF
    if not exist "%TsvFile%" echo UpgradeCode%TAB%Msi> "%TsvFile%"
    echo %~1%TAB%%TheMsi%>> "%TsvFile%"
    echo * %~1 : %TheMsi%
    goto :EOF


@rem ++++++++++++++++++++++++++++++++++
:ExtractUpgradeCode
@rem ++++++++++++++++++++++++++++++++++
    set UpgradeCode={extracting}
    for /f "tokens=2 delims='" %%u in ("%*") do set UpgradeCode=%%u
    goto :EOF


@rem ++++++++++++++++++++++++++++++++++
:SetChar
@rem ++++++++++++++++++++++++++++++++++
    set VbsFile=%TEMP%\SetChar-%RANDOM%.vbs
    set CmdFile=%TEMP%\SetChar-%RANDOM%.cmd
    echo if Wscript.Arguments.Count ^<^> 2 then                                                                        > "%VbsFile%"
    echo    wscript.echo "REM Invalid parameters, expected 2 (1=EnvVar 2=AsciiCode), got " ^& Wscript.Arguments.Count >> "%VbsFile%"
    echo else                                                                                                         >> "%VbsFile%"
    echo    wscript.echo "@echo off"                                                                                  >> "%VbsFile%"
    echo    wscript.echo "SET " ^& Wscript.Arguments(0) ^& "=" ^& chr(Wscript.Arguments(1))                           >> "%VbsFile%"
    echo end if                                                                                                       >> "%VbsFile%"
    cscript.exe //NoLogo "%VbsFile%" "%~1" "%~2"                                                                       > "%CmdFile%"
    call "%CmdFile%"
    del "%VbsFile%" >nul 2>&1
    del "%CmdFile%" >nul 2>&1
    goto :EOF


Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006, 2007, 2008 & 2009 for the Windows SDK (Windows Installer) area.Please email me any feedback, additional information or corrections.
See this page online (look for updates)

[Top][Contents][Prev]: How to Post Process MSIDIFF Output[Next]: MSI (Windows Installer) Platform SDK


MAKEMSI© is (C)opyright Dennis Bareis 2003-2008 (All rights reserved).
Saturday May 28 2022 at 3:11pm
Visit MAKEMSI's Home Page
Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006, 2007, 2008 & 2009 for the Windows SDK (Windows Installer) area.