/// <summary> /// Harvest a reg file. /// </summary> /// <param name="path">The path of the file.</param> /// <returns>A harvested registy file.</returns> public Wix.Fragment HarvestRegFile(string path) { if (null == path) { throw new ArgumentNullException("path"); } if (!File.Exists(path)) { throw new WixException(UtilErrors.FileNotFound(path)); } Wix.Directory directory = new Wix.Directory(); directory.Id = "TARGETDIR"; // Use absolute paths path = Path.GetFullPath(path); FileInfo file = new FileInfo(path); using (StreamReader sr = file.OpenText()) { string line; this.currentLineNumber = 0; while (null != (line = this.GetNextLine(sr))) { if (line.StartsWith(@"Windows Registry Editor Version 5.00")) { this.unicodeRegistry = true; } else if (line.StartsWith(@"REGEDIT4")) { this.unicodeRegistry = false; } else if (line.StartsWith(@"[HKEY_CLASSES_ROOT\")) { this.ConvertKey(sr, ref directory, Wix.RegistryRootType.HKCR, line.Substring(19, line.Length - 20)); } else if (line.StartsWith(@"[HKEY_CURRENT_USER\")) { this.ConvertKey(sr, ref directory, Wix.RegistryRootType.HKCU, line.Substring(19, line.Length - 20)); } else if (line.StartsWith(@"[HKEY_LOCAL_MACHINE\")) { this.ConvertKey(sr, ref directory, Wix.RegistryRootType.HKLM, line.Substring(20, line.Length - 21)); } else if (line.StartsWith(@"[HKEY_USERS\")) { this.ConvertKey(sr, ref directory, Wix.RegistryRootType.HKU, line.Substring(12, line.Length - 13)); } } } Console.WriteLine("Processing complete"); Wix.Fragment fragment = new Wix.Fragment(); fragment.AddChild(directory); return(fragment); }
/// <summary> /// Mutate the directories. /// </summary> private void MutateDirectories() { foreach (Wix.Directory directory in this.directories) { string path = directory.FileSource; // create a new directory element without the FileSource attribute if (null != path) { Wix.Directory newDirectory = new Wix.Directory(); newDirectory.Id = directory.Id; newDirectory.Name = directory.Name; foreach (Wix.ISchemaElement element in directory.Children) { newDirectory.AddChild(element); } ((Wix.IParentElement)directory.ParentElement).AddChild(newDirectory); ((Wix.IParentElement)directory.ParentElement).RemoveChild(directory); if (null != newDirectory.Id) { this.directoryPaths[path.ToLower(CultureInfo.InvariantCulture)] = String.Concat("[", newDirectory.Id, "]"); } } } }
/// <summary> /// Harvest a WiX document. /// </summary> /// <param name="argument">The argument for harvesting.</param> /// <returns>The harvested Fragment.</returns> public override Wix.Fragment[] Harvest(string argument) { DirectoryHarvester directoryHarvester = new DirectoryHarvester(); directoryHarvester.Core = this.Core; directoryHarvester.KeepEmptyDirectories = true; IIsWebSiteHarvester iisWebSiteHarvester = new IIsWebSiteHarvester(); iisWebSiteHarvester.Core = this.Core; IIs.WebSite webSite = iisWebSiteHarvester.HarvestWebSite(argument); Wix.Component component = new Wix.Component(); component.AddChild(new Wix.CreateFolder()); component.AddChild(webSite); this.Core.RootDirectory = webSite.Directory; Wix.Directory directory = directoryHarvester.HarvestDirectory(webSite.Directory, true); directory.AddChild(component); Wix.Fragment fragment = new Wix.Fragment(); fragment.AddChild(directory); return(new Wix.Fragment[] { fragment }); }
private static void WriteWxsFile(string sOutputWxs, List <RegistryKey> wixKeys, List <RegistryValue> wixValues) { var wix = new Wix(); var wixFragment = new Fragment(); wix.AddChild(wixFragment); var wixDirectory = new Directory(); wixFragment.AddChild(wixDirectory); wixDirectory.Id = ""; var wixComponent = new Component(); wixDirectory.AddChild(wixComponent); wixComponent.Id = ""; wixComponent.Guid = "*"; foreach (RegistryKey wixKey in wixKeys) { wixComponent.AddChild(wixKey); } foreach (RegistryValue wixValue in wixValues) { wixComponent.AddChild(wixValue); } // Save to the output file using (var xw = new XmlTextWriter(new FileStream(sOutputWxs, FileMode.Create, FileAccess.Write, FileShare.Read), Encoding.UTF8)) { xw.Formatting = Formatting.Indented; wix.OutputXml(xw); } }
/// <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"); } Wix.File file = this.HarvestFile(argument); Wix.Component component = new Wix.Component(); component.AddChild(file); string directoryPath = Path.GetDirectoryName(Path.GetFullPath(argument)); Wix.Directory directory = new Wix.Directory(); directory.FileSource = directoryPath; directory.Name = Path.GetFileName(directoryPath); directory.AddChild(component); Wix.DirectoryRef directoryRef = new Wix.DirectoryRef(); directoryRef.Id = "TARGETDIR"; directoryRef.AddChild(directory); Wix.Fragment fragment = new Wix.Fragment(); fragment.AddChild(directoryRef); return(fragment); }
/// <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); }
protected Directory GetChildDirectoryByName(Directory parent, string name) { if (string.IsNullOrEmpty(name)) { return(parent); } foreach (ISchemaElement element in parent.Children) { if (element is Directory) { if (((Directory)element).Name == name) { return(element as Directory); } } } // Not found so create it. Directory directory = CreateDirectoryByParentId(parent.Id, name); parent.AddChild(directory); return(directory); }
/// <summary> /// Harvest a directory. /// </summary> /// <param name="path">The path of the directory.</param> /// <param name="harvestChildren">The option to harvest child directories and files.</param> /// <returns>The harvested directory.</returns> public Wix.Directory HarvestDirectory(string path, bool harvestChildren) { if (null == path) { throw new ArgumentNullException("path"); } Wix.Directory directory = new Wix.Directory(); // use absolute paths path = Path.GetFullPath(path); directory.FileSource = path; directory.Name = Path.GetFileName(path); if (harvestChildren) { try { int fileCount = this.HarvestDirectory(path, directory); // its an error to not harvest anything with the option to keep empty directories off if (0 == fileCount && !this.keepEmptyDirectories) { throw new WixException(UtilErrors.EmptyDirectory(path)); } } catch (DirectoryNotFoundException) { throw new WixException(UtilErrors.DirectoryNotFound(path)); } } return(directory); }
/// <summary> /// Gets the directory object for the provided application root path. /// </summary> /// <param name="recalculate">Flag to recalculate root directory.</param> /// <returns>Directory harvested from root.</returns> public Wix.Directory GetRootDirectory(bool recalculate) { if (null == this.source) { throw new ArgumentNullException("RootPath"); } if (recalculate || null == this.rootDirectory) { DirectoryHarvester directoryHarvester = new DirectoryHarvester(); this.rootDirectory = directoryHarvester.HarvestDirectory(this.source, true); Wix.Wix wix = new Wix.Wix(); Wix.Fragment fragment = new Wix.Fragment(); wix.AddChild(fragment); fragment.AddChild(this.rootDirectory); UtilMutator utilMutator = new UtilMutator(); utilMutator.GenerateGuids = true; utilMutator.SetUniqueIdentifiers = true; utilMutator.Mutate(wix); UtilFinalizeHarvesterMutator finalMutator = new UtilFinalizeHarvesterMutator(); finalMutator.Mutate(wix); } return(this.rootDirectory); }
/// <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.Directory directory = this.HarvestDirectory(argument, "SourceDir\\", true); 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); } Wix.Fragment fragment = new Wix.Fragment(); fragment.AddChild(directoryRef); return(new Wix.Fragment[] { fragment }); }
/// <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="harvestChildren">The option to harvest child directories and files.</param> /// <returns>The harvested directory.</returns> public Wix.Directory HarvestDirectory(string path, string relativePath, bool harvestChildren) { if (null == path) { throw new ArgumentNullException("path"); } if (File.Exists(path)) { throw new WixException(WixErrors.ExpectedDirectoryGotFile("dir", path)); } if (null == this.rootedDirectoryRef) { this.rootedDirectoryRef = "TARGETDIR"; } // use absolute paths path = Path.GetFullPath(path); // Remove any trailing separator to ensure Path.GetFileName() will return the directory name. path = path.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); Wix.Directory directory = new Wix.Directory(); directory.Name = Path.GetFileName(path); directory.FileSource = path; if (this.setUniqueIdentifiers) { if (this.suppressRootDirectory) { directory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, this.rootedDirectoryRef); } else { directory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, this.rootedDirectoryRef, directory.Name); } } if (harvestChildren) { try { int fileCount = this.HarvestDirectory(path, relativePath, directory); // its an error to not harvest anything with the option to keep empty directories off if (0 == fileCount && !this.keepEmptyDirectories) { throw new WixException(UtilErrors.EmptyDirectory(path)); } } catch (DirectoryNotFoundException) { throw new WixException(UtilErrors.DirectoryNotFound(path)); } } return(directory); }
private void LoadGacAssembly(bool isWin64, Artifact artifact, string rootFolderPath, Directory rootDirectory) { // Create a new component for the gac assembly using the gac guid. string guid = artifact.GetMetadata(Constants.Catalogue.Artifact.GacGuid); if (string.IsNullOrEmpty(guid)) { guid = System.Guid.Empty.ToString(); } Component component = CreateComponent(isWin64, artifact.ProjectRelativePath, new System.Guid(guid), Wix.Xml.Id.GacPrefix); // Put the component into a special directory. Directory gacDirectory = GetDirectory(rootDirectory, "Gac"); gacDirectory.AddChild(component); // Create a file, not adding the assembly application property. File file = CreateFile(artifact.ProjectRelativePath, FilePath.GetAbsolutePath(artifact.ProjectRelativePath, rootFolderPath), Wix.Xml.Id.GacPrefix); component.AddChild(file); file.KeyPath = YesNoType.yes; file.Assembly = File.AssemblyType.net; }
/// <summary> /// Harvest a reg file. /// </summary> /// <param name="path">The path of the file.</param> /// <returns>A harvested registy file.</returns> public Wix.Fragment HarvestRegFile(string path) { if (null == path) { throw new ArgumentNullException("path"); } if (!File.Exists(path)) { throw new WixException(UtilErrors.FileNotFound(path)); } Wix.Directory directory = new Wix.Directory(); directory.Id = "TARGETDIR"; // Use absolute paths path = Path.GetFullPath(path); FileInfo file = new FileInfo(path); using (StreamReader sr = file.OpenText()) { string line; this.currentLineNumber = 0; while (null != (line = this.GetNextLine(sr))) { if (line.StartsWith(@"Windows Registry Editor Version 5.00")) { this.unicodeRegistry = true; } else if (line.StartsWith(@"REGEDIT4")) { this.unicodeRegistry = false; } else if (line.StartsWith(@"[HKEY_CLASSES_ROOT\")) { this.ConvertKey(sr, ref directory, Wix.RegistryRootType.HKCR, line.Substring(19, line.Length - 20)); } else if (line.StartsWith(@"[HKEY_CURRENT_USER\")) { this.ConvertKey(sr, ref directory, Wix.RegistryRootType.HKCU, line.Substring(19, line.Length - 20)); } else if (line.StartsWith(@"[HKEY_LOCAL_MACHINE\")) { this.ConvertKey(sr, ref directory, Wix.RegistryRootType.HKLM, line.Substring(20, line.Length - 21)); } else if (line.StartsWith(@"[HKEY_USERS\")) { this.ConvertKey(sr, ref directory, Wix.RegistryRootType.HKU, line.Substring(12, line.Length - 13)); } } } Console.WriteLine("Processing complete"); Wix.Fragment fragment = new Wix.Fragment(); fragment.AddChild(directory); return fragment; }
protected Directory CreateDirectory(string id, string name) { Directory directory = new Directory(); directory.Id = id; directory.Name = name; return(directory); }
protected Directory CreateDirectoryByParentId(string parentId, string name) { Directory directory = new Directory(); directory.Id = CreateDirectoryId(parentId, name); directory.Name = name; return(directory); }
/// <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> /// Gets the file object for the ApplicationEntry. /// </summary> public Wix.File GetApplicationEntryFile() { if (null != this.applicationRoot && null != this.applicationEntry.Content && null == this.applicationEntryFile) { Wix.Directory applicationDir = this.GetApplicationRootDirectory(); this.applicationEntryFile = this.GetFile(this.applicationEntry.Content, this.applicationRootDirectory); } return(this.applicationEntryFile); }
/// <summary> /// Converts the registry key to a WiX component element. /// </summary> /// <param name="sr">The registry file stream.</param> /// <param name="directory">A WiX directory reference.</param> /// <param name="root">The root key.</param> /// <param name="line">The current line.</param> private void ConvertKey(StreamReader sr, ref Wix.Directory directory, Wix.RegistryRootType root, string line) { Wix.Component component = new Wix.Component(); component.Id = this.Core.GenerateIdentifier(ComponentPrefix, line); component.KeyPath = Wix.YesNoType.yes; this.ConvertValues(sr, ref component, root, line); directory.AddChild(component); }
private void CreateShortcut(Artifact artifact, Directory directory, string shortcutName, string shortcutPath, File file) { if (string.IsNullOrEmpty(shortcutName)) { shortcutName = Path.GetFileNameWithoutExtension(file.Name); } // Create the shortcut. Shortcut shortcut = CreateShortcut(artifact.ProjectRelativePath, shortcutName); if (directory != null) { shortcut.WorkingDirectory = directory.Id; } file.AddChild(shortcut); // Need to add the shortcut directory. Directory targetDirectory = GetTargetDirectory(file); Directory programMenuDirectory = GetChildDirectory(targetDirectory, Wix.Xml.Directory.ProgramMenu.Id, Wix.Xml.Directory.ProgramMenu.Name); Directory shortcutDirectory; if (string.IsNullOrEmpty(shortcutPath)) { shortcutDirectory = programMenuDirectory; } else { // Create an application directory with a fixed id (not sure why this has to be like this but tried a few variations which did not seem to work). string name; int pos = shortcutPath.IndexOf('\\'); if (pos == -1) { name = shortcutPath; shortcutPath = string.Empty; } else { name = shortcutPath.Substring(pos); shortcutPath = shortcutPath.Substring(pos + 1); } Directory appProgramMenuDirectory = GetChildDirectory(programMenuDirectory, Wix.Xml.Directory.AppProgramMenu.Id, name); shortcutDirectory = appProgramMenuDirectory; if (!string.IsNullOrEmpty(shortcutPath)) { shortcutDirectory = GetDirectory(shortcutDirectory, shortcutPath); } } shortcut.Directory = shortcutDirectory.Id; }
/// <summary> /// Creates a new or uses the root directory to add the newly-created component with files being installed. /// </summary> private void ConvertFiles_AddToDirectory(FolderXml folderxml, Component wixComponent, DirectoryRef wixDirectoryRef) { if (folderxml.TargetRoot != TargetRootXml.InstallDir) { throw new InvalidOperationException(string.Format("Only the InstallDir target root is supported.")); } // No relative path — nothing to create if (folderxml.TargetDir.Length == 0) { wixDirectoryRef.AddChild(wixComponent); return; } // Create the folder structure, add to the innermost string[] arDirectoryChain = folderxml.TargetDir.Split('\\'); Directory wixParentDir = null; for (int a = 0; a < arDirectoryChain.Length; a++) { bool bInnermost = a == arDirectoryChain.Length - 1; // Whether this is the folder in which are the files itself // Create var wixDirectory = new Directory { Name = arDirectoryChain[a] }; // Mount self into the hierarchy if (wixParentDir != null) { wixParentDir.AddChild(wixDirectory); // Previous dir } else { wixDirectoryRef.AddChild(wixDirectory); // The very root } wixParentDir = wixDirectory; // Non-innermost folders get a suffix to their ID if (bInnermost) { wixDirectory.Id = string.Format("{0}.{1}", DirectoryIdPrefix, folderxml.Id); } else { wixDirectory.Id = string.Format("{0}.{1}.P{2}", DirectoryIdPrefix, folderxml.Id, arDirectoryChain.Length - 1 - a); } // Mount the component into the innermost dir if (bInnermost) { wixDirectory.AddChild(wixComponent); } } }
/// <summary> /// Add a scraped directory to the UI. /// </summary> /// <param name="nodes">The NodeCollection under which the new directory should be added.</param> /// <param name="rootDirectory">Root of the scraped directory info's.</param> /// <param name="directory">The scraped directory to add.</param> /// <param name="skip">true if the directory itself shouldn't be added; false otherwise.</param> private void AddDirectory(TreeNodeCollection nodes, string currentPath, Wix.Directory rootDirectory, Wix.Directory directory, bool skip) { // get the directory icon, add it to the image list, then free it immediately if (!skip) { Icon folderIcon = NativeMethods.GetDirectoryIcon(true, false); DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(currentPath, directory.Name)); TreeNode node = (TreeNode)this.Invoke(this.addTreeNodeCallback, new object[] { nodes, folderIcon, directory.Name, directoryInfo, false }); folderIcon.Dispose(); // add sub-directories and files to this node nodes = node.Nodes; currentPath = Path.Combine(currentPath, directory.Name); } foreach (Wix.ISchemaElement element in directory.Children) { Wix.Component component = element as Wix.Component; if (null != component) { foreach (Wix.ISchemaElement child in component.Children) { Wix.File file = child as Wix.File; if (null != file) { bool selected = false; FileInfo fileInfo = new FileInfo(Path.Combine(currentPath, file.Name)); // if there is no application entry point and we've found an executable make this the application entry point if (this.packageBuilder.ApplicationEntry == null && String.Compare(fileInfo.Extension, ".exe", true, CultureInfo.InvariantCulture) == 0) { //this.packageBuilder.ApplicationEntry = fileInfo.FullName.Substring(rootDirectory.FullName.Length + 1); selected = true; } // get the file icon, add it to the image list, then free it immediately Icon fileIcon = NativeMethods.GetFileIcon(fileInfo.FullName, true, false); this.Invoke(this.addTreeNodeCallback, new object[] { nodes, fileIcon, file.Name, fileInfo, selected }); fileIcon.Dispose(); } } } else { Wix.Directory subDirectory = element as Wix.Directory; if (null != subDirectory) { this.AddDirectory(nodes, currentPath, rootDirectory, subDirectory, false); } } } }
/// <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); }
/// <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.Product) { 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> /// Returns the File matching the relative path in the Directory tree. /// </summary> /// <param name="relativePath">Relative path to the file to find in the directory.</param> /// <param name="directory">Directory tree to search for relative path in.</param> private Wix.File GetFile(string relativePath, Wix.Directory rootDirectory) { IEnumerable enumerable = rootDirectory.Children; string[] directory = relativePath.Split(Path.DirectorySeparatorChar); for (int i = 0; i < directory.Length; ++i) { bool found = false; if (i < directory.Length - 1) { foreach (Wix.ISchemaElement element in enumerable) { Wix.Directory childDirectory = element as Wix.Directory; if (null != childDirectory && directory[i] == childDirectory.Name) { enumerable = childDirectory.Children; found = true; break; } } } else { foreach (Wix.ISchemaElement element in enumerable) { Wix.Component component = element as Wix.Component; if (null != component) { foreach (Wix.ISchemaElement child in component.Children) { Wix.File file = child as Wix.File; if (null != file && directory[i] == file.Name) { return(file); } } } } } if (!found) { throw new ApplicationException("Did not find file name"); } } return(null); }
public void Load(bool isWin64, Catalogue catalogue) { // Get the root folder path. string rootFolderPath; if (string.IsNullOrEmpty(catalogue.RootFolder)) { rootFolderPath = Path.GetDirectoryName(catalogue.FullPath); } else { rootFolderPath = FilePath.GetAbsolutePath(catalogue.RootFolder, Path.GetDirectoryName(catalogue.FullPath)); } // Create the module element. Module module = CreateModule(); Wix.AddChild(module); // Create the package element. Microsoft.Tools.WindowsInstallerXml.Serialize.Package package = CreatePackage(isWin64); module.AddChild(package); // Create a target directory element. Directory directory = CreateDirectory(Constants.Wix.Xml.Directory.Target.Id, Constants.Wix.Xml.Directory.Target.Name); module.AddChild(directory); // Load the artifacts in the catalogue. foreach (Artifact artifact in catalogue.Artifacts) { Load(isWin64, artifact, rootFolderPath, directory); } // Add the catalogue file itself. Artifact catalogueArtifact = new Artifact(FilePath.GetRelativePath(catalogue.FullPath, rootFolderPath)); catalogueArtifact.SetMetadata(Constants.Catalogue.Artifact.Guid, catalogue.Guid); Load(isWin64, catalogueArtifact, rootFolderPath, directory); // Resolve all elements. Resolve(directory); }
/// <summary> /// Harvest a directory. /// </summary> /// <param name="path">The path of the directory.</param> /// <param name="directory">The directory for this path.</param> /// <returns>The number of files harvested.</returns> private int HarvestDirectory(string path, Wix.Directory directory) { int fileCount = 0; // harvest the child directories foreach (string childDirectoryPath in Directory.GetDirectories(path)) { Wix.Directory childDirectory = new Wix.Directory(); childDirectory.FileSource = childDirectoryPath; childDirectory.Name = Path.GetFileName(childDirectoryPath); int childFileCount = this.HarvestDirectory(childDirectoryPath, childDirectory); // 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)) { Wix.Component component = new Wix.Component(); Wix.File file = this.fileHarvester.HarvestFile(filePath); component.AddChild(file); directory.AddChild(component); } } else if (0 == fileCount && this.keepEmptyDirectories) { Wix.Component component = new Wix.Component(); component.KeyPath = Wix.YesNoType.yes; Wix.CreateFolder createFolder = new Wix.CreateFolder(); component.AddChild(createFolder); directory.AddChild(component); } return(fileCount + files.Length); }
/// <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.Directory directory = this.HarvestDirectory(argument, true); Wix.Fragment fragment = new Wix.Fragment(); fragment.AddChild(directory); return(fragment); }
protected static void Resolve(Directory directory) { WixPathResolver pathResolver = new WixPathResolver(); pathResolver.Resolve(directory); // There seems to be a problem with Wix for .NET classes as COM objects // where it doesn't seem to handle the InprocServer32 being set to mscoree.dll // properly. Get a "is duplicated in table 'Registry'" error. // Just leave as raw registry entries for now and don't // try to resolve. Whilst not as nice the end result should be equivalent. //WixComResolver comResolver = new WixComResolver(); //comResolver.Resolve(directory); }
protected Directory GetDirectory(Directory parent, string projectRelativePath) { string[] folders = projectRelativePath.Split(Path.DirectorySeparatorChar); Directory directory = parent; for (int index = 0; index < folders.Length; ++index) { string folder = folders[index]; if (folder != ".") { directory = GetChildDirectoryByName(directory, folder); } } return(directory); }
/// <summary> /// Gets the directory object for the ApplicationRoot. /// </summary> public Wix.Directory GetApplicationRootDirectory() { if (null != this.applicationRoot && null == this.applicationRootDirectory) { this.applicationRootDirectory = this.directoryHarvester.HarvestDirectory(this.applicationRoot.Content, true); Wix.Wix wix = new Wix.Wix(); Wix.Fragment fragment = new Wix.Fragment(); wix.AddChild(fragment); fragment.AddChild(this.applicationRootDirectory); this.utilMutator.Mutate(wix); this.finalMutator.Mutate(wix); } return(this.applicationRootDirectory); }
/// <summary> /// Harvest a new directory or return one that was previously harvested. /// </summary> /// <param name="path">The path of the directory.</param> /// <param name="harvestChildren">The option to harvest the children of the directory.</param> /// <returns>The harvested directory.</returns> private Wix.Directory HarvestUniqueDirectory(string path, bool harvestChildren) { if (this.directoryPaths.Contains(path)) { return((Wix.Directory) this.directoryPaths[path]); } else { Wix.Directory directory = this.directoryHarvester.HarvestDirectory(path, harvestChildren); this.rootElement.AddChild(directory); // index this new directory and all of its children this.IndexElement(directory); return(directory); } }
/// <summary> /// Harvest a performance category. /// </summary> /// <param name="argument">The name of the performance category.</param> /// <returns>A harvested performance category.</returns> public override Wix.Fragment[] Harvest(string argument) { if (null == argument) { throw new ArgumentNullException("argument"); } Util.PerformanceCategory perf = this.HarvestPerformanceCategory(argument); Wix.Component component = new Wix.Component(); component.Id = CompilerCore.GetIdentifierFromName(argument); component.KeyPath = Wix.YesNoType.yes; component.AddChild(perf); Wix.Directory directory = new Wix.Directory(); directory.Id = "TARGETDIR"; //directory.Name = directory.Id; directory.AddChild(component); Wix.Fragment fragment = new Wix.Fragment(); fragment.AddChild(directory); return new Wix.Fragment[] { fragment }; }
private void MutateDirectories() { foreach (Wix.Directory directory in this.directories) { string path = directory.FileSource; // create a new directory element without the FileSource attribute if (null != path) { Wix.Directory newDirectory = new Wix.Directory(); newDirectory.Id = directory.Id; newDirectory.Name = directory.Name; foreach (Wix.ISchemaElement element in directory.Children) { newDirectory.AddChild(element); } ((Wix.IParentElement)directory.ParentElement).AddChild(newDirectory); ((Wix.IParentElement)directory.ParentElement).RemoveChild(directory); if (null != newDirectory.Id) { this.directoryPaths[path.ToLower(CultureInfo.InvariantCulture)] = String.Concat("[", newDirectory.Id, "]"); } } } }
private void HarvestProjectOutputGroupFile(string baseDir, string projectName, string pogName, string pogFileSource, string filePath, string fileName, string link, Wix.IParentElement parentDir, string parentDirId, Wix.Component component, Wix.File file, Dictionary<string, bool> seenList) { string varFormat = VariableFormat; if (this.generateWixVars) { varFormat = WixVariableFormat; } if (pogName.Equals("Satellites", StringComparison.OrdinalIgnoreCase)) { Wix.Directory locDirectory = new Wix.Directory(); locDirectory.Name = Path.GetFileName(Path.GetDirectoryName(Path.GetFullPath(filePath))); file.Source = String.Concat(String.Format(CultureInfo.InvariantCulture, varFormat, projectName, pogFileSource), "\\", locDirectory.Name, "\\", Path.GetFileName(filePath)); if (!seenList.ContainsKey(file.Source)) { parentDir.AddChild(locDirectory); locDirectory.AddChild(component); component.AddChild(file); seenList.Add(file.Source, true); if (this.setUniqueIdentifiers) { locDirectory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, parentDirId, locDirectory.Name); file.Id = this.Core.GenerateIdentifier(FilePrefix, locDirectory.Id, fileName); component.Id = this.Core.GenerateIdentifier(ComponentPrefix, locDirectory.Id, file.Id); } else { locDirectory.Id = HarvesterCore.GetIdentifierFromName(String.Format(DirectoryIdFormat, (parentDir is Wix.DirectoryRef) ? ((Wix.DirectoryRef)parentDir).Id : parentDirId, locDirectory.Name)); file.Id = HarvesterCore.GetIdentifierFromName(String.Format(CultureInfo.InvariantCulture, VSProjectHarvester.FileIdFormat, projectName, pogName, String.Concat(locDirectory.Name, ".", fileName))); component.Id = HarvesterCore.GetIdentifierFromName(String.Format(CultureInfo.InvariantCulture, VSProjectHarvester.ComponentIdFormat, projectName, pogName, String.Concat(locDirectory.Name, ".", fileName))); } } } else { file.Source = GenerateSourceFilePath(baseDir, projectName, pogFileSource, filePath, link, varFormat); if (!seenList.ContainsKey(file.Source)) { component.AddChild(file); parentDir.AddChild(component); seenList.Add(file.Source, true); if (this.setUniqueIdentifiers) { file.Id = this.Core.GenerateIdentifier(FilePrefix, parentDirId, fileName); component.Id = this.Core.GenerateIdentifier(ComponentPrefix, parentDirId, file.Id); } else { file.Id = HarvesterCore.GetIdentifierFromName(String.Format(CultureInfo.InvariantCulture, VSProjectHarvester.FileIdFormat, projectName, pogName, fileName)); component.Id = HarvesterCore.GetIdentifierFromName(String.Format(CultureInfo.InvariantCulture, VSProjectHarvester.ComponentIdFormat, projectName, pogName, fileName)); } } } }
/// <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, Product, or Module elements present."); } // create a package element although it won't always be used Wix.Package package = new Wix.Package(); 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.Product product = new Wix.Product(); 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> /// 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> /// 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="harvestChildren">The option to harvest child directories and files.</param> /// <returns>The harvested directory.</returns> public Wix.Directory HarvestDirectory(string path, string relativePath, bool harvestChildren) { if (null == path) { throw new ArgumentNullException("path"); } if (File.Exists(path)) { throw new WixException(WixErrors.ExpectedDirectoryGotFile("dir", path)); } if (null == this.rootedDirectoryRef) { this.rootedDirectoryRef = "TARGETDIR"; } // use absolute paths path = Path.GetFullPath(path); // Remove any trailing separator to ensure Path.GetFileName() will return the directory name. path = path.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); Wix.Directory directory = new Wix.Directory(); directory.Name = Path.GetFileName(path); directory.FileSource = path; if (this.setUniqueIdentifiers) { if (this.suppressRootDirectory) { directory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, this.rootedDirectoryRef); } else { directory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, this.rootedDirectoryRef, directory.Name); } } if (harvestChildren) { try { int fileCount = this.HarvestDirectory(path, relativePath, directory); // its an error to not harvest anything with the option to keep empty directories off if (0 == fileCount && !this.keepEmptyDirectories) { throw new WixException(UtilErrors.EmptyDirectory(path)); } } catch (DirectoryNotFoundException) { throw new WixException(UtilErrors.DirectoryNotFound(path)); } } return directory; }
/// <summary> /// Decompile the Directory table. /// </summary> /// <param name="table">The table to decompile.</param> private void DecompileDirectoryTable(Table table) { foreach (Row row in table.Rows) { Wix.Directory directory = new Wix.Directory(); directory.Id = Convert.ToString(row[0]); string[] names = Installer.GetNames(Convert.ToString(row[2])); if (String.Equals(directory.Id, "TARGETDIR", StringComparison.Ordinal) && !String.Equals(names[0], "SourceDir", StringComparison.Ordinal)) { this.core.OnMessage(WixWarnings.TargetDirCorrectedDefaultDir()); directory.Name = "SourceDir"; } else { if (null != names[0] && "." != names[0]) { if (null != names[1]) { directory.ShortName = names[0]; } else { directory.Name = names[0]; } } if (null != names[1]) { directory.Name = names[1]; } } if (null != names[2]) { if (null != names[3]) { directory.ShortSourceName = names[2]; } else { directory.SourceName = names[2]; } } if (null != names[3]) { directory.SourceName = names[3]; } this.core.IndexElement(row, directory); } // nest the directories foreach (Row row in table.Rows) { Wix.Directory directory = (Wix.Directory)this.core.GetIndexedElement(row); if (null == row[1]) { this.core.RootElement.AddChild(directory); } else { Wix.Directory parentDirectory = (Wix.Directory)this.core.GetIndexedElement("Directory", Convert.ToString(row[1])); if (null == parentDirectory) { this.core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerCore.PrimaryKeyDelimiter), "Directory_Parent", Convert.ToString(row[1]), "Directory")); } else if (parentDirectory == directory) // another way to specify a root directory { this.core.RootElement.AddChild(directory); } else { parentDirectory.AddChild(directory); } } } }
/// <summary> /// Builds a setup package to the specified output path. /// </summary> /// <param name="outputPath">Location to build the setup package to.</param> /// <param name="outputSourcePath">Optional path where the package's .wxs file will be written.</param> public bool Build(string outputPath, string outputSourcePath) { this.buildError = null; // clear out any previous errors int currentProgress = 0; int totalProgress = 7; // calculate the upper progress if (outputSourcePath != null) { ++totalProgress; } if (this.previousPackagePath != null) { ++totalProgress; } this.VerifyRequiredInformation(); if (!this.OnProgress(currentProgress++, totalProgress, "Initialized package builder...")) { return false; } // Calculate where everything is going string localSetupExe = outputPath; string localSetupFeed = Path.Combine(Path.GetDirectoryName(outputPath), Path.GetFileName(this.updateUrl.AbsolutePath)); Uri urlSetupExe = new Uri(this.updateUrl, Path.GetFileName(localSetupExe)); Uri urlSetupFeed = new Uri(this.updateUrl, Path.GetFileName(localSetupFeed)); Guid previousUpgradeCode = Guid.Empty; Version previousVersion = null; Uri previousSetupFeed = null; // if a previous package was provided, go read the key information out of it now if (this.previousPackagePath != null) { if (!this.OnProgress(currentProgress++, totalProgress, "Reading previous package...")) { return false; } this.ReadPreviousPackage(this.previousPackagePath, out previousUpgradeCode, out previousVersion, out previousSetupFeed); } // // if a upgrade code and/or version has not been specified use one // from the previous package or create new. // if (this.upgradeCode == Guid.Empty) { if (previousUpgradeCode == Guid.Empty) { this.upgradeCode = Guid.NewGuid(); } else { this.upgradeCode = previousUpgradeCode; } } if (this.version == null) { if (previousVersion == null) { FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(Path.Combine(this.applicationRoot.Content, this.applicationEntry.Content)); this.version = new Version(fileVersionInfo.FileVersion); } else { this.version = previousVersion; } } // verify that new data is okay when compared to previous package if (previousUpgradeCode != Guid.Empty && previousUpgradeCode != this.upgradeCode) { this.OnMessage(ClickThroughErrors.UpgradeCodeChanged(previousUpgradeCode, this.upgradeCode)); } if (previousVersion != null && previousVersion >= this.version) { this.OnMessage(ClickThroughErrors.NewVersionIsNotGreater(previousVersion, this.version)); } if (this.buildError != null) { throw new InvalidOperationException(String.Format(this.buildError.ResourceManager.GetString(this.buildError.ResourceName), this.buildError.MessageArgs)); } else if (!this.OnProgress(currentProgress++, totalProgress, "Processing package information...")) { return false; } // Product information Application application = new Application(); application.Product.Id = Guid.NewGuid().ToString(); application.Product.Language = "1033"; application.Product.Manufacturer = this.manufacturerName.Content; application.Product.Name = this.applicationName.Content; application.Package.Description = this.description.Content; application.Product.UpgradeCode = this.upgradeCode.ToString(); application.Product.Version = this.version.ToString(); Wix.WixVariable variable = new Wix.WixVariable(); variable = new Wix.WixVariable(); variable.Id = "ProductName"; variable.Value = application.Product.Name; application.Product.AddChild(variable); variable = new Wix.WixVariable(); variable.Id = "ProductCode"; variable.Value = application.Product.Id; application.Product.AddChild(variable); variable = new Wix.WixVariable(); variable.Id = "ProductVersion"; variable.Value = application.Product.Version; application.Product.AddChild(variable); variable = new Wix.WixVariable(); variable.Id = "ShortcutFileId"; variable.Value = "todoFileIdHere"; application.Product.AddChild(variable); // Upgrade logic Wix.Upgrade upgrade = new Wix.Upgrade(); upgrade.Id = application.Product.UpgradeCode; application.Product.AddChild(upgrade); Wix.UpgradeVersion minUpgrade = new Wix.UpgradeVersion(); minUpgrade.Minimum = application.Product.Version; minUpgrade.OnlyDetect = Wix.YesNoType.yes; minUpgrade.Property = "NEWERVERSIONDETECTED"; upgrade.AddChild(minUpgrade); Wix.UpgradeVersion maxUpgrade = new Wix.UpgradeVersion(); maxUpgrade.Maximum = application.Product.Version; maxUpgrade.IncludeMaximum = Wix.YesNoType.no; maxUpgrade.Property = "OLDERVERSIONBEINGUPGRADED"; upgrade.AddChild(maxUpgrade); // Update Feed Wix.Property property = new Wix.Property(); property.Id = "ARPURLUPDATEINFO"; property.Value = urlSetupFeed.AbsoluteUri; application.Product.AddChild(property); #if false // Directory tree Wix.DirectoryRef applicationCacheRef = new Wix.DirectoryRef(); applicationCacheRef.Id = "ApplicationsCacheFolder"; application.Product.AddChild(applicationCacheRef); #endif Wix.DirectoryRef directoryRef = new Wix.DirectoryRef(); directoryRef.Id = "ApplicationsFolder"; application.Product.AddChild(directoryRef); this.applicationRootDirectory.Name = String.Concat(application.Product.UpgradeCode, "v", application.Product.Version); directoryRef.AddChild(this.applicationRootDirectory); #if false // System registry keys Wix.Component registryComponent = new Wix.Component(); registryComponent.Id = "SystemVersionRegistryKeyComponent"; registryComponent.Guid = Guid.NewGuid().ToString(); directoryRef.AddChild(registryComponent); Wix.Registry productRegKey = new Wix.Registry(); productRegKey.Root = Wix.RegistryRootType.HKCU; productRegKey.Key = @"Software\WiX\ClickThrough\Applications\[UpgradeCode]"; productRegKey.Action = Wix.Registry.ActionType.createKeyAndRemoveKeyOnUninstall; registryComponent.AddChild(productRegKey); Wix.Registry versionRegKey = new Wix.Registry(); versionRegKey.Name = "Version"; versionRegKey.Type = Wix.Registry.TypeType.@string; versionRegKey.Value = "[ProductVersion]"; productRegKey.AddChild(versionRegKey); Wix.Registry sourceRegKey = new Wix.Registry(); sourceRegKey.Name = "UpdateInfoSource"; sourceRegKey.Type = Wix.Registry.TypeType.@string; sourceRegKey.Value = "[ARPURLUPDATEINFO]"; productRegKey.AddChild(sourceRegKey); // Shortcut Wix.DirectoryRef programMenuRef = new Wix.DirectoryRef(); programMenuRef.Id = "ProgramMenuFolder"; Wix.Directory shortcutsDirectory = new Wix.Directory(); shortcutsDirectory.Id = "ThisAppShortcuts"; shortcutsDirectory.LongName = application.Product.Name; shortcutsDirectory.Name = "AppSCDir"; programMenuRef.AddChild(shortcutsDirectory); application.Product.AddChild(programMenuRef); Wix.Component shortcutsComponent = new Wix.Component(); shortcutsComponent.Id = "ThisApplicationShortcutComponent"; shortcutsComponent.Guid = Guid.NewGuid().ToString(); shortcutsComponent.KeyPath = Wix.YesNoType.yes; shortcutsDirectory.AddChild(shortcutsComponent); Wix.CreateFolder shortcutsCreateFolder = new Wix.CreateFolder(); shortcutsComponent.AddChild(shortcutsCreateFolder); Wix.Shortcut shortcut = this.GetShortcut(this.applicationEntry.Content, rootDirectory, shortcutsDirectory); shortcutsComponent.AddChild(shortcut); // Remove cached MSI file. Wix.Component removeComponent = new Wix.Component(); removeComponent.Id = "ThisApplicationRemoveComponent"; removeComponent.Guid = Guid.NewGuid().ToString(); removeComponent.KeyPath = Wix.YesNoType.yes; applicationCacheRef.AddChild(removeComponent); Wix.RemoveFile cacheRemoveFile = new Wix.RemoveFile(); cacheRemoveFile.Id = "ThisApplicationRemoveCachedMsi"; cacheRemoveFile.Directory = "ApplicationsCacheFolder"; cacheRemoveFile.Name = "unknown.msi"; cacheRemoveFile.LongName = String.Concat("{", application.Product.Id.ToUpper(CultureInfo.InvariantCulture), "}v", application.Version.ToString(), ".msi"); cacheRemoveFile.On = Wix.RemoveFile.OnType.uninstall; removeComponent.AddChild(cacheRemoveFile); Wix.RemoveFile cacheRemoveFolder = new Wix.RemoveFile(); cacheRemoveFolder.Id = "ThisApplicationRemoveCacheFolder"; cacheRemoveFolder.Directory = "ApplicationsCacheFolder"; cacheRemoveFolder.On = Wix.RemoveFile.OnType.uninstall; removeComponent.AddChild(cacheRemoveFolder); Wix.RemoveFile applicationRemoveFolder = new Wix.RemoveFile(); applicationRemoveFolder.Id = "ThisApplicationRemoveApplicationsFolder"; applicationRemoveFolder.Directory = "ApplicationsFolder"; applicationRemoveFolder.On = Wix.RemoveFile.OnType.uninstall; removeComponent.AddChild(applicationRemoveFolder); #endif // Feature tree Wix.FeatureRef applicationFeatureRef = new Wix.FeatureRef(); applicationFeatureRef.Id = "ApplicationFeature"; application.Product.AddChild(applicationFeatureRef); #if false Wix.Feature applicationFeature = new Wix.Feature(); applicationFeature.Id = "ApplicationFeature"; applicationFeature.Display = "expand"; applicationFeature.Level = 1; applicationFeature.Absent = Wix.Feature.AbsentType.disallow; applicationFeature.AllowAdvertise = Wix.Feature.AllowAdvertiseType.yes; applicationFeature.InstallDefault = Wix.Feature.InstallDefaultType.local; applicationFeature.TypicalDefault = Wix.Feature.TypicalDefaultType.install; application.Product.AddChild(applicationFeature); Wix.ComponentRef shortcutsComponentRef = new Wix.ComponentRef(); shortcutsComponentRef.Id = shortcutsComponent.Id; applicationFeature.AddChild(shortcutsComponentRef); Wix.ComponentRef removeComponentRef = new Wix.ComponentRef(); removeComponentRef.Id = removeComponent.Id; applicationFeature.AddChild(removeComponentRef); #endif Wix.ComponentRef[] componentRefs = this.GetComponentRefs(this.applicationRootDirectory); foreach (Wix.ComponentRef componentRef in componentRefs) { applicationFeatureRef.AddChild(componentRef); } if (!this.OnProgress(currentProgress++, totalProgress, "Serializing package information into XML...")) { return false; } // serialize to an xml string string xml; using (StringWriter sw = new StringWriter()) { XmlTextWriter writer = null; try { writer = new XmlTextWriter(sw); application.WixRoot.OutputXml(writer); xml = sw.ToString(); } finally { if (writer != null) { writer.Close(); } } } // load the xml into a document XmlDocument sourceDoc = new XmlDocument(); sourceDoc.LoadXml(xml); if (outputSourcePath != null) { if (!this.OnProgress(currentProgress++, totalProgress, "Saving .wxs file...")) { return false; } sourceDoc.Save(outputSourcePath); } // generate the MSI, create the setup.exe, and generate the RSS feed. string outputMsi = null; try { outputMsi = Path.GetTempFileName(); if (!this.OnProgress(currentProgress++, totalProgress, "Generating .msi file...")) { return false; } this.GenerateMsi(sourceDoc, outputMsi); if (this.buildError != null) { throw new InvalidOperationException(String.Format(this.buildError.ResourceManager.GetString(this.buildError.ResourceName), this.buildError.MessageArgs)); } string assemblyPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); if (!this.OnProgress(currentProgress++, totalProgress, "Generating setup bootstrapper...")) { return false; } /* NativeMethods.CREATE_SETUP_PACKAGE[] createSetup = new Microsoft.Tools.WindowsInstallerXml.ClickThrough.NativeMethods.CREATE_SETUP_PACKAGE[1]; createSetup[0].fPrivileged = false; createSetup[0].fCache = true; createSetup[0].wzSourcePath = outputMsi; int hr = NativeMethods.CreateSetup(Path.Combine(assemblyPath, "setup.exe"), createSetup, createSetup.Length, localSetupExe); */ int hr = NativeMethods.CreateSimpleSetup(Path.Combine(assemblyPath, "setup.exe"), outputMsi, localSetupExe); if (hr != 0) { this.OnMessage(ClickThroughErrors.FailedSetupExeCreation(Path.Combine(assemblyPath, "setup.exe"), localSetupExe)); } if (!this.OnProgress(currentProgress++, totalProgress, "Generating update feed...")) { return false; } this.GenerateRssFeed(localSetupFeed, localSetupExe, urlSetupExe, application.Product.Id, application.Product.UpgradeCode, application.Product.Version); } finally { this.OnProgress(currentProgress++, totalProgress, "Cleaning up..."); if (outputMsi != null) { File.Delete(outputMsi); } } if (this.buildError != null) { throw new InvalidOperationException(String.Format(this.buildError.ResourceManager.GetString(this.buildError.ResourceName), this.buildError.MessageArgs)); } else if (!this.OnProgress(currentProgress++, totalProgress, "Package build complete.")) { return false; } return true; }
/// <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="directory">The directory for this path.</param> /// <returns>The number of files harvested.</returns> private int HarvestDirectory(string path, string relativePath, Wix.Directory directory) { int fileCount = 0; // harvest the child directories foreach (string childDirectoryPath in Directory.GetDirectories(path)) { Wix.Directory childDirectory = new Wix.Directory(); childDirectory.Name = Path.GetFileName(childDirectoryPath); childDirectory.FileSource = childDirectoryPath; if (this.setUniqueIdentifiers) { childDirectory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, directory.Id, childDirectory.Name); } int childFileCount = this.HarvestDirectory(childDirectoryPath, String.Concat(relativePath, childDirectory.Name, "\\"), childDirectory); // 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); Wix.Component component = new Wix.Component(); Wix.File file = this.fileHarvester.HarvestFile(filePath); file.Source = String.Concat(relativePath, fileName); 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); directory.AddChild(component); } } else if (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> /// Gets the directory object for the provided application root path. /// </summary> /// <param name="recalculate">Flag to recalculate root directory.</param> /// <returns>Directory harvested from root.</returns> public Wix.Directory GetRootDirectory(bool recalculate) { if (null == this.source) { throw new ArgumentNullException("RootPath"); } if (recalculate || null == this.rootDirectory) { DirectoryHarvester directoryHarvester = new DirectoryHarvester(); this.rootDirectory = directoryHarvester.HarvestDirectory(this.source, true); Wix.Wix wix = new Wix.Wix(); Wix.Fragment fragment = new Wix.Fragment(); wix.AddChild(fragment); fragment.AddChild(this.rootDirectory); UtilMutator utilMutator = new UtilMutator(); utilMutator.GenerateGuids = true; utilMutator.SetUniqueIdentifiers = true; utilMutator.Mutate(wix); UtilFinalizeHarvesterMutator finalMutator = new UtilFinalizeHarvesterMutator(); finalMutator.Mutate(wix); } return this.rootDirectory; }
/// <summary> /// Gets the directory object for the ApplicationRoot. /// </summary> public Wix.Directory GetApplicationRootDirectory() { if (null != this.applicationRoot && null == this.applicationRootDirectory) { this.applicationRootDirectory = this.directoryHarvester.HarvestDirectory(this.applicationRoot.Content, true); Wix.Wix wix = new Wix.Wix(); Wix.Fragment fragment = new Wix.Fragment(); wix.AddChild(fragment); fragment.AddChild(this.applicationRootDirectory); this.utilMutator.Mutate(wix); this.finalMutator.Mutate(wix); } return this.applicationRootDirectory; }