One of the features of BizTalk 2006 deployment module is the ability to export and import a BizTalk Application as MSI installation package.
In this way we can treat each application as an atomic deployment package. This means that if we need to update our application resources with a new version, we can create a new MSI version 2.0 with all new versions of the resources and then deploy them all in one managed package.
The creation of the MSI package can be done from within the Administration Console MMC or through BTSTask.exe script.
or with BTSTask.exe:
ExportApp -ApplicationName:MyApp -Package:"C:\Temp\MyApp.Msi"
To see BTSTask.exe usage:
C:\Program Files\Microsoft BizTalk Server 2006>BTSTask.exe ExportApp -?
All BizTalk Exported MSI files are always versioned ‘1.0.0.0’
Both BizTalk Administration console and BTSTask.exe sharing the same API to create this MSI file. The methods and classes to administrate BizTalk reside under Microsoft.BizTalk.ApplicationDeployment.Application namespace of assembly Microsoft.BizTalk.ApplicationDeployment.Engine.
The method that actually creates the MSI package is
CreateMsiPackage(string msiPath, ICollection<Resource> resources, ICollection<string> applicationReferences, IDictionary<string, object> requestProperties)
Now, unfortunately by using this method, BizTalk always creates the MSI file version as 1.0.0.0 – this means that we can’t easily manage our MSI installation packages because even if we're creating MSI of version 2.0, BizTalk will export it as 1.0
This restriction is for some reason hard-coded and you just can't change it.
in the following figure you can see the hard-coded msi version:
How can I change the MSI version and successfully manage my installation packages
One of the ways I’ve seen people handling this restriction is by simply name the generated MSI installation Package with some Naming-Conventions like <ApplicationName>_<VerNum>.MSI
I consider a file name as a poor way to ensure version identity, a better idea is to somehow "Patch" the MSI metadata itself to hold the correct version. in this way, I can assure that no one will accidently rename my MSI file (just think on how easy that can happen).
What is BizTalk MSI installation package
Before I'll show you how to patch the file, it's first must be understood that an MSI file is actually a Database file. Inside the MSI there's some system table that contains a lot of data like parameters of the MSI, the name of the CAB files, the Binary stream data content of the CAB files, custom actions etc.
The MSI Installer engine executes SQL queries against the MSI tables and by that installing and extracting the actual files. the functions required to work with MSI protocol can be reference through msi.dll unmanaged DLL under windows system directory.
You can find the MSI database documentation on MSDN here:
Browse into BizTalk MSI
The best way to know what MSI in general (and BizTalk MSI file in particular) means is by using "Microsoft Orca".
As you can see in the figure above, the version of the MSI is saved in 'ProductVersion' cell under 'Property' table.
So, the solution to BizTalk hard-coded 1.0 version problem is to change this value inside 'Property' table. but how can we get inside the MSI tables and change this value? – one way is by using a tool like Microsoft Orca, but in this way, the developer (or administrator) must patch the file by hand and it’s a path to future mistakes. I consider it to be a good solution only if we can some-how automate the process afterwards, so some like always some C# code can do the trick.
Patching BizTalk MSI file
BizTalk ships with a helper class to manage MSI and CAB files. The assembly name is Microsoft.BizTalk.MSIManager.dll
This class is actually a managed code wrapper around the MSI.dll functions and mach more easy to code then PInvoke. BizTalk infrastructures API's for deployment uses this class to create and import files form BizTalkMgmtDb into an MSI installer file and vise versa.
So, now we understand that we can't force BizTalk to export the MSI with another version then 1.0.0.0 but we can still use BizTalk helper classes to get an easy access the MSI tables and to change the information holds inside the exported MSI.
Here's the code snippet:
public void UpdateMSIProps(string msiPath, string version)
{
Database db = Installer.OpenDatabase(msiPath, DatabaseOpenMode.Transact);
string query = @"UPDATE Property SET Property.Value = '" + version + "' WHERE Property.Property = 'ProductVersion'";
Record rec = null;
Microsoft.BizTalk.ApplicationDeployment.MSIManager.WindowsInstaller.View vw =
db.OpenView(query);
vw.Execute();
vw.Close();
db.Commit();
db.Close();
db.Dispose();
}
I also guess you’ll probably want to automate following steps as a script:
Conclusion
Although BizTalk can export Application from BizTalkMgmtDb into a MSI installer package, it’s also forces this package to be of version 1.0.0.0
we simply can't do much with that because it's hard-coded with BizTalk deployment API but we does can take the newly generated MSI and 'Patch' the correct table with our desired version.
In this way we can handle our MSI versioning in the correct way.
Thanks’ to Moti Feldman for helping me with this issue.