/// <summary> /// Harvest a file. /// </summary> /// <param name="argument">The path of the file.</param> /// <returns>A harvested file.</returns> public override Wix.Fragment[] Harvest(string argument) { if (null == argument) { throw new ArgumentNullException("argument"); } if (null == this.rootedDirectoryRef) { this.rootedDirectoryRef = "TARGETDIR"; } string fullPath = Path.GetFullPath(argument); Wix.DirectoryRef directoryRef = new Wix.DirectoryRef(); directoryRef.Id = this.rootedDirectoryRef; Wix.File file = this.HarvestFile(fullPath); if (!this.suppressRootDirectory) { file.Source = String.Concat("SourceDir\\", Path.GetFileName(Path.GetDirectoryName(fullPath)), "\\", Path.GetFileName(fullPath)); } Wix.Component component = new Wix.Component(); component.AddChild(file); Wix.Directory directory = new Wix.Directory(); if (this.suppressRootDirectory) { directoryRef.AddChild(component); } else { string directoryPath = Path.GetDirectoryName(Path.GetFullPath(argument)); directory.Name = Path.GetFileName(directoryPath); if (this.setUniqueIdentifiers) { directory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, directoryRef.Id, directory.Name); } directory.AddChild(component); directoryRef.AddChild(directory); } if (this.setUniqueIdentifiers) { file.Id = this.Core.GenerateIdentifier(FilePrefix, (this.suppressRootDirectory) ? directoryRef.Id : directory.Id, Path.GetFileName(file.Source)); component.Id = this.Core.GenerateIdentifier(ComponentPrefix, (this.suppressRootDirectory) ? directoryRef.Id : directory.Id, file.Id); } Wix.Fragment fragment = new Wix.Fragment(); fragment.AddChild(directoryRef); 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 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.Directory) { Wix.Directory directory = (Wix.Directory)element; if (null != directory.Id && null != directory.FileSource) { this.directoryPaths.Add(directory.FileSource, directory.Id); } } else if (element is Wix.File) { Wix.File file = (Wix.File)element; if (null != file.Id && null != file.Source) { this.filePaths[file.Source] = String.Concat("[#", file.Id, "]"); } } // index the child elements if (element is Wix.IParentElement) { foreach (Wix.ISchemaElement childElement in ((Wix.IParentElement)element).Children) { this.IndexElement(childElement); } } }
/// <summary> /// Mutate the WebFilter elements. /// </summary> private void MutateWebFilters() { IdentifierGenerator identifierGenerator = null; if (this.setUniqueIdentifiers) { identifierGenerator = new IdentifierGenerator("WebFilter", this.Core); // index all the existing identifiers and names foreach (IIs.WebFilter webFilter in this.webFilters) { if (null != webFilter.Id) { identifierGenerator.IndexExistingIdentifier(webFilter.Id); } else { identifierGenerator.IndexName(webFilter.Name); } } } foreach (IIs.WebFilter webFilter in this.webFilters) { if (this.setUniqueIdentifiers && null == webFilter.Id) { webFilter.Id = identifierGenerator.GetIdentifier(webFilter.Name); } // harvest the file for this WebFilter Wix.Directory directory = this.HarvestUniqueDirectory(Path.GetDirectoryName(webFilter.Path), false); Wix.Component component = new Wix.Component(); directory.AddChild(component); Wix.File file = this.fileHarvester.HarvestFile(webFilter.Path); component.AddChild(file); } }
/// <summary> /// Harvest a file. /// </summary> /// <param name="path">The path of the file.</param> /// <returns>A harvested file.</returns> public Wix.File HarvestFile(string path) { if (null == path) { throw new ArgumentNullException("path"); } if (!File.Exists(path)) { throw new WixException(HarvesterErrors.FileNotFound(path)); } Wix.File file = new Wix.File(); // use absolute paths path = Path.GetFullPath(path); file.KeyPath = Wix.YesNoType.yes; file.Source = String.Concat("SourceDir\\", Path.GetFileName(path)); return(file); }
/// <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 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)); } } } } }