/// <summary>
        /// Processes the ProviderKey bundle attribute.
        /// </summary>
        /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
        /// <param name="parentElement">Parent element of attribute.</param>
        /// <param name="attribute">The XML attribute for the ProviderKey attribute.</param>
        private void ParseBundleProviderKeyAttribute(SourceLineNumber sourceLineNumbers, XElement parentElement, XAttribute attribute)
        {
            var providerKey = this.Core.GetAttributeValue(sourceLineNumbers, attribute);
            int illegalChar;

            // Make sure the key does not contain any illegal characters or values.
            if (String.IsNullOrEmpty(providerKey))
            {
                this.Messaging.Write(ErrorMessages.IllegalEmptyAttributeValue(sourceLineNumbers, parentElement.Name.LocalName, attribute.Name.LocalName));
            }
            else if (0 <= (illegalChar = providerKey.IndexOfAny(InvalidDependencyCharacters)))
            {
                this.Messaging.Write(CompilerErrors.IllegalCharactersInProvider(sourceLineNumbers, "ProviderKey", providerKey[illegalChar], String.Join(" ", InvalidDependencyCharacters)));
            }
            else if ("ALL" == providerKey)
            {
                this.Messaging.Write(CompilerErrors.ReservedValue(sourceLineNumbers, parentElement.Name.LocalName, "ProviderKey", providerKey));
            }

            if (!this.Messaging.EncounteredError)
            {
                // Generate the primary key for the row.
                var id = this.Core.CreateIdentifier("dep", attribute.Name.LocalName, providerKey);

                // Create the provider symbol for the bundle. The Component_ field is required
                // in the table definition but unused for bundles, so just set it to the valid ID.
                this.Core.AddSymbol(new WixDependencyProviderSymbol(sourceLineNumbers, id)
                {
                    ParentRef   = id.Id,
                    ProviderKey = providerKey,
                    Attributes  = WixDependencyProviderAttributes.ProvidesAttributesBundle,
                });
            }
        }
