Example #1
0
        /// <summary>
        /// Parses a module element.
        /// </summary>
        /// <param name="node">Element to parse.</param>
        private void ParseModuleElement(XElement node)
        {
            var    sourceLineNumbers      = Preprocessor.GetSourceLineNumbers(node);
            var    codepage               = 0;
            string moduleId               = null;
            string version                = null;
            var    setCodepage            = false;
            var    setPackageName         = false;
            var    setKeywords            = false;
            var    ignoredForMergeModules = false;

            this.GetDefaultPlatformAndInstallerVersion(out var platform, out var msiVersion);

            this.activeName     = null;
            this.activeLanguage = null;

            foreach (var attrib in node.Attributes())
            {
                if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
                {
                    switch (attrib.Name.LocalName)
                    {
                    case "Id":
                        this.activeName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        if ("PUT-MODULE-NAME-HERE" == this.activeName)
                        {
                            this.Core.Write(WarningMessages.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, this.activeName));
                        }
                        else
                        {
                            this.activeName = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        }
                        break;

                    case "Codepage":
                        codepage = this.Core.GetAttributeCodePageValue(sourceLineNumbers, attrib);
                        break;

                    case "Guid":
                        moduleId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false);
                        break;

                    case "InstallerVersion":
                        msiVersion = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, Int32.MaxValue);
                        break;

                    case "Language":
                        this.activeLanguage = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, Int16.MaxValue);
                        break;

                    case "Version":
                        version = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
                        break;

                    default:
                        this.Core.UnexpectedAttribute(node, attrib);
                        break;
                    }
                }
                else
                {
                    this.Core.ParseExtensionAttribute(node, attrib);
                }
            }

            if (null == this.activeName)
            {
                this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
            }

            if (null == moduleId)
            {
                this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Guid"));
            }

            if (null == this.activeLanguage)
            {
                this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Language"));
            }

            if (null == version)
            {
                this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version"));
            }
            else if (!CompilerCore.IsValidModuleOrBundleVersion(version))
            {
                this.Core.Write(WarningMessages.InvalidModuleOrBundleVersion(sourceLineNumbers, "Module", version));
            }

            try
            {
                this.compilingModule = true; // notice that we are actually building a Merge Module here
                this.Core.CreateActiveSection(this.activeName, SectionType.Module, codepage, this.Context.CompilationId);

                foreach (var child in node.Elements())
                {
                    if (CompilerCore.WixNamespace == child.Name.Namespace)
                    {
                        switch (child.Name.LocalName)
                        {
                        case "AdminExecuteSequence":
                            this.ParseSequenceElement(child, SequenceTable.AdminExecuteSequence);
                            break;

                        case "AdminUISequence":
                            this.ParseSequenceElement(child, SequenceTable.AdminUISequence);
                            break;

                        case "AdvertiseExecuteSequence":
                            this.ParseSequenceElement(child, SequenceTable.AdvertiseExecuteSequence);
                            break;

                        case "InstallExecuteSequence":
                            this.ParseSequenceElement(child, SequenceTable.InstallExecuteSequence);
                            break;

                        case "InstallUISequence":
                            this.ParseSequenceElement(child, SequenceTable.InstallUISequence);
                            break;

                        case "AppId":
                            this.ParseAppIdElement(child, null, YesNoType.Yes, null, null, null);
                            break;

                        case "Binary":
                            this.ParseBinaryElement(child);
                            break;

                        case "Component":
                            this.ParseComponentElement(child, ComplexReferenceParentType.Module, this.activeName, this.activeLanguage, CompilerConstants.IntegerNotSet, null, null);
                            break;

                        case "ComponentGroupRef":
                            this.ParseComponentGroupRefElement(child, ComplexReferenceParentType.Module, this.activeName, this.activeLanguage);
                            break;

                        case "ComponentRef":
                            this.ParseComponentRefElement(child, ComplexReferenceParentType.Module, this.activeName, this.activeLanguage);
                            break;

                        case "Configuration":
                            this.ParseConfigurationElement(child);
                            break;

                        case "CustomAction":
                            this.ParseCustomActionElement(child);
                            break;

                        case "CustomActionRef":
                            this.ParseSimpleRefElement(child, SymbolDefinitions.CustomAction);
                            break;

                        case "CustomTable":
                            this.ParseCustomTableElement(child);
                            break;

                        case "CustomTableRef":
                            this.ParseCustomTableRefElement(child);
                            break;

                        case "Dependency":
                            this.ParseDependencyElement(child);
                            break;

                        case "Directory":
                            this.ParseDirectoryElement(child, null, CompilerConstants.IntegerNotSet, String.Empty);
                            break;

                        case "DirectoryRef":
                            this.ParseDirectoryRefElement(child);
                            break;

                        case "EmbeddedChainer":
                            this.ParseEmbeddedChainerElement(child);
                            break;

                        case "EmbeddedChainerRef":
                            this.ParseSimpleRefElement(child, SymbolDefinitions.MsiEmbeddedChainer);
                            break;

                        case "EnsureTable":
                            this.ParseEnsureTableElement(child);
                            break;

                        case "Exclusion":
                            this.ParseExclusionElement(child);
                            break;

                        case "Icon":
                            this.ParseIconElement(child);
                            break;

                        case "IgnoreTable":
                            this.ParseIgnoreTableElement(child);
                            break;

                        case "Property":
                            this.ParsePropertyElement(child);
                            break;

                        case "PropertyRef":
                            this.ParseSimpleRefElement(child, SymbolDefinitions.Property);
                            break;

                        case "SetDirectory":
                            this.ParseSetDirectoryElement(child);
                            break;

                        case "SetProperty":
                            this.ParseSetPropertyElement(child);
                            break;

                        case "SFPCatalog":
                            string parentName = null;
                            this.ParseSFPCatalogElement(child, ref parentName);
                            break;

                        case "Substitution":
                            this.ParseSubstitutionElement(child);
                            break;

                        case "SummaryInformation":
                            this.ParseSummaryInformationElement(child, ref setCodepage, ref setPackageName, ref setKeywords, ref ignoredForMergeModules);
                            break;

                        case "UI":
                            this.ParseUIElement(child);
                            break;

                        case "UIRef":
                            this.ParseSimpleRefElement(child, SymbolDefinitions.WixUI);
                            break;

                        case "WixVariable":
                            this.ParseWixVariableElement(child);
                            break;

                        default:
                            this.Core.UnexpectedElement(node, child);
                            break;
                        }
                    }
                    else
                    {
                        this.Core.ParseExtensionElement(node, child);
                    }
                }


                if (!this.Core.EncounteredError)
                {
                    if (!setCodepage)
                    {
                        this.Core.AddSymbol(new SummaryInformationSymbol(sourceLineNumbers)
                        {
                            PropertyId = SummaryInformationType.Codepage,
                            Value      = "1252"
                        });
                    }

                    if (!setPackageName)
                    {
                        this.Core.AddSymbol(new SummaryInformationSymbol(sourceLineNumbers)
                        {
                            PropertyId = SummaryInformationType.Subject,
                            Value      = this.activeName
                        });
                    }

                    if (!setKeywords)
                    {
                        this.Core.AddSymbol(new SummaryInformationSymbol(sourceLineNumbers)
                        {
                            PropertyId = SummaryInformationType.Keywords,
                            Value      = "Installer"
                        });
                    }

                    var symbol = this.Core.AddSymbol(new ModuleSignatureSymbol(sourceLineNumbers, new Identifier(AccessModifier.Public, this.activeName, this.activeLanguage))
                    {
                        ModuleID = this.activeName,
                        Version  = version
                    });

                    symbol.Set((int)ModuleSignatureSymbolFields.Language, this.activeLanguage);

                    this.Core.AddSymbol(new SummaryInformationSymbol(sourceLineNumbers)
                    {
                        PropertyId = SummaryInformationType.PackageCode,
                        Value      = moduleId
                    });

                    this.ValidateAndAddCommonSummaryInformationSymbols(sourceLineNumbers, msiVersion, platform);
                }
            }
            finally
            {
                this.compilingModule = false; // notice that we are no longer building a Merge Module here
            }
        }