/// <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.directoryPaths.Clear(); this.webAddresses.Clear(); this.webDirs.Clear(); this.webDirProperties.Clear(); this.webFilters.Clear(); this.webSites.Clear(); this.webVirtualDirs.Clear(); this.rootElement = null; this.IndexElement(wix); this.MutateWebAddresses(); this.MutateWebDirs(); this.MutateWebDirProperties(); this.MutateWebSites(); this.MutateWebVirtualDirs(); // this must come after the web virtual dirs in case they harvest a directory containing a web filter file this.MutateWebFilters(); // this must come after the web site identifiers are created this.MutateComponents(); }
/// <summary> /// Calls self-reg harvester. /// </summary> /// <param name="parentElement">The parent element.</param> /// <param name="fileSource">The file source.</param> private void HarvestSelfReg(Wix.IParentElement parentElement, string fileSource) { // try the self-reg harvester try { DllHarvester dllHarvester = new DllHarvester(); this.Core.Messaging.Write(HarvesterVerboses.HarvestingSelfReg(fileSource)); Wix.RegistryValue[] registryValues = dllHarvester.HarvestRegistryValues(fileSource); foreach (Wix.RegistryValue registryValue in registryValues) { parentElement.AddChild(registryValue); } } catch (TargetInvocationException tie) { if (tie.InnerException is EntryPointNotFoundException) { // No DllRegisterServer(), which is fine by me. } else { this.Core.Messaging.Write(HarvesterWarnings.SelfRegHarvestFailed(fileSource, tie.Message)); } } catch (Exception ex) { this.Core.Messaging.Write(HarvesterWarnings.SelfRegHarvestFailed(fileSource, ex.Message)); } }
/// <summary> /// Index an element. /// </summary> /// <param name="element">The element to index.</param> private void IndexElement(Wix.ISchemaElement element) { if (element is IIs.WebAddress) { this.webAddresses.Add(element); } else if (element is IIs.WebDir) { this.webDirs.Add(element); } else if (element is IIs.WebDirProperties) { this.webDirProperties.Add(element); } else if (element is IIs.WebFilter) { this.webFilters.Add(element); } else if (element is IIs.WebSite) { this.webSites.Add(element); } else if (element is IIs.WebVirtualDir) { this.webVirtualDirs.Add(element); } else if (element is Wix.Component) { this.components.Add(element); } else if (element is Wix.Directory) { Wix.Directory directory = (Wix.Directory)element; if (null != directory.FileSource) { this.directoryPaths.Add(directory.FileSource, directory); } } else if (element is Wix.Fragment || element is Wix.Module || element is Wix.PatchCreation || element is Wix.Package) { this.rootElement = (Wix.IParentElement)element; } // index the child elements if (element is Wix.IParentElement) { foreach (Wix.ISchemaElement childElement in ((Wix.IParentElement)element).Children) { this.IndexElement(childElement); } } }
/// <summary> /// Harvest a directory. /// </summary> /// <param name="argument">The path of the directory.</param> /// <returns>The harvested directory.</returns> public override Wix.Fragment[] Harvest(string argument) { if (null == argument) { throw new ArgumentNullException("argument"); } Wix.IParentElement harvestParent = this.HarvestDirectory(argument, true, this.GenerateType); Wix.ISchemaElement harvestElement; if (this.GenerateType == GenerateType.PayloadGroup) { Wix.PayloadGroup payloadGroup = (Wix.PayloadGroup)harvestParent; payloadGroup.Id = this.RootedDirectoryRef; harvestElement = payloadGroup; } else { Wix.Directory directory = (Wix.Directory)harvestParent; Wix.DirectoryRef directoryRef = new Wix.DirectoryRef(); directoryRef.Id = this.RootedDirectoryRef; if (this.SuppressRootDirectory) { foreach (Wix.ISchemaElement element in directory.Children) { directoryRef.AddChild(element); } } else { directoryRef.AddChild(directory); } harvestElement = directoryRef; } Wix.Fragment fragment = new Wix.Fragment(); fragment.AddChild(harvestElement); return(new Wix.Fragment[] { fragment }); }
/// <summary> /// Index an element. /// </summary> /// <param name="element">The element to index.</param> private void IndexElement(Wix.ISchemaElement element) { if (element is Wix.Component) { this.components.Add(element); } else if (element is Wix.ComponentGroup) { this.componentGroups.Add(element); } else if (element is Wix.Directory) { this.directories.Add(element); } else if (element is Wix.DirectoryRef) { this.directoryRefs.Add(element); } else if (element is Wix.Feature) { this.features.Add(element); } else if (element is Wix.File) { this.files.Add(element); } else if (element is Wix.Module || element is Wix.PatchCreation || element is Wix.Package) { Debug.Assert(null == this.rootElement); this.rootElement = (Wix.IParentElement)element; } // index the child elements if (element is Wix.IParentElement) { foreach (Wix.ISchemaElement childElement in ((Wix.IParentElement)element).Children) { this.IndexElement(childElement); } } }
/// <summary> /// Mutate an element. /// </summary> /// <param name="parentElement">The parent of the element to mutate.</param> /// <param name="element">The element to mutate.</param> private void MutateElement(Wix.IParentElement parentElement, Wix.ISchemaElement element) { if (element is Wix.File) { this.MutateFile(parentElement, (Wix.File)element); } // mutate the child elements if (element is Wix.IParentElement) { ArrayList childElements = new ArrayList(); // copy the child elements to a temporary array (to allow them to be deleted/moved) foreach (Wix.ISchemaElement childElement in ((Wix.IParentElement)element).Children) { childElements.Add(childElement); } foreach (Wix.ISchemaElement childElement in childElements) { this.MutateElement((Wix.IParentElement)element, childElement); } } }
/// <summary> /// Harvest a directory. /// </summary> /// <param name="path">The path of the directory.</param> /// <param name="relativePath">The relative path that will be used when harvesting.</param> /// <param name="harvestParent">The directory for this path.</param> /// <param name="generateType"></param> /// <returns>The number of files harvested.</returns> private int HarvestDirectory(string path, string relativePath, Wix.IParentElement harvestParent, GenerateType generateType) { int fileCount = 0; Wix.Directory directory = generateType != GenerateType.PayloadGroup ? (Wix.Directory)harvestParent : null; // harvest the child directories foreach (string childDirectoryPath in Directory.GetDirectories(path)) { var childDirectoryName = Path.GetFileName(childDirectoryPath); Wix.IParentElement newParent; Wix.Directory childDirectory = null; if (generateType == GenerateType.PayloadGroup) { newParent = harvestParent; } else { childDirectory = new Wix.Directory(); newParent = childDirectory; childDirectory.Name = childDirectoryName; childDirectory.FileSource = childDirectoryPath; if (this.SetUniqueIdentifiers) { childDirectory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, directory.Id, childDirectory.Name); } } int childFileCount = this.HarvestDirectory(childDirectoryPath, String.Concat(relativePath, childDirectoryName, "\\"), newParent, generateType); if (generateType != GenerateType.PayloadGroup) { // keep the directory if it contained any files (or empty directories are being kept) if (0 < childFileCount || this.KeepEmptyDirectories) { directory.AddChild(childDirectory); } } fileCount += childFileCount; } // harvest the files string[] files = Directory.GetFiles(path); if (0 < files.Length) { foreach (string filePath in Directory.GetFiles(path)) { string fileName = Path.GetFileName(filePath); string source = String.Concat(relativePath, fileName); Wix.ISchemaElement newChild; if (generateType == GenerateType.PayloadGroup) { Wix.Payload payload = new Wix.Payload(); newChild = payload; payload.SourceFile = source; } else { Wix.Component component = new Wix.Component(); newChild = component; Wix.File file = this.fileHarvester.HarvestFile(filePath); file.Source = source; if (this.SetUniqueIdentifiers) { file.Id = this.Core.GenerateIdentifier(FilePrefix, directory.Id, fileName); component.Id = this.Core.GenerateIdentifier(ComponentPrefix, directory.Id, file.Id); } component.AddChild(file); } harvestParent.AddChild(newChild); } } else if (generateType != GenerateType.PayloadGroup && 0 == fileCount && this.KeepEmptyDirectories) { Wix.Component component = new Wix.Component(); component.KeyPath = Wix.YesNoType.yes; if (this.SetUniqueIdentifiers) { component.Id = this.Core.GenerateIdentifier(ComponentPrefix, directory.Id); } Wix.CreateFolder createFolder = new Wix.CreateFolder(); component.AddChild(createFolder); directory.AddChild(component); } return(fileCount + files.Length); }
/// <summary> /// Mutate a Wix element. /// </summary> /// <param name="wix">The Wix element to mutate.</param> private void MutateWix(Wix.Wix wix) { if (TemplateType.Fragment != this.templateType) { if (null != this.rootElement || 0 != this.features.Count) { throw new Exception("The template option cannot be used with Feature, Package, or Module elements present."); } // create a package element although it won't always be used Wix.SummaryInformation package = new Wix.SummaryInformation(); if (TemplateType.Module == this.templateType) { package.Id = this.GetGuid(); } else { package.Compressed = Wix.YesNoType.yes; } package.InstallerVersion = 200; Wix.Directory targetDir = new Wix.Directory(); targetDir.Id = "TARGETDIR"; targetDir.Name = "SourceDir"; foreach (Wix.DirectoryRef directoryRef in this.directoryRefs) { if (String.Equals(directoryRef.Id, "TARGETDIR", StringComparison.OrdinalIgnoreCase)) { Wix.IParentElement parent = directoryRef.ParentElement as Wix.IParentElement; foreach (Wix.ISchemaElement element in directoryRef.Children) { targetDir.AddChild(element); } parent.RemoveChild(directoryRef); if (null != ((Wix.ISchemaElement)parent).ParentElement) { int i = 0; foreach (Wix.ISchemaElement element in parent.Children) { i++; } if (0 == i) { Wix.IParentElement supParent = (Wix.IParentElement)((Wix.ISchemaElement)parent).ParentElement; supParent.RemoveChild((Wix.ISchemaElement)parent); } } break; } } if (TemplateType.Module == this.templateType) { Wix.Module module = new Wix.Module(); module.Id = "PUT-MODULE-NAME-HERE"; module.Language = "1033"; module.Version = "1.0.0.0"; package.Manufacturer = "PUT-COMPANY-NAME-HERE"; module.AddChild(package); module.AddChild(targetDir); wix.AddChild(module); this.rootElement = module; } else // product { Wix.Package product = new Wix.Package(); product.Id = this.GetGuid(); product.Language = "1033"; product.Manufacturer = "PUT-COMPANY-NAME-HERE"; product.Name = "PUT-PRODUCT-NAME-HERE"; product.UpgradeCode = this.GetGuid(); product.Version = "1.0.0.0"; product.AddChild(package); product.AddChild(targetDir); Wix.Media media = new Wix.Media(); media.Id = "1"; media.Cabinet = "product.cab"; media.EmbedCab = Wix.YesNoType.yes; product.AddChild(media); Wix.Feature feature = new Wix.Feature(); feature.Id = "ProductFeature"; feature.Title = "PUT-FEATURE-TITLE-HERE"; feature.Level = 1; product.AddChild(feature); this.features.Add(feature); wix.AddChild(product); this.rootElement = product; } } }
/// <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(); if (null != this.componentGroupName) { this.CreateComponentGroup(wix); } // add the components to the product feature after all the identifiers have been set if (TemplateType.Package == this.templateType) { Wix.Feature feature = (Wix.Feature) this.features[0]; foreach (Wix.ComponentGroup group in this.componentGroups) { Wix.ComponentGroupRef componentGroupRef = new Wix.ComponentGroupRef(); componentGroupRef.Id = group.Id; feature.AddChild(componentGroupRef); } } else if (TemplateType.Module == this.templateType) { foreach (Wix.ISchemaElement element in wix.Children) { if (element is Wix.Module) { foreach (Wix.ComponentGroup group in this.componentGroups) { Wix.ComponentGroupRef componentGroupRef = new Wix.ComponentGroupRef(); componentGroupRef.Id = group.Id; ((Wix.IParentElement)element).AddChild(componentGroupRef); } break; } } } //if(!this.createFragments && TemplateType.Package foreach (Wix.Fragment fragment in this.fragments.Values) { wix.AddChild(fragment); } }
/// <summary> /// Mutate a file. /// </summary> /// <param name="parentElement">The parent of the element to mutate.</param> /// <param name="file">The file to mutate.</param> private void MutateFile(Wix.IParentElement parentElement, Wix.File file) { if (null != file.Source) { string fileExtension = Path.GetExtension(file.Source); string fileSource = this.Core.ResolveFilePath(file.Source); if (String.Equals(".ax", fileExtension, StringComparison.OrdinalIgnoreCase) || // DirectShow filter String.Equals(".dll", fileExtension, StringComparison.OrdinalIgnoreCase) || String.Equals(".exe", fileExtension, StringComparison.OrdinalIgnoreCase) || String.Equals(".ocx", fileExtension, StringComparison.OrdinalIgnoreCase)) // ActiveX { // try the assembly harvester try { AssemblyHarvester assemblyHarvester = new AssemblyHarvester(); this.Core.Messaging.Write(HarvesterVerboses.HarvestingAssembly(fileSource)); Wix.RegistryValue[] registryValues = assemblyHarvester.HarvestRegistryValues(fileSource); foreach (Wix.RegistryValue registryValue in registryValues) { parentElement.AddChild(registryValue); } // also try self-reg since we could have a mixed-mode assembly this.HarvestSelfReg(parentElement, fileSource); } catch (BadImageFormatException) // not an assembly, try raw DLL. { this.HarvestSelfReg(parentElement, fileSource); } catch (Exception ex) { this.Core.Messaging.Write(HarvesterWarnings.AssemblyHarvestFailed(fileSource, ex.Message)); } } else if (String.Equals(".olb", fileExtension, StringComparison.OrdinalIgnoreCase) || // type library String.Equals(".tlb", fileExtension, StringComparison.OrdinalIgnoreCase)) // type library { // try the type library harvester try { TypeLibraryHarvester typeLibHarvester = new TypeLibraryHarvester(); this.Core.Messaging.Write(HarvesterVerboses.HarvestingTypeLib(fileSource)); Wix.RegistryValue[] registryValues = typeLibHarvester.HarvestRegistryValues(fileSource); foreach (Wix.RegistryValue registryValue in registryValues) { parentElement.AddChild(registryValue); } } catch (COMException ce) { // 0x8002801C (TYPE_E_REGISTRYACCESS) // If we don't have permission to harvest typelibs, it's likely because we're on // Vista or higher and aren't an Admin, or don't have the appropriate QFE installed. if (!this.calledPerUserTLibReg && (0x8002801c == unchecked ((uint)ce.ErrorCode))) { this.Core.Messaging.Write(WarningMessages.InsufficientPermissionHarvestTypeLib()); } else if (0x80029C4A == unchecked ((uint)ce.ErrorCode)) // generic can't load type library { this.Core.Messaging.Write(HarvesterWarnings.TypeLibLoadFailed(fileSource, ce.Message)); } } } } }