65.9K
CodeProject is changing. Read more.
Home

Extension for extracting Regsitry entries for COM DLLs and EXEs

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.43/5 (5 votes)

Jul 14, 2008

Public Domain

1 min read

viewsIcon

28590

downloadIcon

494

Support for COM/DLL Registry in WIX. As WIX does not support the Extract At build feature, we can make use of this DLL as an extesnion while running Candle and have all the Registry entries extracted during build time.

Introduction

Extracting the Registry entries for COM DLLs and EXEs during build time is not supported in WIX. But, they provide an option for writing an extension. The Registry data can be extracted by making use of Heat. Hence, I am making use of Heat.exe, and extension facility of WIX. So, while pre-processing the Wxs file using Candle, we can generate all the Registry data. I am still not sure what to do with the rgs data. But this solves at least half of the problem for the installer guys. Hope this helps many installer guys looking for such a utility.

Using the code

Make a new C# project, and copy class1.cs and Assemblyinfo.cs to their respective locations. Now, add the references wix.dll and wixUtilExtensions.dll. Compile the project, and you have the DLL you are looking for.

While running candle.exe, pass one more command argument: "-ext ComExtension.dll". And, for whatever file you want to get the Registry for, add an extra attribute "ExtractAtBuid="yes"" to those files. This DLL will add a Registry entry for that file and remove the attribute from the file so that the compilation does not fail.

This is the part of the code taken from Heat:

public static Wix.RegistryValue[] RegistryHarvest(string filePath)
{
    try
    {
        AssemblyHarvester assemblyHarvester = new AssemblyHarvester();

        Wix.RegistryValue[] registryValues = 
            assemblyHarvester.HarvestRegistryValues(filePath);
        return registryValues;
    }
    catch
    {
        // try the self-reg harvester
        try
        {
            DllHarvester dllHarvester = new DllHarvester();

            Wix.RegistryValue[] registryValues = 
                dllHarvester.HarvestRegistryValues(filePath);
            return registryValues;
        }
        catch
        {
            // try the type library harvester
            try
            {
                TypeLibraryHarvester typeLibHarvester = new TypeLibraryHarvester();

                Wix.RegistryValue[] registryValues = 
                    typeLibHarvester.HarvestRegistryValues(filePath);
                return registryValues;
            }
            catch
            {
                return null;
                // ignore all exceptions
            }
        }
    }
}
         
//This checks for the attribute ExtractAtBuild and remove it after making use of it
if (fileElem.HasAttribute("ExtractAtBuild"))
{
    GetCompleteFilePath(fileElem);
    string fileName = Path.Combine(SourcePath, fileElem.GetAttribute("Name"));
    if (!File.Exists(fileName))
    {
        this.Core.OnMessage(WixErrors.WixFileNotFound(fileName));
        continue;
    }

    RegHarvester.GenerateComRegistryData(SourcePath, DestinationId, document, fileNode);
    fileElem.RemoveAttribute("ExtractAtBuild");
}

Hope this code helps.

Also attached is the DLL. Directly make use of the DLL to get things done. Also, use the -v option to get the verbose output and to see for what files the Registry entry is getting generated and what the values for them are.