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]: SuperOrca - MSI Editor[Next]: JT.EXE
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
\->Tips and Tricks->Tools->MsiSync.VBS

MsiSync.VBS

This is a tool that is provided with MAKEMSI and it is intended for development environments where multiple users might be updating and/or needing installation of a set of MSIs on a file share (a simple deployment tool).

This program will when invoked look in "source" directory(s) and all its subdirectories. The default source directory is the one the script is in.

Any MSIs found will have their "ProductCode", "PackageCode" and "ProductVersion" examined. If it is not installed for the user (per-machine or per-user) then it is installed.

Before installing an MSI this tool gets a list of all related products (uses the "UpgradeCode" property) and uninstalls these.

You would generally place this script in the appropriate folder and create a shortcut in the "Startup" folder or perhaps registry "run" key. You might also wish to set up a desktop shortcut and/or schedule its execution.

As the source directory can be altered some users may wish to set up their own variations of the configuration.

If MSIs need to be installed/updated in a particular order you can control this to some degree as MSIs in a particular directory are processed before files in any subdirectories.

Configuration File (.XML)

It is recommended that a good XML or text editor (with XML plugins) be used to ensure that it is valid (its validated against the schema) as it is not validated by this tool when loading it (due to current MS XML issues).

The XML file should hold correctly formed XML and may omit any attributes or XML tags that are not required. All attributes are tested for environment variables (surrounded by the "%" character), any found are replaced.

The configuration file's default filename (command line not used) has the same name as the VBSCRIPT but with the ".XML" extension. In this case the configuration file need not exist. One easy way to support multiple configurations is to have multiple versions (copy the script and XML) of the script and XML.

The following is a fully populated sample file (hover other highlighted items for tooltips):

<MsiSync Test="No" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="MsiSync.xsd">
    <Log Name="%TEMP%\MsiSync.log.txt" />

    <MsiSource>
        <Directory>c:\NoSuch\ChangeTheXmlConfigurationFileToPointToMsiSourceDirectory!</Directory>
        <MsiReMask>\.MSI$</MsiReMask>
    </MsiSource>

    <Retries>
        <StartupLock Tries="10" Delay="30"  />
        <MsiInUse    Tries="10" Delay="30" />
    </Retries>

    <Install>
        <MsiExec.EXE>
            <QuietSwitches>/qb</QuietSwitches>
            <RebootSwitches>REBOOT=ReallySuppress</RebootSwitches>
            <OtherSwitches></OtherSwitches>
        </MsiExec.EXE>
    </Install>

    <Uninstall>
        <MsiExec.EXE>
            <QuietSwitches>/qb</QuietSwitches>
            <RebootSwitches>REBOOT=ReallySuppress</RebootSwitches>
            <OtherSwitches></OtherSwitches>
        </MsiExec.EXE>
    </Uninstall>

    <Dialogs>
        <!-- Normal operation -->
        <Final             Show="Yes" />
        <FinalNoFilesFound Show="Yes" />
        <FinalNothingDone  Show="No"  />
        <FinalNeedReboot   Show="Yes" />

        <!-- Debug operation (in "test" mode) -->
        <DebugCfgItemFoundInXml    Show="No" />
        <DebugCfgItemNotFoundInXml Show="Yes" />
    </Dialogs>

    <Beeps>
        <AtEndIfNoDialog Number="1" />
    </Beeps>
</MsiSync>

Configuration File StyleSheet (.XSD)

You don't have to use a stylesheet but it could make entering data easier (depending on the text or XML editor used) and allows more validation of the structure and data to take place.

If you don't wish to use a style sheet then the "MsiSync" tage would look more like:

<MsiSync Test="N">

Instead of:

<MsiSync Test="N" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="MsiSync.xsd">

The stylesheet needs to be in the same directory as the XML:

<?xml version="1.0" encoding="utf-8"?>
<!--
    ;===========================================================================
    ;     MODULE NAME:   MsiSync.XSD
    ;
    ;         $Author:   USER "Dennis"  $
    ;       $Revision:   1.3  $
    ;           $Date:   27 May 2005 17:36:12  $
    ;        $Logfile:   C:/DBAREIS/Projects.PVCS/Win32/MakeMsi/MsiSync.xsd.pvcs  $
    ;===========================================================================
