howto: embed a CAB shared by two .msi (multilanguage)

May 6, 2010 at 9:50 AM
Hello everyone, I'm very new to DNI. I've got two .msi I need them for a multilanguage installation for. Those two .msi share an external .cab file. How can I embed the cabinet once for both .msi files? I've got the following schema: - Root Config File - install:1040 - Embed file: msi#1 (needs CAB) - install:1033 - Embed file: msi#2 (needs CAB) Launching the bootstrapper prompts the user for the language choice, then the proper .msi is executed. Both need the same cab in order to work properly and I don't want to embed the cab inside them because it costs 37MB and I would duplicate my final installer dimensions. Thanks in advance for your answers! (hopefully :-P)
May 11, 2010 at 11:39 PM

You can embed the CAB at top level (not under a component).

I *think* you should be able to embed the MSI twice in two CAB components with the same ID. I am goging to give an educated guess that if the ID is the same, you only get the same file embedded once and extracted for each component. Give it a try. Does it work?

May 12, 2010 at 9:09 AM

I didn't try it yet due to an incoming deadline. By the way, I worked it around by using MSI transforms, generate only one .msi with the cab embedded and then embed the .msi and .mst files inside the .exe with DNI.

May 12, 2010 at 11:35 AM

I'd be curious to see how you did that. I never used MSI transforms ;)

May 12, 2010 at 1:13 PM

You need to build a single .msi for each language you want to implement inside your installer, plus a neutral one (I choose the culture en-us as the neutral one).


Then you generate a .mst file (MSI transformation) for each non-neutral culture, by using the MsiTran.exe application with the syntax: "MsiTran.exe -g NeutralInstaller.msi CultureSpecificInstaller.msi TransformFile.mst".

This application compares two .msi files and creates a delta, placing it inside the .mst file. So in each .mst file you've got the differences between your main .msi (neutral) and the culture-based one.


After that you need to add informations inside the neutral.msi file, modifying it by using the MsiDb.exe application with the syntax: "MsiDb.exe -d NeutralInstaller.msi -r TransformFile.mst".


If you run NeutralInstaller.msi with no arguments, you notice no differences. If you run NeutralInstaller.msi, with the parameter "TRANSFORMS=TransformFile.mst", the installer starts with transformations specified inside the TransformFile.mst

Then you create a bootstrapper with the NeutralInstaller.msi, and every .mst file embedded. When you select a language, you pass "TRANSFORMS=#LANGID.mst" as a cmdparamenter of the .msi, and the installation starts with the language you selected. Notice: in order for this DNI to work properly, you must add a simple hack: add to the project a number of "Setup configuration" equal to the number of languages you need to implement. Each SC has a language string and a language id associated (i.e. English 1033, Italian 1040, ecc ecc). For everyone but the first SC you need to add the lcid_filter with a number you are sure you will never use as language id, so you have the dropdownlist menu with languages and you're sure that only the first SC will be executed, even if the #LANGID property is correctly set.

It's vital that .mst filenames correspond to language IDs, in order for #LANGID property to work properly.


It's the first time I use this stuff, I might have been inaccurate and lucky, so take it with due softness please.




P.S. Both MsiTran.exe and MsiDb.exe are shipped with Microsoft SDK, you can download it form the MS' website.

Aug 12, 2010 at 11:56 AM

Is it mean that we must have 0.mst, 1033.mst, 1040.mst... transforms for correct msiexec command line parameters processing?