/// <summary> /// Creates a new melter object. /// </summary> /// <param name="decompiler">The decompiler to use during the melting process.</param> /// <param name="id">The Id to use for the ComponentGroup, DirectoryRef, and WixVariables. If null, defaults to the Module's Id</param> public Melter(Decompiler decompiler, string id) { this.core = new MelterCore(this.Message); this.componentGroup = new Wix.ComponentGroup(); this.fragment = new Wix.Fragment(); this.primaryDirectoryRef = new Wix.DirectoryRef(); this.decompiler = decompiler; this.id = id; if (null == this.decompiler) { this.core.OnMessage(WixErrors.ExpectedDecompiler("The melting process")); } }
/// <summary> /// Creates a new melter object. /// </summary> /// <param name="decompiler">The decompiler to use during the melting process.</param> /// <param name="id">The Id to use for the ComponentGroup, DirectoryRef, and WixVariables. If null, defaults to the Module's Id</param> public Melter(Decompiler decompiler, string id) { this.core = new MelterCore(this.Message); this.componentGroup = new Wix.ComponentGroup(); this.fragment = new Wix.Fragment(); this.primaryDirectoryRef = new Wix.DirectoryRef(); this.decompiler = decompiler; this.id = id; if (null == this.decompiler) { this.core.OnMessage(WixErrors.ExpectedDecompiler("The melting process")); } }
/// <summary> /// Creates a component group with a given name. /// </summary> /// <param name="wix">The Wix document element.</param> private void CreateComponentGroup(Wix.Wix wix) { Wix.ComponentGroup componentGroup = new Wix.ComponentGroup(); componentGroup.Id = this.componentGroupName; this.componentGroups.Add(componentGroup); Wix.Fragment cgFragment = new Wix.Fragment(); cgFragment.AddChild(componentGroup); wix.AddChild(cgFragment); int componentCount = 0; for (; componentCount < this.components.Count; componentCount++) { Wix.Component c = this.components[componentCount] as Wix.Component; if (this.createFragments) { if (c.ParentElement is Wix.Directory) { Wix.Directory parentDirectory = c.ParentElement as Wix.Directory; componentGroup.AddChild(c); c.Directory = parentDirectory.Id; parentDirectory.RemoveChild(c); } else if (c.ParentElement is Wix.DirectoryRef) { Wix.DirectoryRef parentDirectory = c.ParentElement as Wix.DirectoryRef; componentGroup.AddChild(c); c.Directory = parentDirectory.Id; parentDirectory.RemoveChild(c); // Remove whole fragment if moving the component to the component group just leaves an empty DirectoryRef if (0 < fragments.Count && parentDirectory.ParentElement is Wix.Fragment) { Wix.Fragment parentFragment = parentDirectory.ParentElement as Wix.Fragment; int childCount = 0; foreach (Wix.ISchemaElement element in parentFragment.Children) { childCount++; } // Component should always have an Id but the SortedList creation allows for null and bases the name on the fragment count which we cannot reverse engineer here. if (1 == childCount && !String.IsNullOrEmpty(c.Id)) { int removeIndex = fragments.IndexOfKey(String.Concat("Component:", c.Id)); if (0 <= removeIndex) { fragments.RemoveAt(removeIndex); } } } } } else { Wix.ComponentRef componentRef = new Wix.ComponentRef(); componentRef.Id = c.Id; componentGroup.AddChild(componentRef); } } }
/// <summary> /// Creates a component group with a given name. /// </summary> /// <param name="wix">The Wix document element.</param> private void CreateComponentGroup(Wix.Wix wix) { Wix.ComponentGroup componentGroup = new Wix.ComponentGroup(); componentGroup.Id = this.componentGroupName; this.componentGroups.Add(componentGroup); Wix.Fragment cgFragment = new Wix.Fragment(); cgFragment.AddChild(componentGroup); wix.AddChild(cgFragment); int componentCount = 0; for (; componentCount < this.components.Count; componentCount++) { Wix.Component c = this.components[componentCount] as Wix.Component; if (this.createFragments) { if (c.ParentElement is Wix.Directory) { Wix.Directory parentDirectory = c.ParentElement as Wix.Directory; componentGroup.AddChild(c); c.Directory = parentDirectory.Id; parentDirectory.RemoveChild(c); } else if (c.ParentElement is Wix.DirectoryRef) { Wix.DirectoryRef parentDirectory = c.ParentElement as Wix.DirectoryRef; componentGroup.AddChild(c); c.Directory = parentDirectory.Id; parentDirectory.RemoveChild(c); // Remove whole fragment if moving the component to the component group just leaves an empty DirectoryRef if (0 < fragments.Count && parentDirectory.ParentElement is Wix.Fragment) { Wix.Fragment parentFragment = parentDirectory.ParentElement as Wix.Fragment; int childCount = 0; foreach (Wix.ISchemaElement element in parentFragment.Children) { childCount++; } // Component should always have an Id but the SortedList creation allows for null and bases the name on the fragment count which we cannot reverse engineer here. if (1 == childCount && !String.IsNullOrEmpty(c.Id)) { int removeIndex = fragments.IndexOfKey(String.Concat("Component:", c.Id)); if (0 <= removeIndex) { fragments.RemoveAt(removeIndex); } } } } } else { Wix.ComponentRef componentRef = new Wix.ComponentRef(); componentRef.Id = c.Id; componentGroup.AddChild(componentRef); } } }
/// <summary> /// Creates WiX fragments for files in one output group. /// </summary> /// <param name="projectFile">VS MSBuild project file.</param> /// <param name="buildOutputs">Dictionary of build outputs retrieved from an MSBuild run on the project file.</param> /// <param name="pog">Project output group parameters.</param> /// <param name="fragmentList">List to which generated fragments will be added.</param> /// <returns>Count of harvested files.</returns> private int HarvestProjectOutputGroup(string projectFile, IDictionary buildOutputs, ProjectOutputGroup pog, IList fragmentList) { string projectName = Path.GetFileNameWithoutExtension(projectFile); string projectBaseDir = null; if (this.ProjectName != null) { projectName = this.ProjectName; } string sanitizedProjectName = HarvesterCore.GetIdentifierFromName(projectName); Wix.IParentElement harvestParent; if (this.GenerateType == GenerateType.Container) { Wix.Container container = new Wix.Container(); harvestParent = container; container.Name = String.Format(CultureInfo.InvariantCulture, DirectoryIdFormat, sanitizedProjectName, pog.Name); } else if (this.GenerateType == GenerateType.PayloadGroup) { Wix.PayloadGroup container = new Wix.PayloadGroup(); harvestParent = container; container.Id = String.Format(CultureInfo.InvariantCulture, DirectoryIdFormat, sanitizedProjectName, pog.Name); } else if (this.GenerateType == GenerateType.PackageGroup) { Wix.PackageGroup container = new Wix.PackageGroup(); harvestParent = container; container.Id = String.Format(CultureInfo.InvariantCulture, DirectoryIdFormat, sanitizedProjectName, pog.Name); } else { Wix.DirectoryRef directoryRef = new Wix.DirectoryRef(); harvestParent = directoryRef; if (!String.IsNullOrEmpty(this.directoryIds)) { directoryRef.Id = this.directoryIds; } else if (this.setUniqueIdentifiers) { directoryRef.Id = String.Format(CultureInfo.InvariantCulture, DirectoryIdFormat, sanitizedProjectName, pog.Name); } else { directoryRef.Id = HarvesterCore.GetIdentifierFromName(String.Format(CultureInfo.InvariantCulture, VSProjectHarvester.DirectoryIdFormat, sanitizedProjectName, pog.Name)); } this.directoryRefSeed = this.Core.GenerateIdentifier(DirectoryPrefix, this.projectGUID, pog.Name); } IEnumerable pogFiles = buildOutputs[pog.BuildOutputGroup] as IEnumerable; if (pogFiles == null) { throw new WixException(VSErrors.MissingProjectOutputGroup( projectFile, pog.BuildOutputGroup)); } if (pog.FileSource == "ProjectDir") { projectBaseDir = Path.GetDirectoryName(projectFile) + "\\"; } int harvestCount = this.HarvestProjectOutputGroupFiles(projectBaseDir, projectName, pog.Name, pog.FileSource, pogFiles, harvestParent); if (this.GenerateType == GenerateType.Container) { // harvestParent must be a Container at this point Wix.Container container = harvestParent as Wix.Container; Wix.Fragment fragment = new Wix.Fragment(); fragment.AddChild(container); fragmentList.Add(fragment); } else if (this.GenerateType == GenerateType.PackageGroup) { // harvestParent must be a PackageGroup at this point Wix.PackageGroup packageGroup = harvestParent as Wix.PackageGroup; Wix.Fragment fragment = new Wix.Fragment(); fragment.AddChild(packageGroup); fragmentList.Add(fragment); } else if (this.GenerateType == GenerateType.PayloadGroup) { // harvestParent must be a Container at this point Wix.PayloadGroup payloadGroup = harvestParent as Wix.PayloadGroup; Wix.Fragment fragment = new Wix.Fragment(); fragment.AddChild(payloadGroup); fragmentList.Add(fragment); } else { // harvestParent must be a DirectoryRef at this point Wix.DirectoryRef directoryRef = harvestParent as Wix.DirectoryRef; if (harvestCount > 0) { Wix.Fragment drf = new Wix.Fragment(); drf.AddChild(directoryRef); fragmentList.Add(drf); } Wix.ComponentGroup cg = new Wix.ComponentGroup(); if (this.setUniqueIdentifiers || !String.IsNullOrEmpty(this.directoryIds)) { cg.Id = String.Format(CultureInfo.InvariantCulture, DirectoryIdFormat, sanitizedProjectName, pog.Name); } else { cg.Id = directoryRef.Id; } if (harvestCount > 0) { this.AddComponentsToComponentGroup(directoryRef, cg); } Wix.Fragment cgf = new Wix.Fragment(); cgf.AddChild(cg); fragmentList.Add(cgf); } return harvestCount; }
/// <summary> /// Mutate a WiX document. /// </summary> /// <param name="wix">The Wix document element.</param> public override void Mutate(Wix.Wix wix) { this.components.Clear(); this.directories.Clear(); this.directoryRefs.Clear(); this.features.Clear(); this.files.Clear(); this.fragments.Clear(); this.rootElement = null; // index elements in this wix document this.IndexElement(wix); this.MutateWix(wix); this.MutateFiles(); this.MutateDirectories(); this.MutateComponents(); // add the components to the product feature after all the identifiers have been set if (TemplateType.Product == this.templateType) { Wix.Feature feature = (Wix.Feature) this.features[0]; foreach (Wix.Component component in this.components) { if (null != component.Id) { Wix.ComponentRef componentRef = new Wix.ComponentRef(); componentRef.Id = component.Id; feature.AddChild(componentRef); } } } // create a ComponentGroup with all the components else if (TemplateType.Fragment == this.templateType && !this.createFragments) { Wix.ComponentGroup componentGroup = new Wix.ComponentGroup(); componentGroup.Id = "ComponentGroup1"; foreach (Wix.Component component in this.components) { if (null != component.Id) { Wix.ComponentRef componentRef = new Wix.ComponentRef(); componentRef.Id = component.Id; componentGroup.AddChild(componentRef); } } Wix.Fragment fragment = new Wix.Fragment(); this.fragments.Add("ComponentGroup:1", fragment); fragment.AddChild(componentGroup); } foreach (Wix.Fragment fragment in this.fragments.Values) { wix.AddChild(fragment); } }