In our build process there is currently the potential for non-code based files (such as image files) to be added to our web project, but not included in the MSI installer built by WiX.
To help prevent this, I want to perform the following in the AfterBuild target for our WiX project:
If I fire up Orca I can easily see the File table and count, but I don't know how to automate this from MSBuild. Is there some API or other mechanism to get this information out of an MSI?
I don't mind writing a custom MSBuild task to extract the MSI File table count.
Extract an MSI File using the Command Line Windows has the ability to allow the MSI file contents to be extracted using the Command Prompt or via a script. Simply open the Run box (Win+R) or a Command Prompt and type msiexec to get a list of arguments.
View MSI files by launching the app, or by right-clicking an MSI file in File Explorer and choosing "Open in MSI Viewer".
Just download Universal Extractor. It extracts all types of files, including .exe,. msi,. rar,.
lessmsi is a portable app with a GUI or command-line to view and extract an MSI file's contents. MSI stands for Microsoft Installer, and it works just like an executable does. Double-click any MSI, and the install routine will begin.
Create a new visual studio project, add a reference to c:\windows\system32\msi.dll
and use the following code to read the number of files in a msi file:
Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
var installer =
(WindowsInstaller.Installer)Activator.CreateInstance(installerType);
var msi = installer.OpenDatabase(@"path\to\some\file.msi", 0);
var fileView = msi.OpenView("SELECT FileName FROM File");
fileView.Execute(null);
int fileCount = 0;
while (fileView.Fetch() != null)
{
fileCount++;
}
Console.WriteLine(fileCount);
This code uses the WindowsInstaller.Installer
COM object, which is the entry-point for the windows installer automation API. Take a look at the complete reference documentation.
edit: apparently wix comes with managed assemblies (in C:\program files\Windows Installer XML v3\sdk
) which wrap msi.dll. I guess this is what Rob is referring to by "DTF" in his answer. Using the types in the Microsoft.Deployment.WindowsInstaller assembly and namespace would simplify the code sample to this:
var database = new Database(@"\path\to\some\file.msi");
var list = database.ExecuteQuery("SELECT FileName FROM File");
Console.WriteLine(list.Count);
MSI files are little baby databases with a custom SQL engine. You just need to run the query:
SELECT `File` FROM `File`
and count the number of rows that come back. Easiest way to integrate into an MSBuild Task would probably be to use WiX's DTF which provides managed wrappers for all of the MSI APIs.
The solution will be really simple once you get all the tools in place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With