Say, if I have an MSI installation file, can I extract its contents from a C# or C++ program without installing it?
Typically you can perforrm an Administrative installation to extract the contents of an MSI.
msiexec /a foo.msi TARGETDIR=C:\EXTRACTHERE /qn
If you don't want to go out of process you can interop directly with MSI via the MsiInstallProduct function.
szPackagePath [in] A null-terminated string that specifies the path to the location of the Windows Installer package. The string value can contain a URL a network path, a file path (e.g. file://packageLocation/package.msi), or a local path (e.g. D:\packageLocation\package.msi).
szCommandLine [in] A null-terminated string that specifies the command line property settings. This should be a list of the format Property=Setting Property=Setting. For more information, see About Properties.
To perform an administrative installation, include ACTION=ADMIN in szCommandLine. For more information, see the ACTION property.
Note that while you can declare the P/Invoke yourself, there is a really good .NET interop library available with Windows Instaler XML called Deployment Tools Foundation (DTF). The Microsoft.Deployment.WindowsInstaller namespace has a class method called Installer that exposes a static method called InstallProduct. This is a direct encapsulation of MsiInstallProduct.
Using the DTF libraries hides you from the ugliness on the Win32 API and correctly implements IDisposable where needed to ensure that underlying unmanaged handles are released where needed.
Additionally DTF has the Microsoft.DeploymentWindowwsInstaller.Package namespace with the InstallPackage class. This class exposes a method called ExtractFiles() that extracts the files to the working directory. An example of code looks like:
using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Deployment.WindowsInstaller.Package;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
using( var package = new InstallPackage(@"C:\test.msi", DatabaseOpenMode.ReadOnly))
{
package.ExtractFiles();
}
}
}
}
An MSI file is a COM structured storage. It is basically a database. You can find some detailed documentation on msdn:
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