Exemplo n.º 1
0
        /// <summary>
        /// Processes the installation files, produces the WiX data.
        /// </summary>
        private int ConvertFiles(DirectoryRef wixDirectoryRef, ComponentGroup wixComponentGroup, InstallationDataXml dataxml, IDictionary <string, string> macros)
        {
            int nProduced = 0;

            // Each installation folder derives a component, regardless of whether there are more files in the same folder, or not
            foreach (FolderXml folderxml in dataxml.Files)
            {
                folderxml.AssertValid();

                // Create the component with the files
                var wixComponent = new Component();
                wixComponent.Id       = string.Format("{0}.{1}", ComponentIdPrefix, folderxml.Id);
                wixComponent.Guid     = folderxml.MsiComponentGuid;
                wixComponent.DiskId   = Bag.Get <int>(AttributeName.DiskId);
                wixComponent.Location = Component.LocationType.local;
                ConvertFiles_AddToDirectory(folderxml, wixComponent, wixDirectoryRef);                 // To the directory structure

                // Add to the feature
                var wixComponentRef = new ComponentRef();
                wixComponentRef.Id = wixComponent.Id;
                wixComponentGroup.AddChild(wixComponentRef);                 // To the feature

                var diSource = new DirectoryInfo(Path.Combine(LocalInstallDataResolved.ResolveSourceDirRoot(folderxml.SourceRoot, Bag), folderxml.SourceDir));
                if (!diSource.Exists)
                {
                    throw new InvalidOperationException(string.Format("The source folder “{0}” does not exist.", diSource.FullName));
                }

                // Add files
                foreach (FileXml filexml in folderxml.Files)
                {
                    filexml.AssertValid();

                    FileInfo[] files = diSource.GetFiles(filexml.SourceName);
                    if (files.Length == 0)
                    {
                        throw new InvalidOperationException(string.Format("There are no files matching the “{0}” mask in the source folder “{1}”.", filexml.SourceName, diSource.FullName));
                    }
                    if ((files.Length > 1) && (filexml.TargetName.Length > 0))
                    {
                        throw new InvalidOperationException(string.Format("There are {2} files matching the “{0}” mask in the source folder “{1}”, in which case it's illegal to specify a target name for the file.", filexml.SourceName, diSource.FullName, files.Length));
                    }

                    foreach (FileInfo fiSource in files)
                    {
                        nProduced++;

                        var wixFile = new File();
                        wixComponent.AddChild(wixFile);
                        wixFile.Id       = string.Format("{0}.{1}.{2}", FileIdPrefix, folderxml.Id, fiSource.Name).Replace('-', '_').Replace(' ', '_'); // Replace chars that are not allowed in the ID
                        wixFile.Name     = filexml.TargetName.Length > 0 ? filexml.TargetName : fiSource.Name;                                          // Explicit target name, if present and if a single file; otherwise, use from source
                        wixFile.Checksum = YesNoType.yes;
                        wixFile.ReadOnly = YesNoType.yes;
                        wixFile.Source   = fiSource.FullName;
                    }
                }
            }

            return(nProduced);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates a new WiX Component for populating with the values of a specific hive, or reuses an existing one.
        /// Registry items from different hives must not be mixed within a single component.
        /// </summary>
        /// <param name="hive">Registry hive.</param>
        /// <param name="directory">A WiX directory to parent the newly-created component.</param>
        /// <param name="componentgroup">A group of components to register the newly-created component into.</param>
        protected Component GetComponentForHive(RegistryHiveXml hive, DirectoryRef directory, ComponentGroup componentgroup)
        {
            if (directory == null)
            {
                throw new ArgumentNullException("directory");
            }
            if (componentgroup == null)
            {
                throw new ArgumentNullException("componentgroup");
            }

            Component component;

            if (myMapHiveToComponent.TryGetValue(hive, out component)) // Lookup
            {
                return(component);                                     // Reuse existing
            }
            // Create a new one
            component = new Component();
            myMapHiveToComponent.Add(hive, component);
            directory.AddChild(component);
            component.Id = string.Format("{0}.{1}", ComponentIdPrefix, hive);

            // Chose a GUID for the component, assign
            component.Guid = myGuidCache[GetGuidId(hive)].ToString("B").ToUpperInvariant();

            // Register in the group
            var componentref = new ComponentRef();

            componentgroup.AddChild(componentref);
            componentref.Id = component.Id;

            return(component);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Actions under the resolver.
        /// </summary>
        protected override void ExecuteTaskResolved()
        {
            GuidCacheXml guidcachexml = GuidCacheXml.Load(new FileInfo(Bag.GetString(AttributeName.GuidCacheFile)).OpenRead());

            // Global structure of the WiX fragment file
            var wix = new Wix();
            var wixFragmentComponents = new Fragment();             // Fragment with the payload

            wix.AddChild(wixFragmentComponents);
            var wixDirectoryRef = new DirectoryRef();             // Mount into the directories tree, defined externally

            wixFragmentComponents.AddChild(wixDirectoryRef);
            wixDirectoryRef.Id = Bag.GetString(AttributeName.WixDirectoryId);
            var wixDirectory = new Directory();             // A locally created nameless directory that does not add any nested folders but defines the sources location

            wixDirectoryRef.AddChild(wixDirectory);
            wixDirectory.Id         = DirectoryId;
            wixDirectory.FileSource = Bag.GetString(AttributeName.ProductBinariesDir);
            var wixFragmentGroup = new Fragment();             // Fragment with the component-group that collects the components

            wix.AddChild(wixFragmentGroup);
            var wixComponentGroup = new ComponentGroup();             // ComponentGroup that collects the components

            wixFragmentGroup.AddChild(wixComponentGroup);
            wixComponentGroup.Id = Bag.GetString(AttributeName.WixComponentGroupId);

            // A component for the generated Registry entries
            var wixComponentRegistry = new Component();

            wixDirectory.AddChild(wixComponentRegistry);
            wixComponentRegistry.Id       = RegistryComponentIdPrefix;
            wixComponentRegistry.Guid     = guidcachexml[GuidIdXml.MsiComponent_ProductBinaries_Registry_Hkmu].ToString("B").ToUpper();
            wixComponentRegistry.DiskId   = Bag.Get <int>(AttributeName.DiskId);
            wixComponentRegistry.Location = Component.LocationType.local;
            var wixComponentRegistryRef = new ComponentRef();

            wixComponentGroup.AddChild(wixComponentRegistryRef);
            wixComponentRegistryRef.Id = wixComponentRegistry.Id;

            // Create the Registry key for the Plugins section
            CreatePluginsRegistryKey(wixComponentRegistry);

            // Load the AllAssemblies file
            AllAssembliesXml allassembliesxml = AllAssembliesXml.LoadFrom(Bag.Get <TaskItemByValue>(AttributeName.AllAssembliesXml).ItemSpec);

            // Tracks the files on the target machine, to prevent the same file from being installed both as an assembly and as a reference
            var mapTargetFiles = new Dictionary <string, string>();

            int nGeneratedComponents = ProcessAssemblies(wixDirectory, wixComponentGroup, wixComponentRegistry, allassembliesxml, mapTargetFiles, guidcachexml);

            // Save to the output file
            using (var xw = new XmlTextWriter(new FileStream(Bag.GetString(AttributeName.OutputFile), FileMode.Create, FileAccess.Write, FileShare.Read), Encoding.UTF8))
            {
                xw.Formatting = Formatting.Indented;
                wix.OutputXml(xw);
            }

            // Report (also to see the target in the build logs)
            Log.LogMessage(MessageImportance.Normal, "Generated {0} product binary components.", nGeneratedComponents);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Processes the files that should be taken from the “References” folder and installed “AS IS”.
        /// </summary>
        private int ProcessReferences(Directory wixDirectory, ComponentGroup wixComponentGroup, AllAssembliesXml allassembliesxml, Dictionary <string, string> mapTargetFiles)
        {
            int nGeneratedComponents = 0;

            // Replaces illegal chars with underscores
            var regexMakeId = new Regex("[^a-zA-Z0-9_.]");

            foreach (ItemGroupXml group in allassembliesxml.ItemGroup)
            {
                if (group.References == null)
                {
                    continue;
                }
                foreach (ReferenceXml referencexml in group.References)
                {
                    nGeneratedComponents++;
                    var fiReference = new FileInfo(Path.Combine(Bag.GetString(AttributeName.ProductReferencesDir), referencexml.Include));
                    if (!fiReference.Exists)
                    {
                        throw new InvalidOperationException(string.Format("The reference file “{0}” could not be found.", fiReference.FullName));
                    }

                    string sIdSuffix = regexMakeId.Replace(fiReference.Name, "_");

                    // Create the component for the assembly (one per assembly)
                    var wixComponent = new Component();
                    wixDirectory.AddChild(wixComponent);
                    wixComponent.Id       = string.Format("{0}.{1}", FileComponentIdPrefix, sIdSuffix);
                    wixComponent.Guid     = referencexml.MsiGuid;
                    wixComponent.DiskId   = Bag.Get <int>(AttributeName.DiskId);
                    wixComponent.Location = Component.LocationType.local;

                    // Register component in the group
                    var componentref = new ComponentRef();
                    wixComponentGroup.AddChild(componentref);
                    componentref.Id = wixComponent.Id;

                    // Add the reference file (and make it the key path)
                    var wixFileReference = new File();
                    wixComponent.AddChild(wixFileReference);
                    wixFileReference.Id       = string.Format("{0}.{1}", FileIdPrefix, sIdSuffix);
                    wixFileReference.Name     = fiReference.Name;
                    wixFileReference.KeyPath  = YesNoType.yes;
                    wixFileReference.Checksum = YesNoType.yes;
                    wixFileReference.Vital    = YesNoType.yes;
                    wixFileReference.ReadOnly = YesNoType.yes;

                    RegisterTargetFile(wixFileReference.Name, string.Format("The “{0}” reference.", referencexml.Include), mapTargetFiles);
                }
            }

            return(nGeneratedComponents);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Processes those AllAssemblies.Xml entries that are our own product assemblies.
        /// </summary>
        private int ProcessAssemblies(Directory wixDirectory, ComponentGroup wixComponentGroup, Component wixComponentRegistry, AllAssembliesXml allassembliesxml, Dictionary <string, string> mapTargetFiles, GuidCacheXml guidcachexml)
        {
            // Collect the assemblies
            int nGeneratedComponents = 0;

            foreach (ItemGroupXml group in allassembliesxml.ItemGroup)
            {
                if (group.AllAssemblies == null)
                {
                    continue;
                }
                foreach (AssemblyXml assemblyxml in group.AllAssemblies)
                {
                    nGeneratedComponents++;
                    FileInfo fiAssembly = FindAssemblyFile(assemblyxml);
                    string   sExtension = fiAssembly.Extension.TrimStart('.');                   // The extension without a dot

                    // Create the component for the assembly (one per assembly)
                    var wixComponent = new Component();
                    wixDirectory.AddChild(wixComponent);
                    wixComponent.Id       = string.Format("{0}.{1}.{2}", FileComponentIdPrefix, assemblyxml.Include, sExtension);
                    wixComponent.Guid     = assemblyxml.MsiGuid;
                    wixComponent.DiskId   = Bag.Get <int>(AttributeName.DiskId);
                    wixComponent.Location = Component.LocationType.local;

                    // Register component in the group
                    var componentref = new ComponentRef();
                    wixComponentGroup.AddChild(componentref);
                    componentref.Id = wixComponent.Id;

                    // Add the assembly file (and make it the key path)
                    var wixFileAssembly = new File();
                    wixComponent.AddChild(wixFileAssembly);
                    wixFileAssembly.Id       = string.Format("{0}.{1}.{2}", FileIdPrefix, assemblyxml.Include, sExtension);
                    wixFileAssembly.Name     = string.Format("{0}.{1}", assemblyxml.Include, sExtension);
                    wixFileAssembly.KeyPath  = YesNoType.yes;
                    wixFileAssembly.Checksum = YesNoType.yes;
                    wixFileAssembly.Vital    = YesNoType.yes;
                    wixFileAssembly.ReadOnly = YesNoType.yes;

                    RegisterTargetFile(wixFileAssembly.Name, string.Format("The {0} product assembly.", assemblyxml.Include), mapTargetFiles);

                    // Check whether it's a managed or native assembly
                    AssemblyName assemblyname = null;
                    try
                    {
                        assemblyname = AssemblyName.GetAssemblyName(fiAssembly.FullName);
                    }
                    catch (BadImageFormatException)
                    {
                    }

                    // Add COM Self-Registration data
                    if (assemblyxml.ComRegister)
                    {
                        /*
                         * foreach(ISchemaElement harvested in HarvestComSelfRegistration(wixFileAssembly, fiAssembly))
                         * wixComponent.AddChild(harvested);
                         */
                        SelfRegHarvester.Harvest(fiAssembly, assemblyname != null, wixComponent, wixFileAssembly);
                    }

                    // Ensure the managed DLL has a strong name
                    if ((assemblyname != null) && (Bag.Get <bool>(AttributeName.RequireStrongName)))
                    {
                        byte[] token = assemblyname.GetPublicKeyToken();
                        if ((token == null) || (token.Length == 0))
                        {
                            throw new InvalidOperationException(string.Format("The assembly “{0}” does not have a strong name.", assemblyxml.Include));
                        }
                    }

                    // Add PDBs
                    if (Bag.Get <bool>(AttributeName.IncludePdb))
                    {
                        HarvestSatellite(assemblyxml, assemblyxml.Include + ".pdb", wixComponent, MissingSatelliteErrorLevel.Error, "PDB file", mapTargetFiles);
                    }

                    // Add XmlDocs
                    if ((assemblyname != null) && (Bag.Get <bool>(AttributeName.IncludeXmlDoc)))
                    {
                        HarvestSatellite(assemblyxml, assemblyxml.Include + ".xml", wixComponent, MissingSatelliteErrorLevel.Error, "XmlDoc file", mapTargetFiles);
                    }

                    // Add configs
                    HarvestSatellite(assemblyxml, assemblyxml.Include + "." + sExtension + ".config", wixComponent, (assemblyxml.HasAppConfig ? MissingSatelliteErrorLevel.Error : MissingSatelliteErrorLevel.None), "application configuration file", mapTargetFiles);
                    HarvestSatellite(assemblyxml, assemblyxml.Include + "." + sExtension + ".manifest", wixComponent, (assemblyxml.HasMainfest ? MissingSatelliteErrorLevel.Error : MissingSatelliteErrorLevel.None), "assembly manifest file", mapTargetFiles);
                    HarvestSatellite(assemblyxml, assemblyxml.Include + ".XmlSerializers." + sExtension, wixComponent, (assemblyxml.HasXmlSerializers ? MissingSatelliteErrorLevel.Error : MissingSatelliteErrorLevel.None), "serialization assembly", mapTargetFiles);

                    // Add publisher policy assemblies
                    if (assemblyname != null)
                    {
                        HarvestPublisherPolicyAssemblies(assemblyxml, wixDirectory, wixComponentGroup, ref nGeneratedComponents, mapTargetFiles, guidcachexml);
                    }

                    // Register as an OmeaPlugin
                    if (assemblyname != null)
                    {
                        RegisterPlugin(assemblyxml, wixFileAssembly, wixComponentRegistry);
                    }
                }
            }
            return(nGeneratedComponents);
        }
Exemplo n.º 6
0
        private void HarvestPublisherPolicyAssemblies(AssemblyXml assemblyxml, Directory directory, ComponentGroup componentgroup, ref int nGeneratedComponents, Dictionary <string, string> mapTargetFiles, GuidCacheXml guidcachexml)
        {
            if (!Bag.Get <bool>(AttributeName.IncludePublisherPolicy))
            {
                return;
            }

            int    nWasGeneratedComponents = nGeneratedComponents;
            var    diFolder           = new DirectoryInfo(Bag.GetString(AttributeName.ProductBinariesDir));
            string sSatelliteWildcard = string.Format("Policy.*.{0}.{1}", assemblyxml.Include, "dll");             // Even an EXE assembly has a DLL policy file

            foreach (FileInfo fiPolicyAssembly in diFolder.GetFiles(sSatelliteWildcard))
            {
                // Find the companion policy config file
                var fiPolicyConfig = new FileInfo(Path.ChangeExtension(fiPolicyAssembly.FullName, ".Config"));
                if (!fiPolicyConfig.Exists)
                {
                    throw new InvalidOperationException(string.Format("Could not locate the publisher policy config file for the assembly “{0}”; expected: “{1}”.", fiPolicyAssembly.FullName, fiPolicyConfig.FullName));
                }

                // We have to create a new component for each of the DLLs we'd like to GAC as publisher policy assemblies
                nGeneratedComponents++;

                // Create the component for the assembly (one per assembly)
                var component = new Component();
                directory.AddChild(component);
                component.Id       = string.Format("{0}.{1}", FileComponentIdPrefix, fiPolicyAssembly.Name);
                component.Guid     = guidcachexml[assemblyxml.Include + " PublisherPolicy"].ToString("B").ToUpper();
                component.DiskId   = Bag.Get <int>(AttributeName.DiskId);
                component.Location = Component.LocationType.local;

                // Register component in the group
                var componentref = new ComponentRef();
                componentgroup.AddChild(componentref);
                componentref.Id = component.Id;

                // Add the assembly file (and make it the key path)
                var fileAssembly = new File();
                component.AddChild(fileAssembly);
                fileAssembly.Id       = string.Format("{0}.{1}", FileIdPrefix, fiPolicyAssembly.Name);
                fileAssembly.Name     = fiPolicyAssembly.Name;
                fileAssembly.KeyPath  = YesNoType.yes;
                fileAssembly.Checksum = YesNoType.yes;
                fileAssembly.Vital    = YesNoType.no;
                fileAssembly.Assembly = File.AssemblyType.net;
                fileAssembly.ReadOnly = YesNoType.yes;

                RegisterTargetFile(fileAssembly.Name, string.Format("Publisher policy assembly file for the {0} product assembly.", assemblyxml.Include), mapTargetFiles);

                // Add the policy config file
                var filePolicy = new File();
                component.AddChild(filePolicy);
                filePolicy.Id       = string.Format("{0}.{1}", FileIdPrefix, fiPolicyConfig.Name);
                filePolicy.Name     = fiPolicyConfig.Name;
                filePolicy.KeyPath  = YesNoType.no;
                filePolicy.Checksum = YesNoType.yes;
                filePolicy.Vital    = YesNoType.no;
                filePolicy.ReadOnly = YesNoType.yes;

                RegisterTargetFile(fileAssembly.Name, string.Format("Publisher policy configuration file for the {0} product assembly.", assemblyxml.Include), mapTargetFiles);
            }

            if (nWasGeneratedComponents == nGeneratedComponents)            // None were actually collected
            {
                throw new InvalidOperationException(string.Format("Could not locate the Publisher Policy assemblies for the “{0}” assembly. The expected full path is “{1}\\{2}”.", assemblyxml.Include, diFolder.FullName, sSatelliteWildcard));
            }
        }