Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting the list of installed DLLs from an Microsoft Windows installer class

I am trying to write a plugin (actually a visual studio template wizard that generates the plugin) for an existing application. As part of the plugin installation, I have to insert entries into a configuration database. Often there are multiple DLLs corresponding to different parts of the functionality, sometimes each requiring entries in the same tables, but usually with different combinations of table entries. I need to add those from my installer.

Everything is in C#, for policy reasons.

I'm currently using Visual Studio Installer (VS2010) to create the installer. I'd prefer to use something that is likely to be installed on the user's machine to keep the template / wizard installation simple, but I could (if necessary) bundle / chain-install an open-source (or at least freely redistributable) alternative installer.

For example, to add a menu entry to the application, I have to insert entries into a couple of tables. In the past, I've done this by using an installer helper (sometimes an application, sometimes an installer class) that is called from the installer application. In that design, I would embed the settings I need to add to configuration tables into the installer helper, then execute SQL (via C# :-)) to actually do the add.

The problem is that this leads to repeating the same information into two places, and it's not very maintainable or clean in a wizard environment. I'd really prefer to introspect this information from some attribute I can set on the plugin assemblies.

However I've stumbled at the first step - how can my Installer class find out which assemblies were installed (or will be installed) by this installation?

I did consider trying to embed the list of DLLs into a custom installer property, but that will be hard to generate from my plugin wizard too. Ideally there would be some existing event I can register for, or an existing property I can read, but I haven't discovered it yet.

like image 870
BradHards Avatar asked Jan 06 '14 01:01

BradHards


1 Answers

What you can do is use the Windows Installer API to dump all the DLLs contained in a given MSI package.

In C#, there are various libraries or sample code available to do this.

Here, I will use the open source Wix toolset project's DLLs. So, you just need to download the binaries (not the wix installer), create a project and add references to Microsoft.Deployment.WindowsInstaller.dll and Microsoft.Deployment.WindowsInstaller.Package.dll in this binaries directory

Here is a sample program that writes out all DLL files part of the package.

class Program
{
    static void Main(string[] args)
    {
        string path = @"... myfile.msi";
        using (InstallPackage package = new InstallPackage(path, DatabaseOpenMode.ReadOnly))
        {
            foreach (var kvp in package.Files.Where(f => Path.GetExtension(f.Value.TargetName) == ".dll"))
            {
                Console.WriteLine(kvp.Value.TargetName);
            }
        }
    }
}

}

like image 86
Simon Mourier Avatar answered Oct 09 '22 15:10

Simon Mourier