/// <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); }
/// <summary> /// Actions under the resolver. /// </summary> protected override void ExecuteTaskResolved() { // Prepare the GUID cache myGuidCache = 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 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); // Get the dump from the product InstallationDataXml dataxml = CreateInstaller().HarvestInstallationData(); IDictionary <string, string> macros = GetMacros(); // Nullref guards dataxml.AssertValid(); // Convert into WiX int nProducedFiles = ConvertFiles(wixDirectoryRef, wixComponentGroup, dataxml, macros); int nProducedKeys = ConvertRegistryKeys(wixDirectoryRef, wixComponentGroup, dataxml, macros); int nProducedValues = ConvertRegistryValues(wixDirectoryRef, wixComponentGroup, dataxml, macros); // 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} files, {1} Registry keys, and {2} Registry values.", nProducedFiles, nProducedKeys, nProducedValues); }
/// <summary> /// Processes those AllAssemblies.Xml entries that are our own product assemblies. /// </summary> private int ProcessAssemblies(Directory wixDirectory, ComponentGroup wixComponentGroup, Component wixComponentRegistry, AllAssembliesXml allassembliesxml, Dictionary <string, string> mapTargetFiles, GuidCacheXml guidcachexml) { // Collect the assemblies int nGeneratedComponents = 0; foreach (ItemGroupXml group in allassembliesxml.ItemGroup) { if (group.AllAssemblies == null) { continue; } foreach (AssemblyXml assemblyxml in group.AllAssemblies) { nGeneratedComponents++; FileInfo fiAssembly = FindAssemblyFile(assemblyxml); string sExtension = fiAssembly.Extension.TrimStart('.'); // The extension without a dot // Create the component for the assembly (one per assembly) var wixComponent = new Component(); wixDirectory.AddChild(wixComponent); wixComponent.Id = string.Format("{0}.{1}.{2}", FileComponentIdPrefix, assemblyxml.Include, sExtension); wixComponent.Guid = assemblyxml.MsiGuid; wixComponent.DiskId = Bag.Get <int>(AttributeName.DiskId); wixComponent.Location = Component.LocationType.local; // Register component in the group var componentref = new ComponentRef(); wixComponentGroup.AddChild(componentref); componentref.Id = wixComponent.Id; // Add the assembly file (and make it the key path) var wixFileAssembly = new File(); wixComponent.AddChild(wixFileAssembly); wixFileAssembly.Id = string.Format("{0}.{1}.{2}", FileIdPrefix, assemblyxml.Include, sExtension); wixFileAssembly.Name = string.Format("{0}.{1}", assemblyxml.Include, sExtension); wixFileAssembly.KeyPath = YesNoType.yes; wixFileAssembly.Checksum = YesNoType.yes; wixFileAssembly.Vital = YesNoType.yes; wixFileAssembly.ReadOnly = YesNoType.yes; RegisterTargetFile(wixFileAssembly.Name, string.Format("The {0} product assembly.", assemblyxml.Include), mapTargetFiles); // Check whether it's a managed or native assembly AssemblyName assemblyname = null; try { assemblyname = AssemblyName.GetAssemblyName(fiAssembly.FullName); } catch (BadImageFormatException) { } // Add COM Self-Registration data if (assemblyxml.ComRegister) { /* * foreach(ISchemaElement harvested in HarvestComSelfRegistration(wixFileAssembly, fiAssembly)) * wixComponent.AddChild(harvested); */ SelfRegHarvester.Harvest(fiAssembly, assemblyname != null, wixComponent, wixFileAssembly); } // Ensure the managed DLL has a strong name if ((assemblyname != null) && (Bag.Get <bool>(AttributeName.RequireStrongName))) { byte[] token = assemblyname.GetPublicKeyToken(); if ((token == null) || (token.Length == 0)) { throw new InvalidOperationException(string.Format("The assembly “{0}” does not have a strong name.", assemblyxml.Include)); } } // Add PDBs if (Bag.Get <bool>(AttributeName.IncludePdb)) { HarvestSatellite(assemblyxml, assemblyxml.Include + ".pdb", wixComponent, MissingSatelliteErrorLevel.Error, "PDB file", mapTargetFiles); } // Add XmlDocs if ((assemblyname != null) && (Bag.Get <bool>(AttributeName.IncludeXmlDoc))) { HarvestSatellite(assemblyxml, assemblyxml.Include + ".xml", wixComponent, MissingSatelliteErrorLevel.Error, "XmlDoc file", mapTargetFiles); } // Add configs HarvestSatellite(assemblyxml, assemblyxml.Include + "." + sExtension + ".config", wixComponent, (assemblyxml.HasAppConfig ? MissingSatelliteErrorLevel.Error : MissingSatelliteErrorLevel.None), "application configuration file", mapTargetFiles); HarvestSatellite(assemblyxml, assemblyxml.Include + "." + sExtension + ".manifest", wixComponent, (assemblyxml.HasMainfest ? MissingSatelliteErrorLevel.Error : MissingSatelliteErrorLevel.None), "assembly manifest file", mapTargetFiles); HarvestSatellite(assemblyxml, assemblyxml.Include + ".XmlSerializers." + sExtension, wixComponent, (assemblyxml.HasXmlSerializers ? MissingSatelliteErrorLevel.Error : MissingSatelliteErrorLevel.None), "serialization assembly", mapTargetFiles); // Add publisher policy assemblies if (assemblyname != null) { HarvestPublisherPolicyAssemblies(assemblyxml, wixDirectory, wixComponentGroup, ref nGeneratedComponents, mapTargetFiles, guidcachexml); } // Register as an OmeaPlugin if (assemblyname != null) { RegisterPlugin(assemblyxml, wixFileAssembly, wixComponentRegistry); } } } return(nGeneratedComponents); }
private void HarvestPublisherPolicyAssemblies(AssemblyXml assemblyxml, Directory directory, ComponentGroup componentgroup, ref int nGeneratedComponents, Dictionary <string, string> mapTargetFiles, GuidCacheXml guidcachexml) { if (!Bag.Get <bool>(AttributeName.IncludePublisherPolicy)) { return; } int nWasGeneratedComponents = nGeneratedComponents; var diFolder = new DirectoryInfo(Bag.GetString(AttributeName.ProductBinariesDir)); string sSatelliteWildcard = string.Format("Policy.*.{0}.{1}", assemblyxml.Include, "dll"); // Even an EXE assembly has a DLL policy file foreach (FileInfo fiPolicyAssembly in diFolder.GetFiles(sSatelliteWildcard)) { // Find the companion policy config file var fiPolicyConfig = new FileInfo(Path.ChangeExtension(fiPolicyAssembly.FullName, ".Config")); if (!fiPolicyConfig.Exists) { throw new InvalidOperationException(string.Format("Could not locate the publisher policy config file for the assembly “{0}”; expected: “{1}”.", fiPolicyAssembly.FullName, fiPolicyConfig.FullName)); } // We have to create a new component for each of the DLLs we'd like to GAC as publisher policy assemblies nGeneratedComponents++; // Create the component for the assembly (one per assembly) var component = new Component(); directory.AddChild(component); component.Id = string.Format("{0}.{1}", FileComponentIdPrefix, fiPolicyAssembly.Name); component.Guid = guidcachexml[assemblyxml.Include + " PublisherPolicy"].ToString("B").ToUpper(); component.DiskId = Bag.Get <int>(AttributeName.DiskId); component.Location = Component.LocationType.local; // Register component in the group var componentref = new ComponentRef(); componentgroup.AddChild(componentref); componentref.Id = component.Id; // Add the assembly file (and make it the key path) var fileAssembly = new File(); component.AddChild(fileAssembly); fileAssembly.Id = string.Format("{0}.{1}", FileIdPrefix, fiPolicyAssembly.Name); fileAssembly.Name = fiPolicyAssembly.Name; fileAssembly.KeyPath = YesNoType.yes; fileAssembly.Checksum = YesNoType.yes; fileAssembly.Vital = YesNoType.no; fileAssembly.Assembly = File.AssemblyType.net; fileAssembly.ReadOnly = YesNoType.yes; RegisterTargetFile(fileAssembly.Name, string.Format("Publisher policy assembly file for the {0} product assembly.", assemblyxml.Include), mapTargetFiles); // Add the policy config file var filePolicy = new File(); component.AddChild(filePolicy); filePolicy.Id = string.Format("{0}.{1}", FileIdPrefix, fiPolicyConfig.Name); filePolicy.Name = fiPolicyConfig.Name; filePolicy.KeyPath = YesNoType.no; filePolicy.Checksum = YesNoType.yes; filePolicy.Vital = YesNoType.no; filePolicy.ReadOnly = YesNoType.yes; RegisterTargetFile(fileAssembly.Name, string.Format("Publisher policy configuration file for the {0} product assembly.", assemblyxml.Include), mapTargetFiles); } if (nWasGeneratedComponents == nGeneratedComponents) // None were actually collected { throw new InvalidOperationException(string.Format("Could not locate the Publisher Policy assemblies for the “{0}” assembly. The expected full path is “{1}\\{2}”.", assemblyxml.Include, diFolder.FullName, sSatelliteWildcard)); } }