MSI is an application packaging system created by Microsoft that supports local and remote deployment of desktop applications as well as the deployment of Web applications. It is built around an extensibility model that allows the embedding of code that runs at install or uninstall time, amongst other things.
There are several applications geared to create MSI packages like Visual Studio and Installshield. In Visual Studio a package is a type of project. To create a new package you create a new project, expand the Other Projects node in the New Project screen and select the Setup and Deployment sub node. You will find several project types there of which the ”’Setup Project”’ is covered here.
Finding the dependencies
There are two types of dependencies: application files like images and configuration files and system files which are components and configuration files required by the framework or runtime you are using. The most important part of the MSI creation is determining the system files required by your application. Depending on whether your application is a VB6 or .NET application you use different tools and strategies to determine the files you need to deploy.
For .NET you need to deploy all the dlls and .config files from the output folder of your project plus any components that are installed on the GAC or that you are referencing without creating a local copy of the component. The location of all files can be derived by looking at the references in your solution. Some commercial components may require that we only distribute a certain copy of their component so be sure to check their help files. Microsoft published a very complete knowledge base article on how to distribute the .NET framework.
In VB6 projects you have to look under References and Components to collect a list of the dlls, tlbs and ocxs selected. There are four types of components: your custom components, the VB6 runtime components, the various Microsoft components (DataGrid, Common Dialogs, etc) and finally any third party controls. Each dependency can have dependencies of its own. These can be resolved in the Merge Module (see below) or using a tool called Depends which is under the Visual Studio tools. Open the control or dll in Depends and it will show you all its static dependencies. There may be dynamic dependencies which are loaded at runtime and one way of finding them is to create a complete MSI, install it on a virtual machine with a clean install of your target platform, run the application and analyze any errors to determine what files need to be added to the MSI. Filemon is very helpful in this situation too.
The VB6 runtime, all the Microsoft controls and many third party controls provide Merge Modules for deployment. Merge Modules are files that contain instructions on what files are needed for the deployment of a certain dependency as well as the correct location in the final user’s machine. The VB6 runtime and Microsoft controls Merge Modules can be found in your development machine at C:\Program Files\Common Files\Merge Modules\.
Creating the MSI Package
Now that you created the new project and figured out all the dependencies you can start to fill the project. When you open the project you will see a tree on the left with the following structure:
->File System On Target Machine
—->User’s Programs Menu
Add all the custom components and application files including the executable if it exists to the “Application Folder” branch by right clicking on it and selecting add file. Each external dependency that has a corresponding Merge Module should not be added directly. Say that you use the MSBIND.DLL in your application. Instead of adding the MSBIND.DLL you must add the file MSBIND.MSM. This is very important as a rogue installation may interfere with other applications and break them. The next step is to right click on the “User’s Desktop” and select “Create New Shortcut” pointing it to the executable on the “Application Folder”. Finally repeat this step for “the User’s Programs Menu”. The two final steps are setting the version of the MSI to match the application version and to compile it. The version is set in the properties of the project.
Deployment and Testing
Before releasing the MSI you must test in a test machine as explained above and you should also test if it runs in silent mode. This is important if your application will be deployed to several computers within an organization as the deployment team will be able to create a Systems Management Server (SMS) job with your MSI. In a nutshell, an SMS job allows automated and remote installation of an MSI. To test the silent mode, open a command line and run:
msiexec /package “c:\…\path to the msi” /quiet
The installation should proceed without any prompts. To uninstall the application you can either run the the Add/Remove Programs under Control Panel or you can run:
msiexec /uninstall “c:\…\path to the msi” /quiet
Upgrading an Existing Application
If you are upgrading an existing application that was previously deployed using MSIs you must change the version of the MSI project at which point it will popup the following message:
Microsoft Visual Studio
It is recommended that the ProductCode be changed if you change the version. Do you want to do this?
Yes No Cancel Help
You have to answer YES, and recompile the MSI. To test if the upgrade works you should install the previous version on a test machine and then run the new MSI in passive mode. Open a command line and type:
msiexec /package “c:\…\path to the new MSI” /passive
You will be able to see the uninstallation of the previous version followed by the installation of the new version. At this stage most errors are caused by not changing the version of the MSI and the correspondent product code as explained before. You can find detailed information about this process in the Windows Installer MSDN pages.
Testing an MSI can be sped up using batch files. You can create a batch file with the following line in it:
msiexec /package %1 /passive
And drag and drop the MSI on top of it. This will run the installation in a semi-silent mode showing a minimal user interface with only a progress bar. To uninstall MSIs create another batch file with the following:
msiexec /uninstall %1 /passive
And drag and drop the MSI on top of it too. You will have to use the exact same MSI that was used for installation.
Application Compatibility – MSI Installer Issues
Very interesting video with many advanced tips about MSIs and Vista and Win2k8
Discussions about advanced deployment issues