Example #1
0
        /// <summary>
        /// Sequence an action before or after a standard action.
        /// </summary>
        /// <param name="actionSymbol">The action symbol to be sequenced.</param>
        /// <param name="requiredActionSymbols">Collection of actions which must be included.</param>
        private void SequenceActionSymbol(WixActionSymbol actionSymbol, Dictionary <string, WixActionSymbol> requiredActionSymbols)
        {
            var after = false;

            if (actionSymbol.After != null)
            {
                after = true;
            }
            else if (actionSymbol.Before == null)
            {
                throw new InvalidOperationException("Found an action with no Sequence, Before, or After column set.");
            }

            var parentActionName = (after ? actionSymbol.After : actionSymbol.Before);
            var parentActionKey  = actionSymbol.SequenceTable.ToString() + "/" + parentActionName;

            if (!requiredActionSymbols.TryGetValue(parentActionKey, out var parentActionSymbol))
            {
                // If the missing parent action is a standard action (with a suggested sequence number), add it.
                if (WindowsInstallerStandard.TryGetStandardAction(parentActionKey, out parentActionSymbol))
                {
                    // Create a clone to avoid modifying the static copy of the object.
                    // TODO: consider this: parentActionSymbol = parentActionSymbol.Clone();

                    requiredActionSymbols.Add(parentActionSymbol.Id.Id, parentActionSymbol);
                }
                else
                {
                    throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Found an action with a non-existent {0} action: {1}.", (after ? "After" : "Before"), parentActionName));
                }
            }
            else if (actionSymbol == parentActionSymbol || this.ContainsChildActionSymbol(actionSymbol, parentActionSymbol)) // cycle detected
            {
                throw new WixException(ErrorMessages.ActionCircularDependency(actionSymbol.SourceLineNumbers, actionSymbol.SequenceTable.ToString(), actionSymbol.Action, parentActionSymbol.Action));
            }

            // Add this action to the appropriate list of dependent action symbols.
            var relativeActions = this.GetRelativeActions(parentActionSymbol);
            var relatedSymbols  = (after ? relativeActions.NextActions : relativeActions.PreviousActions);

            relatedSymbols.Add(actionSymbol);
        }
Example #2
0
        /// <summary>
        /// Sequence an action before or after a standard action.
        /// </summary>
        /// <param name="actionRow">The action row to be sequenced.</param>
        /// <param name="requiredActionRows">Collection of actions which must be included.</param>
        private void SequenceActionRow(WixActionTuple actionRow, Dictionary <string, WixActionTuple> requiredActionRows)
        {
            var after = false;

            if (actionRow.After != null)
            {
                after = true;
            }
            else if (actionRow.Before == null)
            {
                throw new InvalidOperationException(WixStrings.EXP_FoundActionRowWithNoSequenceBeforeOrAfterColumnSet);
            }

            var parentActionName = (after ? actionRow.After : actionRow.Before);
            var parentActionKey  = actionRow.SequenceTable.ToString() + "/" + parentActionName;

            if (!requiredActionRows.TryGetValue(parentActionKey, out var parentActionRow))
            {
                // If the missing parent action is a standard action (with a suggested sequence number), add it.
                if (this.StandardActionsById.TryGetValue(parentActionKey, out parentActionRow))
                {
                    // Create a clone to avoid modifying the static copy of the object.
                    // TODO: consider this: parentActionRow = parentActionRow.Clone();

                    requiredActionRows.Add(parentActionRow.Id.Id, parentActionRow);
                }
                else
                {
                    throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_FoundActionRowWinNonExistentAction, (after ? "After" : "Before"), parentActionName));
                }
            }
            else if (actionRow == parentActionRow || this.ContainsChildActionRow(actionRow, parentActionRow)) // cycle detected
            {
                throw new WixException(ErrorMessages.ActionCircularDependency(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, parentActionRow.Action));
            }

            // Add this action to the appropriate list of dependent action rows.
            var relativeActions = this.GetRelativeActions(parentActionRow);
            var relatedRows     = (after ? relativeActions.NextActions : relativeActions.PreviousActions);

            relatedRows.Add(actionRow);
        }
Example #3
0
        /// <summary>
        /// Check the specified action symbol to see if it leads to a cycle.
        /// </summary>
        /// <para> Use the provided dictionary to note the initial action symbol that first led to each action
        /// symbol. Any action symbol encountered that has already been encountered starting from a different
        /// initial action symbol inherits the loop characteristics of that initial action symbol, and thus is
        /// also not part of a cycle. However, any action symbol encountered that has already been encountered
        /// starting from the same initial action symbol is an indication that the current action symbol is
        /// part of a cycle.
        /// </para>
        /// <param name="actionSymbol">The action symbol to be checked.</param>
        /// <param name="requiredActionSymbols">Collection of actions which must be included.</param>
        /// <param name="firstReference">The first encountered action symbol that led to each action symbol.</param>
        private void CheckForCircularActionReference(WixActionSymbol actionSymbol, Dictionary <string, WixActionSymbol> requiredActionSymbols, Dictionary <WixActionSymbol, WixActionSymbol> firstReference)
        {
            WixActionSymbol currentActionSymbol = null;
            var             parentActionSymbol  = actionSymbol;

            do
            {
                var previousActionSymbol = currentActionSymbol ?? parentActionSymbol;
                currentActionSymbol = parentActionSymbol;

                if (!firstReference.TryGetValue(currentActionSymbol, out var existingInitialActionSymbol))
                {
                    firstReference[currentActionSymbol] = actionSymbol;
                }
                else if (existingInitialActionSymbol == actionSymbol)
                {
                    throw new WixException(ErrorMessages.ActionCircularDependency(currentActionSymbol.SourceLineNumbers, currentActionSymbol.SequenceTable.ToString(), currentActionSymbol.Action, previousActionSymbol.Action));
                }

                parentActionSymbol = this.GetParentActionSymbol(currentActionSymbol, requiredActionSymbols);
            } while (null != parentActionSymbol);
        }