-->

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <!-- GROUP: MSIEXEC Parameters for INSTALL & UNINSTALL  -->
    <xs:group name="grp.MsiExec.EXE">
        <xs:all>
            <xs:element name="MsiExec.EXE" minOccurs="0" maxOccurs="1">
                <xs:complexType>
                    <xs:all>
                        <xs:element name="QuietSwitches"  type="xs:string" minOccurs="0" maxOccurs="1" />
                        <xs:element name="RebootSwitches" type="xs:string" minOccurs="0" maxOccurs="1" />
                        <xs:element name="OtherSwitches"  type="xs:string" minOccurs="0" maxOccurs="1" />
                    </xs:all>
                </xs:complexType>
            </xs:element>
        </xs:all>
    </xs:group>

    <!-- GROUP: Dialog item attributes  -->
    <xs:attributeGroup name="grp.DialogAttributes">
        <xs:attribute name="Show">
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:enumeration value="Yes" />
                    <xs:enumeration value="Y" />
                    <xs:enumeration value="No" />
                    <xs:enumeration value="N" />
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
    </xs:attributeGroup>


    <!-- GROUP: Retry item attributes  -->
    <xs:attributeGroup name="grp.RetryAttributes">
        <!-- Tries -->
        <xs:attribute name="Tries" type="xs:positiveInteger" />

        <!-- Delay -->
        <xs:attribute name="Delay" type="xs:positiveInteger" />
    </xs:attributeGroup>

    <!-- Start defining tree with the ROOT element -->
    <xs:element name="MsiSync">
        <xs:complexType>
            <xs:all>
                <!-- MsiSource -->
                <xs:element name="MsiSource" minOccurs="0" maxOccurs="1">
                    <xs:complexType>
                        <xs:all>
                            <xs:element name="Directory" type="xs:string" minOccurs="0" maxOccurs="1" />
                            <xs:element name="MsiReMask" type="xs:string" minOccurs="0" maxOccurs="1" />
                        </xs:all>
                    </xs:complexType>
                </xs:element>

                <!-- Retries -->
                <xs:element name="Retries" minOccurs="0" maxOccurs="1">
                    <xs:complexType>
                        <xs:all>
                            <!-- StartupLock -->
                            <xs:element name="StartupLock" minOccurs="0" maxOccurs="1">
                                <xs:complexType>
                                    <xs:attributeGroup ref="grp.RetryAttributes" />
                                </xs:complexType>
                            </xs:element>

                            <!-- MsiInUse -->
                            <xs:element name="MsiInUse" minOccurs="0" maxOccurs="1">
                                <xs:complexType>
                                    <xs:attributeGroup ref="grp.RetryAttributes" />
                                </xs:complexType>
                            </xs:element>
                        </xs:all>
                    </xs:complexType>
                </xs:element>

                <!-- Install -->
                <xs:element name="Install" minOccurs="0" maxOccurs="1">
                    <xs:complexType>
                        <xs:group ref="grp.MsiExec.EXE" />
                    </xs:complexType>
                </xs:element>

                <!-- Uninstall -->
                <xs:element name="Uninstall" minOccurs="0" maxOccurs="1">
                    <xs:complexType>
                        <xs:group ref="grp.MsiExec.EXE" />
                    </xs:complexType>
                </xs:element>


                <!-- Dialogs -->
                <xs:element name="Dialogs" minOccurs="0" maxOccurs="1">
                    <xs:complexType>
                        <xs:all>
                            <!-- Final tag -->
                            <xs:element name="Final" minOccurs="0" maxOccurs="1">
                                <xs:complexType>
                                    <xs:attributeGroup ref="grp.DialogAttributes" />
                                </xs:complexType>
                            </xs:element>

                            <!-- FinalNoFilesFound tag -->
                            <xs:element name="FinalNoFilesFound" minOccurs="0" maxOccurs="1">
                                <xs:complexType>
                                    <xs:attributeGroup ref="grp.DialogAttributes" />
                                </xs:complexType>
                            </xs:element>

                            <!-- FinalNothingDone tag -->
                            <xs:element name="FinalNothingDone" minOccurs="0" maxOccurs="1">
                                <xs:complexType>
                                    <xs:attributeGroup ref="grp.DialogAttributes" />
                                </xs:complexType>
                            </xs:element>

                            <!-- FinalNeedReboot tag -->
                            <xs:element name="FinalNeedReboot" minOccurs="0" maxOccurs="1">
                                <xs:complexType>
                                    <xs:attributeGroup ref="grp.DialogAttributes" />
                                </xs:complexType>
                            </xs:element>


                            <!-- DebugCfgItemFoundInXml tag -->
                            <xs:element name="DebugCfgItemFoundInXml" minOccurs="0" maxOccurs="1">
                                <xs:complexType>
                                    <xs:attributeGroup ref="grp.DialogAttributes" />
                                </xs:complexType>
                            </xs:element>


                            <!-- DebugCfgItemNotFoundInXml tag -->
                            <xs:element name="DebugCfgItemNotFoundInXml" minOccurs="0" maxOccurs="1">
                                <xs:complexType>
                                    <xs:attributeGroup ref="grp.DialogAttributes" />
                                </xs:complexType>
                            </xs:element>
                        </xs:all>
                    </xs:complexType>
                </xs:element>

                <!-- Log -->
                <xs:element name="Log" minOccurs="0" maxOccurs="1">
                    <xs:complexType>
                        <xs:attribute name="Name" type="xs:string" />
                    </xs:complexType>
                </xs:element>


                <!-- Beeps -->
                <xs:element name="Beeps" minOccurs="0" maxOccurs="1">
                    <xs:complexType>
                        <xs:all>
                            <xs:element name="AtEndIfNoDialog" minOccurs="0" maxOccurs="1">
                                <xs:complexType>
                                    <xs:attribute name="Number" type="xs:nonNegativeInteger" />
                                </xs:complexType>
                            </xs:element>
                        </xs:all>
                    </xs:complexType>
                </xs:element>
            </xs:all>

            <!-- MsiSync attributes -->
            <xs:attribute name="Test" type="xs:string" />
        </xs:complexType>
    </xs:element>
</xs:schema>


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]: SuperOrca - MSI Editor[Next]: JT.EXE


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.