示例#2
0
        /// <summary>
        /// Parses a TagRef element for Software Id Tag registration under a PatchFamily element.
        /// </summary>
        /// <param name="node">The element to parse.</param>
        private void ParseTagRefElement(XElement node)
        {
            var    sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string regid             = null;

            foreach (var attrib in node.Attributes())
            {
                if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
                {
                    switch (attrib.Name.LocalName)
                    {
                    case "Regid":
                        regid = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        break;

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

            this.Core.ParseForExtensionElements(node);

            if (String.IsNullOrEmpty(regid))
            {
                this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Regid"));
            }
            else if (regid.Equals("example.com", StringComparison.OrdinalIgnoreCase))
            {
                this.Core.Write(CompilerErrors.ExampleRegid(sourceLineNumbers, regid));
            }

            if (!this.Core.EncounteredError)
            {
                var id = this.CreateTagId(regid);

                this.Core.AddSymbol(new WixPatchRefSymbol(sourceLineNumbers, id)
                {
                    Table       = SymbolDefinitions.Component.Name,
                    PrimaryKeys = id.Id
                });
            }
        }
        /// <summary>
        /// Processes the Provides element.
        /// </summary>
        /// <param name="node">The XML node for the Provides element.</param>
        /// <param name="packageType">The type of the package being chained into a bundle, or null if building an MSI package.</param>
        /// <param name="parentId">The identifier of the parent component or package.</param>
        /// <param name="possibleKeyPath">Possible KeyPath identifier.</param>
        /// <returns>Yes if this is the keypath.</returns>
        private YesNoType ParseProvidesElement(XElement node, WixBundlePackageType?packageType, string parentId, out string possibleKeyPath)
        {
            possibleKeyPath = null;

            var        sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            Identifier id          = null;
            string     key         = null;
            string     version     = null;
            string     displayName = null;

            foreach (var attrib in node.Attributes())
            {
                if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
                {
                    switch (attrib.Name.LocalName)
                    {
                    case "Id":
                        id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
                        break;

                    case "Key":
                        key = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        break;

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

                    case "DisplayName":
                        displayName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        break;

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

            // Make sure the key is valid. The key will default to the ProductCode for MSI packages
            // and the package code for MSP packages in the binder if not specified.
            if (!String.IsNullOrEmpty(key))
            {
                int illegalChar;

                // Make sure the key does not contain any illegal characters or values.
                if (0 <= (illegalChar = key.IndexOfAny(InvalidDependencyCharacters)))
                {
                    this.Messaging.Write(CompilerErrors.IllegalCharactersInProvider(sourceLineNumbers, "Key", key[illegalChar], String.Join(" ", InvalidDependencyCharacters)));
                }
                else if ("ALL" == key)
                {
                    this.Messaging.Write(CompilerErrors.ReservedValue(sourceLineNumbers, node.Name.LocalName, "Key", key));
                }
            }
            else if (!packageType.HasValue)
            {
                // Make sure the ProductCode is authored and set the key.
                this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Property, "ProductCode");
                key = "!(bind.property.ProductCode)";
            }
            else if (WixBundlePackageType.Exe == packageType || WixBundlePackageType.Msu == packageType)
            {
                // Must specify the provider key when authored for a package.
                this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key"));
            }

            // The Version attribute should not be authored in or for an MSI package.
            if (!String.IsNullOrEmpty(version))
            {
                switch (packageType)
                {
                case null:
                    this.Messaging.Write(CompilerWarnings.DiscouragedVersionAttribute(sourceLineNumbers));
                    break;

                case WixBundlePackageType.Msi:
                    this.Messaging.Write(CompilerWarnings.DiscouragedVersionAttribute(sourceLineNumbers, parentId));
                    break;
                }
            }
            else if (WixBundlePackageType.Msp == packageType || WixBundlePackageType.Msu == packageType)
            {
                // Must specify the Version when authored for packages that do not contain a version.
                this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version"));
            }

            // Need the element ID for child element processing, so generate now if not authored.
            if (null == id)
            {
                id = this.Core.CreateIdentifier("dep", node.Name.LocalName, parentId, key);
            }

            foreach (var child in node.Elements())
            {
                if (CompilerCore.WixNamespace == child.Name.Namespace)
                {
                    switch (child.Name.LocalName)
                    {
                    case "Requires":
                        this.ParseRequiresElement(child, id.Id);
                        break;

                    case "RequiresRef":
                        this.ParseRequiresRefElement(child, id.Id, requiresAction: !packageType.HasValue);
                        break;

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

            if (!this.Messaging.EncounteredError)
            {
                var symbol = this.Core.AddSymbol(new WixDependencyProviderSymbol(sourceLineNumbers, id)
                {
                    ParentRef   = parentId,
                    ProviderKey = key,
                });

                if (!String.IsNullOrEmpty(version))
                {
                    symbol.Version = version;
                }

                if (!String.IsNullOrEmpty(displayName))
                {
                    symbol.DisplayName = displayName;
                }

                if (!packageType.HasValue)
                {
                    // Generate registry rows for the provider using binder properties.
                    var keyProvides = String.Concat(DependencyRegistryRoot, key);
                    var root        = RegistryRootType.MachineUser;

                    var value = "[ProductCode]";
                    this.Core.CreateRegistryRow(sourceLineNumbers, root, keyProvides, null, value, parentId);

                    value = !String.IsNullOrEmpty(version) ? version : "[ProductVersion]";
                    var versionRegistrySymbol = this.Core.CreateRegistryRow(sourceLineNumbers, root, keyProvides, "Version", value, parentId);

                    value = !String.IsNullOrEmpty(displayName) ? displayName : "[ProductName]";
                    this.Core.CreateRegistryRow(sourceLineNumbers, root, keyProvides, "DisplayName", value, parentId);

                    // Use the Version registry value and use that as a potential key path.
                    possibleKeyPath = versionRegistrySymbol.Id;
                }
            }

            return(YesNoType.NotSet);
        }
        /// <summary>
        /// Processes the Requires element.
        /// </summary>
        /// <param name="node">The XML node for the Requires element.</param>
        /// <param name="providerId">The parent provider identifier.</param>
        private void ParseRequiresElement(XElement node, string providerId)
        {
            var        sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            Identifier id          = null;
            string     providerKey = null;
            string     minVersion  = null;
            string     maxVersion  = null;
            var        attributes  = WixDependencySymbolAttributes.None;
            var        illegalChar = -1;

            foreach (var attrib in node.Attributes())
            {
                if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
                {
                    switch (attrib.Name.LocalName)
                    {
                    case "Id":
                        id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
                        break;

                    case "ProviderKey":
                        providerKey = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        break;

                    case "Minimum":
                        minVersion = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
                        break;

                    case "Maximum":
                        maxVersion = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
                        break;

                    case "IncludeMinimum":
                        if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                        {
                            attributes |= WixDependencySymbolAttributes.RequiresAttributesMinVersionInclusive;
                        }
                        break;

                    case "IncludeMaximum":
                        if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                        {
                            attributes |= WixDependencySymbolAttributes.RequiresAttributesMaxVersionInclusive;
                        }
                        break;

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

            this.Core.ParseForExtensionElements(node);

            if (null == id)
            {
                // Generate an ID only if this element is authored under a Provides element; otherwise, a RequiresRef
                // element will be necessary and the Id attribute will be required.
                if (!String.IsNullOrEmpty(providerId))
                {
                    id = this.Core.CreateIdentifier("dep", node.Name.LocalName, providerKey);
                }
                else
                {
                    this.Messaging.Write(ErrorMessages.ExpectedAttributeWhenElementNotUnderElement(sourceLineNumbers, node.Name.LocalName, "Id", "Provides"));
                    id = Identifier.Invalid;
                }
            }

            if (String.IsNullOrEmpty(providerKey))
            {
                this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ProviderKey"));
            }
            // Make sure the key does not contain any illegal characters.
            else if (0 <= (illegalChar = providerKey.IndexOfAny(InvalidDependencyCharacters)))
            {
                this.Messaging.Write(CompilerErrors.IllegalCharactersInProvider(sourceLineNumbers, "ProviderKey", providerKey[illegalChar], String.Join(" ", InvalidDependencyCharacters)));
            }

            if (!this.Messaging.EncounteredError)
            {
                this.Core.AddSymbol(new WixDependencySymbol(sourceLineNumbers, id)
                {
                    ProviderKey = providerKey,
                    MinVersion  = minVersion,
                    MaxVersion  = maxVersion,
                    Attributes  = attributes
                });

                // Create the relationship between this WixDependency symbol and the WixDependencyProvider symbol.
                if (!String.IsNullOrEmpty(providerId))
                {
                    this.Core.AddSymbol(new WixDependencyRefSymbol(sourceLineNumbers)
                    {
                        WixDependencyProviderRef = providerId,
                        WixDependencyRef         = id.Id,
                    });
                }
            }
        }
示例#5
0
        /// <summary>
        /// Parses a Tag element for Software Id Tag registration under a Bundle element.
        /// </summary>
        /// <param name="node">The element to parse.</param>
        private void ParseBundleTagElement(XElement node)
        {
            var    sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string name        = null;
            string regid       = null;
            string installPath = null;

            foreach (var attrib in node.Attributes())
            {
                if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
                {
                    switch (attrib.Name.LocalName)
                    {
                    case "Name":
                        name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false);
                        break;

                    case "Regid":
                        regid = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        break;

                    case "InstallDirectory":
                    case "Bitness":
                        this.Core.Write(ErrorMessages.ExpectedParentWithAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Package"));
                        break;

                    case "InstallPath":
                        installPath = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        break;

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

            this.Core.ParseForExtensionElements(node);

            if (String.IsNullOrEmpty(name))
            {
                name = node.Parent?.Attribute("Name")?.Value;

                if (String.IsNullOrEmpty(name))
                {
                    this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
                }
            }

            if (!String.IsNullOrEmpty(name) && !this.Core.IsValidLongFilename(name))
            {
                this.Core.Write(CompilerErrors.IllegalName(sourceLineNumbers, node.Name.LocalName, name));
            }

            if (String.IsNullOrEmpty(regid))
            {
                this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Regid"));
            }
            else if (regid.Equals("example.com", StringComparison.OrdinalIgnoreCase))
            {
                this.Core.Write(CompilerErrors.ExampleRegid(sourceLineNumbers, regid));
            }

            if (String.IsNullOrEmpty(installPath))
            {
                this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "InstallPath"));
            }

            if (!this.Core.EncounteredError)
            {
                this.Core.AddSymbol(new WixBundleTagSymbol(sourceLineNumbers)
                {
                    Filename    = String.Concat(name, ".swidtag"),
                    Regid       = regid,
                    Name        = name,
                    InstallPath = installPath
                });
            }
        }
示例#6
0
        /// <summary>
        /// Parses a Tag element for Software Id Tag registration under a Package element.
        /// </summary>
        /// <param name="node">The element to parse.</param>
        private void ParsePackageTagElement(XElement node)
        {
            var        sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            Identifier id               = null;
            string     name             = null;
            string     regid            = null;
            string     feature          = null;
            string     installDirectory = null;
            var        win64            = this.Context.IsCurrentPlatform64Bit;

            foreach (var attrib in node.Attributes())
            {
                if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
                {
                    switch (attrib.Name.LocalName)
                    {
                    case "Id":
                        id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
                        break;

                    case "Name":
                        name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false);
                        break;

                    case "Regid":
                        regid = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        break;

                    case "Feature":
                        feature = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        break;

                    case "InstallDirectory":
                        installDirectory = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        break;

                    case "InstallPath":
                        this.Core.Write(ErrorMessages.ExpectedParentWithAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Bundle"));
                        break;

                    case "Bitness":
                        var bitnessValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        switch (bitnessValue)
                        {
                        case "always32":
                            win64 = false;
                            break;

                        case "always64":
                            win64 = true;
                            break;

                        case "default":
                        case "":
                            break;

                        default:
                            this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, bitnessValue, "default", "always32", "always64"));
                            break;
                        }
                        break;

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

            this.Core.ParseForExtensionElements(node);

            if (String.IsNullOrEmpty(name))
            {
                name = node.Parent?.Attribute("Name")?.Value;

                if (String.IsNullOrEmpty(name))
                {
                    this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
                }
            }

            if (!String.IsNullOrEmpty(name) && !this.Core.IsValidLongFilename(name))
            {
                this.Core.Write(CompilerErrors.IllegalName(sourceLineNumbers, node.Name.LocalName, name));
            }

            if (String.IsNullOrEmpty(regid))
            {
                this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Regid"));
            }
            else if (regid.Equals("example.com", StringComparison.OrdinalIgnoreCase))
            {
                this.Core.Write(CompilerErrors.ExampleRegid(sourceLineNumbers, regid));
                return;
            }
            else if (id == null)
            {
                id = this.CreateTagId(regid);
            }

            if (String.IsNullOrEmpty(installDirectory))
            {
                this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "InstallDirectory"));
            }

            if (!this.Core.EncounteredError)
            {
                var fileName = String.Concat(name, ".swidtag");

                this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, installDirectory);
                this.Core.AddSymbol(new DirectorySymbol(sourceLineNumbers, id)
                {
                    Name = "swidtag",
                    ParentDirectoryRef          = installDirectory,
                    ComponentGuidGenerationSeed = "4BAD0C8B-3AF0-BFE3-CC83-094749A1C4B1"
                });

                this.Core.AddSymbol(new ComponentSymbol(sourceLineNumbers, id)
                {
                    ComponentId  = "*",
                    DirectoryRef = id.Id,
                    KeyPath      = id.Id,
                    KeyPathType  = ComponentKeyPathType.File,
                    Location     = ComponentLocation.LocalOnly,
                    Win64        = win64
                });

                this.Core.AddSymbol(new FileSymbol(sourceLineNumbers, id)
                {
                    ComponentRef = id.Id,
                    Name         = fileName,
                    DiskId       = 1,
                    Attributes   = FileSymbolAttributes.ReadOnly,
                });

                if (!String.IsNullOrEmpty(feature))
                {
                    this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Feature, feature);
                }
                else
                {
                    feature = "WixSwidTag";
                    this.Core.AddSymbol(new FeatureSymbol(sourceLineNumbers, new Identifier(AccessModifier.Section, feature))
                    {
                        Title             = "ISO/IEC 19770-2",
                        Level             = 1,
                        InstallDefault    = FeatureInstallDefault.Local,
                        Display           = 0,
                        DisallowAdvertise = true,
                        DisallowAbsent    = true,
                    });
                }
                this.Core.CreateComplexReference(sourceLineNumbers, ComplexReferenceParentType.Feature, feature, null, ComplexReferenceChildType.Component, id.Id, true);

                this.Core.EnsureTable(sourceLineNumbers, "SoftwareIdentificationTag");
                this.Core.AddSymbol(new WixProductTagSymbol(sourceLineNumbers, id)
                {
                    FileRef = id.Id,
                    Regid   = regid,
                    Name    = name
                });
            }
        }