/// <summary> /// Resolves all the simple references in a section. /// </summary> /// <param name="outputType">Parent output type that will get the resolved section collection.</param> /// <param name="allSymbols">Collection of all symbols from loaded intermediates.</param> /// <param name="referencedSymbols">Collection populated during resolution of all symbols referenced during linking.</param> /// <param name="unresolvedReferences">Collection populated during resolution of all references that are left unresolved.</param> /// <param name="messageHandler">Message handler to report any duplicate symbols that may be tripped across.</param> /// <returns>The resolved sections.</returns> internal SectionCollection ResolveReferences( OutputType outputType, SymbolCollection allSymbols, StringCollection referencedSymbols, ArrayList unresolvedReferences, IMessageHandler messageHandler) { SectionCollection sections = new SectionCollection(); RecursivelyResolveReferences(this, outputType, allSymbols, sections, referencedSymbols, unresolvedReferences, messageHandler); return(sections); }
/// <summary> /// Finds the entry section and loads the symbols from an array of intermediates. /// </summary> /// <param name="allowIdenticalRows">Flag specifying whether identical rows are allowed or not.</param> /// <param name="messageHandler">Message handler object to route all errors through.</param> /// <param name="entrySection">Located entry section.</param> /// <param name="allSymbols">Collection of symbols loaded.</param> internal void FindEntrySectionAndLoadSymbols( bool allowIdenticalRows, IMessageHandler messageHandler, out Section entrySection, out SymbolCollection allSymbols) { entrySection = null; allSymbols = new SymbolCollection(); foreach (Section section in this.collection) { if (SectionType.Product == section.Type || SectionType.Module == section.Type || SectionType.PatchCreation == section.Type || SectionType.Patch == section.Type) { if (null == entrySection) { entrySection = section; } else { messageHandler.OnMessage(WixErrors.MultipleEntrySections(entrySection.SourceLineNumbers, entrySection.Id, section.Id)); messageHandler.OnMessage(WixErrors.MultipleEntrySections2(section.SourceLineNumbers)); } } foreach (Symbol symbol in section.GetSymbols(messageHandler)) { try { Symbol existingSymbol = allSymbols[symbol.Name]; if (null == existingSymbol) { allSymbols.Add(symbol); } else if (allowIdenticalRows && existingSymbol.Row.IsIdentical(symbol.Row)) { messageHandler.OnMessage(WixWarnings.IdenticalRowWarning(symbol.Row.SourceLineNumbers, existingSymbol.Name)); messageHandler.OnMessage(WixWarnings.IdenticalRowWarning2(existingSymbol.Row.SourceLineNumbers)); } else { allSymbols.AddDuplicate(symbol); } } catch (DuplicateSymbolsException) { // if there is already a duplicate symbol, just // another to the list, don't bother trying to // see if there are any identical symbols allSymbols.AddDuplicate(symbol); } } } }
/// <summary> /// Gets the symbols for this section. /// </summary> /// <param name="messageHandler">The message handler.</param> /// <returns>Collection of symbols for this section.</returns> internal SymbolCollection GetSymbols(IMessageHandler messageHandler) { if (null == this.symbols) { this.symbols = new SymbolCollection(); // add a symbol for this section if (null != this.id) { this.symbols.Add(new Symbol(this, this.type.ToString(), this.id)); } else { Debug.Assert(SectionType.Fragment == this.type, "Only Fragment sections can have a null Id."); } foreach (Table table in this.tables) { foreach (Row row in table.Rows) { Symbol symbol = row.Symbol; if (null != symbol) { try { this.symbols.Add(symbol); } catch (ArgumentException) { Symbol existingSymbol = this.symbols[symbol.Name]; messageHandler.OnMessage(WixErrors.DuplicateSymbol(existingSymbol.Row.SourceLineNumbers, existingSymbol.Name)); messageHandler.OnMessage(WixErrors.DuplicateSymbol2(symbol.Row.SourceLineNumbers)); } } } } } return(this.symbols); }
/// <summary> /// Loads the standard actions' symbols into the entry section. /// </summary> /// <param name="allSymbols">Collection of symbols.</param> /// <param name="entrySection">Entry section.</param> /// <param name="actionTable">Table that contains the standard actions.</param> private void LoadStandardActionSymbols(SymbolCollection allSymbols, Section entrySection, ActionTable actionTable) { foreach (Action action in actionTable) { // if the action's symbol has not already been defined (i.e. overriden by the user), add it now Symbol symbol = action.GetSymbol(entrySection); if (!allSymbols.Contains(symbol.Name)) { allSymbols.Add(symbol); } } }
/// <summary> /// Finds the entry section and loads the symbols from an array of intermediates. /// </summary> /// <param name="allowIdenticalRows">Flag specifying whether identical rows are allowed or not.</param> /// <param name="messageHandler">Message handler object to route all errors through.</param> /// <param name="expectedOutputType">Expected entry output type, based on output file extension provided to the linker.</param> /// <param name="entrySection">Located entry section.</param> /// <param name="allSymbols">Collection of symbols loaded.</param> internal void FindEntrySectionAndLoadSymbols( bool allowIdenticalRows, IMessageHandler messageHandler, OutputType expectedOutputType, out Section entrySection, out SymbolCollection allSymbols) { entrySection = null; allSymbols = new SymbolCollection(); string outputExtension = Output.GetExtension(expectedOutputType); SectionType expectedEntrySectionType; try { expectedEntrySectionType = (SectionType)Enum.Parse(typeof(SectionType), expectedOutputType.ToString()); } catch (ArgumentException) { expectedEntrySectionType = SectionType.Unknown; } foreach (Section section in this.collection.Keys) { if (SectionType.Product == section.Type || SectionType.Module == section.Type || SectionType.PatchCreation == section.Type || SectionType.Patch == section.Type || SectionType.Bundle == section.Type) { if (SectionType.Unknown != expectedEntrySectionType && section.Type != expectedEntrySectionType) { messageHandler.OnMessage(WixWarnings.UnexpectedEntrySection(section.SourceLineNumbers, section.Type.ToString(), expectedEntrySectionType.ToString(), outputExtension)); } if (null == entrySection) { entrySection = section; } else { messageHandler.OnMessage(WixErrors.MultipleEntrySections(entrySection.SourceLineNumbers, entrySection.Id, section.Id)); messageHandler.OnMessage(WixErrors.MultipleEntrySections2(section.SourceLineNumbers)); } } foreach (Symbol symbol in section.GetSymbols(messageHandler)) { try { Symbol existingSymbol = allSymbols[symbol.Name]; if (null == existingSymbol) { allSymbols.Add(symbol); } else if (allowIdenticalRows && existingSymbol.Row.IsIdentical(symbol.Row)) { messageHandler.OnMessage(WixWarnings.IdenticalRowWarning(symbol.Row.SourceLineNumbers, existingSymbol.Name)); messageHandler.OnMessage(WixWarnings.IdenticalRowWarning2(existingSymbol.Row.SourceLineNumbers)); } else { allSymbols.AddDuplicate(symbol); } } catch (DuplicateSymbolsException) { // if there is already a duplicate symbol, just // another to the list, don't bother trying to // see if there are any identical symbols allSymbols.AddDuplicate(symbol); } } } }
/// <summary> /// Finds the entry section and loads the symbols from an array of intermediates. /// </summary> /// <param name="allowIdenticalRows">Flag specifying whether identical rows are allowed or not.</param> /// <param name="messageHandler">Message handler object to route all errors through.</param> /// <param name="expectedOutputType">Expected entry output type, based on output file extension provided to the linker.</param> /// <param name="entrySection">Located entry section.</param> /// <param name="allSymbols">Collection of symbols loaded.</param> internal void FindEntrySectionAndLoadSymbols( bool allowIdenticalRows, IMessageHandler messageHandler, OutputType expectedOutputType, out Section entrySection, out SymbolCollection allSymbols) { entrySection = null; allSymbols = new SymbolCollection(); string outputExtension = Output.GetExtension(expectedOutputType); SectionType expectedEntrySectionType; try { expectedEntrySectionType = (SectionType)Enum.Parse(typeof(SectionType), expectedOutputType.ToString()); } catch (ArgumentException) { expectedEntrySectionType = SectionType.Unknown; } foreach (Section section in this.collection.Keys) { if (SectionType.Product == section.Type || SectionType.Module == section.Type || SectionType.PatchCreation == section.Type || SectionType.Patch == section.Type || SectionType.Bundle == section.Type) { if (SectionType.Unknown != expectedEntrySectionType && section.Type != expectedEntrySectionType) { messageHandler.OnMessage(WixWarnings.UnexpectedEntrySection(section.SourceLineNumbers, section.Type.ToString(), expectedEntrySectionType.ToString(), outputExtension)); } if (null == entrySection) { entrySection = section; } else { messageHandler.OnMessage(WixErrors.MultipleEntrySections(entrySection.SourceLineNumbers, entrySection.Id, section.Id)); messageHandler.OnMessage(WixErrors.MultipleEntrySections2(section.SourceLineNumbers)); } } foreach (Symbol symbol in section.GetSymbols(messageHandler)) { try { Symbol existingSymbol = allSymbols[symbol.Name]; if (null == existingSymbol) { allSymbols.Add(symbol); } else if (allowIdenticalRows && existingSymbol.Row.IsIdentical(symbol.Row)) { messageHandler.OnMessage(WixWarnings.IdenticalRowWarning(symbol.Row.SourceLineNumbers, existingSymbol.Name)); messageHandler.OnMessage(WixWarnings.IdenticalRowWarning2(existingSymbol.Row.SourceLineNumbers)); } else { allSymbols.AddDuplicate(symbol); } } catch (DuplicateSymbolsException) { // if there is already a duplicate symbol, just // another to the list, don't bother trying to // see if there are any identical symbols allSymbols.AddDuplicate(symbol); } } } }
/// <summary> /// Gets the symbols that were not referenced during processing (usually linking). /// </summary> /// <param name="referencedSymbols">Collection of symbol names in string form.</param> /// <param name="messageHandler">Message handler to display errors while acquiring symbols.</param> /// <returns>Collection of unreferenced symbols.</returns> internal SymbolCollection GetOrphanedSymbols(StringCollection referencedSymbols, IMessageHandler messageHandler) { SymbolCollection unreferencedSymbols = new SymbolCollection(); // Loop through all of the symbols in all of the sections in this collection // looking for names that are not in the provided string collection. foreach (Section section in this.collection.Keys) { if (SectionType.Product == section.Type || SectionType.Module == section.Type || SectionType.PatchCreation == section.Type || SectionType.Patch == section.Type) { // Skip all symbols in the entry section; // They may appear to be unreferenced but they // will get into the linked image. continue; } foreach (Symbol symbol in section.GetSymbols(messageHandler)) { if (!referencedSymbols.Contains(symbol.Name)) { // If the symbol was created by the user, then it will have // a row associated with it. We don't care about generated // (those with out Rows) unreferenced symbols so skip them. if (null != symbol.Row && !unreferencedSymbols.Contains(symbol.Name)) { unreferencedSymbols.Add(symbol); } } } } return unreferencedSymbols; }
/// <summary> /// Resolves the features connected to other features in the active output. /// </summary> /// <param name="featuresToFeatures">Feature to feature complex references.</param> /// <param name="allSymbols">All symbols loaded from the sections.</param> private void ResolveFeatureToFeatureConnects( ConnectToFeatureCollection featuresToFeatures, SymbolCollection allSymbols) { foreach (ConnectToFeature connection in featuresToFeatures) { WixSimpleReferenceRow wixSimpleReferenceRow = new WixSimpleReferenceRow(null, this.tableDefinitions["WixSimpleReference"]); wixSimpleReferenceRow.TableName = "Feature"; wixSimpleReferenceRow.PrimaryKeys = connection.ChildId; Symbol symbol = allSymbols.GetSymbolForSimpleReference(wixSimpleReferenceRow, this); if (null == symbol) { continue; } Row row = symbol.Row; row[1] = connection.PrimaryFeature; } }
/// <summary> /// Load the standard action symbols. /// </summary> /// <param name="allSymbols">Collection of symbols.</param> private void LoadStandardActionSymbols(SymbolCollection allSymbols) { foreach (WixActionRow actionRow in this.standardActions) { // if the action's symbol has not already been defined (i.e. overriden by the user), add it now if (!allSymbols.Contains(actionRow.Symbol.Name)) { allSymbols.Add(actionRow.Symbol); } } }
/// <summary> /// Recursive helper function to resolve all references of passed in section. /// </summary> /// <param name="section">Section with references to resolve.</param> /// <param name="outputType">Parent output type that will get the resolved section collection.</param> /// <param name="allSymbols">All symbols that can be used to resolve section's references.</param> /// <param name="sections">Collection to add sections to during processing.</param> /// <param name="referencedSymbols">Collection populated during resolution of all symbols referenced during linking.</param> /// <param name="unresolvedReferences">Collection populated during resolution of all references that are left unresolved.</param> /// <param name="messageHandler">Message handler to report any duplicate symbols that may be tripped across.</param> /// <remarks>Note: recursive function.</remarks> private static void RecursivelyResolveReferences( Section section, OutputType outputType, SymbolCollection allSymbols, SectionCollection sections, StringCollection referencedSymbols, ArrayList unresolvedReferences, IMessageHandler messageHandler) { // if we already have this section bail if (sections.Contains(section)) { return; } // add the passed in section to the collection of sections sections.Add(section); // process all of the references contained in this section using the collection of // symbols provided. Then recursively call this method to process the // located symbol's section. All in all this is a very simple depth-first // search of the references per-section Table wixSimpleReferenceTable = section.Tables["WixSimpleReference"]; if (null != wixSimpleReferenceTable) { foreach (WixSimpleReferenceRow wixSimpleReferenceRow in wixSimpleReferenceTable.Rows) { // If we're building a Merge Module, ignore all references to the Media table // because Merge Modules don't have Media tables. if (OutputType.Module == outputType && "Media" == wixSimpleReferenceRow.TableName) { continue; } if ("WixAction" == wixSimpleReferenceRow.TableName) { Symbol[] symbols = allSymbols.GetSymbolsForSimpleReference(wixSimpleReferenceRow); if (0 == symbols.Length) { if (null != unresolvedReferences) { unresolvedReferences.Add(new SimpleReferenceSection(section, wixSimpleReferenceRow)); } } else { foreach (Symbol symbol in symbols) { if (null != symbol.Section) { // components are indexed in ResolveComplexReferences if (null != referencedSymbols && null != symbol.Row.TableDefinition.Name && "Component" != symbol.Row.TableDefinition.Name && !referencedSymbols.Contains(symbol.Name)) { referencedSymbols.Add(symbol.Name); } RecursivelyResolveReferences(symbol.Section, outputType, allSymbols, sections, referencedSymbols, unresolvedReferences, messageHandler); } } } } else { Symbol symbol = allSymbols.GetSymbolForSimpleReference(wixSimpleReferenceRow, messageHandler); if (null == symbol) { if (null != unresolvedReferences) { unresolvedReferences.Add(new SimpleReferenceSection(section, wixSimpleReferenceRow)); } } else { // components are indexed in ResolveComplexReferences if (null != referencedSymbols && null != symbol.Row.TableDefinition.Name && "Component" != symbol.Row.TableDefinition.Name && !referencedSymbols.Contains(symbol.Name)) { referencedSymbols.Add(symbol.Name); } RecursivelyResolveReferences(symbol.Section, outputType, allSymbols, sections, referencedSymbols, unresolvedReferences, messageHandler); } } } } }
/// <summary> /// Gets the symbols for this section. /// </summary> /// <param name="messageHandler">The message handler.</param> /// <returns>Collection of symbols for this section.</returns> internal SymbolCollection GetSymbols(IMessageHandler messageHandler) { if (null == this.symbols) { this.symbols = new SymbolCollection(); foreach (Table table in this.tables) { foreach (Row row in table.Rows) { Symbol symbol = row.Symbol; if (null != symbol) { try { this.symbols.Add(symbol); } catch (ArgumentException) { Symbol existingSymbol = this.symbols[symbol.Name]; messageHandler.OnMessage(WixErrors.DuplicateSymbol(existingSymbol.Row.SourceLineNumbers, existingSymbol.Name)); if (null != symbol.Row.SourceLineNumbers) { messageHandler.OnMessage(WixErrors.DuplicateSymbol2(symbol.Row.SourceLineNumbers)); } } } } } } return this.symbols; }
/// <summary> /// Gets the symbol for a reference. /// </summary> /// <param name="section">Section that contains references to resolve.</param> /// <param name="reference">References to resolve.</param> /// <param name="allSymbols">Collection of all symbols from loaded intermediates.</param> /// <param name="referencedSymbols">Collection of all symbols referenced during linking.</param> /// <param name="unresolvedReferences">Unresolved references.</param> /// <param name="messageHandler">Message handler to report errors through.</param> /// <returns>Symbol it it was found or null if the symbol was not specified.</returns> internal static Symbol GetSymbolForReference( Section section, Reference reference, SymbolCollection allSymbols, StringCollection referencedSymbols, ArrayList unresolvedReferences, IMessageHandler messageHandler) { Symbol symbol = null; try { symbol = allSymbols[reference.SymbolicName]; if (null == symbol) { unresolvedReferences.Add(new ReferenceSection(section, reference)); } else { // components are indexed in ResolveComplexReferences if (null != symbol.TableName && "Component" != symbol.TableName && !referencedSymbols.Contains(symbol.Name)) { referencedSymbols.Add(symbol.Name); } } } catch (DuplicateSymbolsException e) { Symbol[] symbols = e.GetDuplicateSymbols(); Debug.Assert(1 < symbols.Length); messageHandler.OnMessage(WixErrors.DuplicateSymbol((null != symbols[0].Row ? symbols[0].Row.SourceLineNumbers : null), symbols[0].Name)); for (int i = 1; i < symbols.Length; ++i) { if (null != symbols[i].Row && null != symbols[i].Row.SourceLineNumbers) { messageHandler.OnMessage(WixErrors.DuplicateSymbol2(symbols[i].Row.SourceLineNumbers)); } } } return symbol; }
/// <summary> /// Finds the entry section and loads the symbols from an array of intermediates. /// </summary> /// <param name="intermediates">Array of intermediates to load symbols for and find entry section.</param> /// <param name="allowIdenticalRows">Flag specifying whether identical rows are allowed or not.</param> /// <param name="messageHandler">Message handler object to route all errors through.</param> /// <param name="entrySection">Located entry section.</param> /// <param name="allSymbols">Collection of symbols loaded.</param> internal static void FindEntrySectionAndLoadSymbols( Intermediate[] intermediates, bool allowIdenticalRows, IMessageHandler messageHandler, out Section entrySection, out SymbolCollection allSymbols) { entrySection = null; allSymbols = new SymbolCollection(); for (int i = 0; i < intermediates.Length; ++i) { foreach (Section section in intermediates[i].Sections) { if (SectionType.Product == section.Type || SectionType.Module == section.Type || SectionType.PatchCreation == section.Type) { if (null == entrySection) { entrySection = section; } else { messageHandler.OnMessage(WixErrors.MultipleEntrySections(SourceLineNumberCollection.FromFileName(entrySection.Intermediate.SourcePath), entrySection.Id, section.Id)); messageHandler.OnMessage(WixErrors.MultipleEntrySections2(SourceLineNumberCollection.FromFileName(section.Intermediate.SourcePath))); } } foreach (Symbol symbol in section.GetSymbols(messageHandler)) { try { Symbol existingSymbol = allSymbols[symbol.Name]; if (null == existingSymbol) { allSymbols.Add(symbol); } else if (allowIdenticalRows && existingSymbol.Row.IsIdentical(symbol.Row)) { messageHandler.OnMessage(WixWarnings.IdenticalRowWarning(symbol.Row.SourceLineNumbers, existingSymbol.Name)); messageHandler.OnMessage(WixWarnings.IdenticalRowWarning2(existingSymbol.Row.SourceLineNumbers)); } else { allSymbols.AddDuplicate(symbol); } } catch (DuplicateSymbolsException) { // if there is already a duplicate symbol, just // another to the list, don't bother trying to // see if there are any identical symbols allSymbols.AddDuplicate(symbol); } } } } }
/// <summary> /// Resolves all the simple references in a section. /// </summary> /// <param name="outputType">Active output type.</param> /// <param name="sections">Collection to add sections to.</param> /// <param name="section">Section with references to resolve.</param> /// <param name="allSymbols">Collection of all symbols from loaded intermediates.</param> /// <param name="referencedSymbols">Collection of all symbols referenced during linking.</param> /// <param name="unresolvedReferences">Unresolved references.</param> /// <param name="messageHandler">Message handler to report errors through.</param> /// <remarks>Note: recursive function.</remarks> internal static void ResolveReferences( OutputType outputType, SectionCollection sections, Section section, SymbolCollection allSymbols, StringCollection referencedSymbols, ArrayList unresolvedReferences, IMessageHandler messageHandler) { // if we already have this section bail if (sections.Contains(section)) { return; } // add the section to the output and loop through the rest of the references // in a simple depth-first search sections.Add(section); foreach (Reference reference in section.References) { // if we're building into an output, modules ignore all references to the Media table if (OutputType.Module == outputType && "Media" == reference.TableName) { continue; } Symbol symbol = Common.GetSymbolForReference(section, reference, allSymbols, referencedSymbols, unresolvedReferences, messageHandler); if (null != symbol) { Common.ResolveReferences(outputType, sections, symbol.Section, allSymbols, referencedSymbols, unresolvedReferences, messageHandler); } } }
/// <summary> /// Gets the symbols for this section. /// </summary> /// <param name="messageHandler">The message handler.</param> /// <returns>Collection of symbols for this section.</returns> internal SymbolCollection GetSymbols(IMessageHandler messageHandler) { if (null == this.symbols) { this.symbols = new SymbolCollection(); // add a symbol for this section if (null != this.id) { this.symbols.Add(new Symbol(this, this.type.ToString(), this.id)); } else { Debug.Assert(SectionType.Fragment == this.type, "Only Fragment sections can have a null Id."); } foreach (Table table in this.tables) { foreach (Row row in table.Rows) { Symbol symbol = row.Symbol; if (null != symbol) { try { this.symbols.Add(symbol); } catch (ArgumentException) { Symbol existingSymbol = this.symbols[symbol.Name]; messageHandler.OnMessage(WixErrors.DuplicateSymbol(existingSymbol.Row.SourceLineNumbers, existingSymbol.Name)); messageHandler.OnMessage(WixErrors.DuplicateSymbol2(symbol.Row.SourceLineNumbers)); } } } } } return this.symbols; }
/// <summary> /// Resolve the feature backlinks to the final feature that a component will live in. /// </summary> /// <param name="output">Active output to add sections to.</param> /// <param name="componentsToFeatures">Component to feature complex references.</param> /// <param name="allSymbols">All symbols loaded from the intermediates.</param> /// <param name="referencedSymbols">Collection of all symbols referenced during linking.</param> /// <param name="unresolvedReferences">Unresolved references.</param> private void ResolveFeatureBacklinks( Output output, ConnectToFeatureCollection componentsToFeatures, SymbolCollection allSymbols, StringCollection referencedSymbols, ArrayList unresolvedReferences) { Hashtable uniqueComponentIds = new Hashtable(); foreach (Section section in output.Sections) { foreach (FeatureBacklink blink in section.FeatureBacklinks) { Reference reference = blink.Reference; Symbol symbol = Common.GetSymbolForReference(section, reference, allSymbols, referencedSymbols, unresolvedReferences, this); if (null == symbol) { continue; } Row row = symbol.Row; string parentFeature; if (OutputType.Module == output.Type) { parentFeature = Guid.Empty.ToString("B"); } else { ConnectToFeature connection = componentsToFeatures[blink.Component]; if (null == connection) { throw new WixMissingFeatureException(SourceLineNumberCollection.FromFileName(section.Intermediate.Path), blink); } parentFeature = connection.PrimaryFeature; // check for unique, implicit, primary feature parents with multiple possible parent features if (PedanticLevel.Legendary == this.pedanticLevel && !connection.IsExplicitPrimaryFeature && 0 < connection.ConnectFeatures.Count && !uniqueComponentIds.Contains(blink.Component)) { this.OnMessage(WixWarnings.ImplicitPrimaryFeature(blink.Component)); // remember this component so only one warning is generated for it uniqueComponentIds[blink.Component] = null; } } switch (blink.Type) { case FeatureBacklinkType.Class: row[11] = parentFeature; break; case FeatureBacklinkType.Extension: row[4] = parentFeature; break; case FeatureBacklinkType.PublishComponent: row[4] = parentFeature; break; case FeatureBacklinkType.Shortcut: row[4] = parentFeature; break; case FeatureBacklinkType.TypeLib: row[6] = parentFeature; break; default: throw new ApplicationException("Internal Error: Unknown FeatureBackLinkType."); } } } }
/// <summary> /// Recursive helper function to resolve all references of passed in section. /// </summary> /// <param name="section">Section with references to resolve.</param> /// <param name="outputType">Parent output type that will get the resolved section collection.</param> /// <param name="allSymbols">All symbols that can be used to resolve section's references.</param> /// <param name="sections">Collection to add sections to during processing.</param> /// <param name="referencedSymbols">Collection populated during resolution of all symbols referenced during linking.</param> /// <param name="unresolvedReferences">Collection populated during resolution of all references that are left unresolved.</param> /// <param name="messageHandler">Message handler to report any duplicate symbols that may be tripped across.</param> /// <remarks>Note: recursive function.</remarks> private static void RecursivelyResolveReferences( Section section, OutputType outputType, SymbolCollection allSymbols, SectionCollection sections, StringCollection referencedSymbols, ArrayList unresolvedReferences, IMessageHandler messageHandler) { // if we already have this section bail if (sections.Contains(section)) { return; } // add the passed in section to the collection of sections sections.Add(section); // process all of the references contained in this section using the collection of // symbols provided. Then recursively call this method to process the // located symbol's section. All in all this is a very simple depth-first // search of the references per-section Table wixSimpleReferenceTable = section.Tables["WixSimpleReference"]; if (null != wixSimpleReferenceTable) { foreach (WixSimpleReferenceRow wixSimpleReferenceRow in wixSimpleReferenceTable.Rows) { // If we're building a Merge Module, ignore all references to the Media table // because Merge Modules don't have Media tables. if (OutputType.Module == outputType && "Media" == wixSimpleReferenceRow.TableName) { continue; } if ("WixAction" == wixSimpleReferenceRow.TableName) { Symbol[] symbols = allSymbols.GetSymbolsForSimpleReference(wixSimpleReferenceRow); if (0 == symbols.Length) { if (null != unresolvedReferences) { unresolvedReferences.Add(new SimpleReferenceSection(section, wixSimpleReferenceRow)); } } else { foreach (Symbol symbol in symbols) { if (null != symbol.Section) { // components are indexed in ResolveComplexReferences if (null != referencedSymbols && null != symbol.Row.TableDefinition.Name && "Component" != symbol.Row.TableDefinition.Name && !referencedSymbols.Contains(symbol.Name)) { referencedSymbols.Add(symbol.Name); } RecursivelyResolveReferences(symbol.Section, outputType, allSymbols, sections, referencedSymbols, unresolvedReferences, messageHandler); } } } } else { Symbol symbol = allSymbols.GetSymbolForSimpleReference(wixSimpleReferenceRow, messageHandler); if (null == symbol) { if (null != unresolvedReferences) { unresolvedReferences.Add(new SimpleReferenceSection(section, wixSimpleReferenceRow)); } } else { // components are indexed in ResolveComplexReferences if (null != referencedSymbols && null != symbol.Row.TableDefinition.Name && "Component" != symbol.Row.TableDefinition.Name && !referencedSymbols.Contains(symbol.Name)) { referencedSymbols.Add(symbol.Name); } RecursivelyResolveReferences(symbol.Section, outputType, allSymbols, sections, referencedSymbols, unresolvedReferences, messageHandler); } } } } }
/// <summary> /// Resolves the features connected to other features in the active output. /// </summary> /// <param name="featuresToFeatures">Feature to feature complex references.</param> /// <param name="allSymbols">All symbols loaded from the intermediates.</param> /// <param name="referencedSymbols">Collection of all symbols referenced during linking.</param> /// <param name="unresolvedReferences">Unresolved references.</param> private void ResolveFeatureToFeatureConnects(ConnectToFeatureCollection featuresToFeatures, SymbolCollection allSymbols, StringCollection referencedSymbols, ArrayList unresolvedReferences) { foreach (ConnectToFeature connection in featuresToFeatures) { Reference reference = new Reference("Feature", connection.ChildId); Symbol symbol = Common.GetSymbolForReference(connection.Section, reference, allSymbols, referencedSymbols, unresolvedReferences, this); if (null == symbol) { continue; } Row row = symbol.Row; row[1] = connection.PrimaryFeature; } }
/// <summary> /// Resolves all the simple references in a section. /// </summary> /// <param name="outputType">Parent output type that will get the resolved section collection.</param> /// <param name="allSymbols">Collection of all symbols from loaded intermediates.</param> /// <param name="referencedSymbols">Collection populated during resolution of all symbols referenced during linking.</param> /// <param name="unresolvedReferences">Collection populated during resolution of all references that are left unresolved.</param> /// <param name="messageHandler">Message handler to report any duplicate symbols that may be tripped across.</param> /// <returns>The resolved sections.</returns> internal SectionCollection ResolveReferences( OutputType outputType, SymbolCollection allSymbols, StringCollection referencedSymbols, ArrayList unresolvedReferences, IMessageHandler messageHandler) { SectionCollection sections = new SectionCollection(); RecursivelyResolveReferences(this, outputType, allSymbols, sections, referencedSymbols, unresolvedReferences, messageHandler); return sections; }