Beispiel #1
0
        /// <summary>
        /// Parse a localization file from an XML format.
        /// </summary>
        /// <param name="reader">XmlReader where the localization file is persisted.</param>
        /// <param name="tableDefinitions">Collection containing TableDefinitions to use when parsing the localization file.</param>
        /// <returns>The parsed localization.</returns>
        internal static Localization Parse(XmlReader reader, TableDefinitionCollection tableDefinitions)
        {
            Debug.Assert("WixLocalization" == reader.LocalName);

            bool   empty    = reader.IsEmptyElement;
            int    codepage = -1;
            string culture  = null;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "Codepage":
                    try
                    {
                        codepage = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture.NumberFormat);
                    }
                    catch (FormatException)
                    {
                        throw new WixException(WixErrors.IllegalIntegerValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "WixLocalization", reader.Name, reader.Value));
                    }
                    catch (OverflowException)
                    {
                        throw new WixException(WixErrors.IllegalIntegerValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "WixLocalization", reader.Name, reader.Value));
                    }
                    break;

                case "Culture":
                    culture = reader.Value;
                    break;

                default:
                    if (!reader.NamespaceURI.StartsWith("http://www.w3.org/"))
                    {
                        throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "WixLocalization", reader.Name));
                    }
                    break;
                }
            }

            if (null == culture)
            {
                throw new WixException(WixErrors.ExpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "WixLocalization", "Culture"));
            }

            Localization localization = new Localization(codepage, culture);

            if (!empty)
            {
                bool done = false;

                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        switch (reader.LocalName)
                        {
                        case "String":
                            ParseString(reader, tableDefinitions, localization);
                            break;

                        default:
                            throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "WixLocalization", reader.Name));
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "WixLocalization"));
                }
            }

            return(localization);
        }
        /// <summary>
        /// Parses a PlugCollectionInto element.
        /// </summary>
        /// <param name="node">Element to process.</param>
        /// <param name="parentId">Identifier of the parent help collection.</param>
        private void ParsePlugCollectionIntoElement(XElement node, string parentId)
        {
            SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string           hxa                        = null;
            string           hxt                        = null;
            string           hxtParent                  = null;
            string           namespaceParent            = null;
            string           feature                    = null;
            YesNoType        suppressExternalNamespaces = YesNoType.No;
            bool             pluginVS05                 = false;
            bool             pluginVS08                 = false;

            foreach (XAttribute attrib in node.Attributes())
            {
                if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
                {
                    switch (attrib.Name.LocalName)
                    {
                    case "Attributes":
                        hxa = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        break;

                    case "TableOfContents":
                        hxt = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        break;

                    case "TargetCollection":
                        namespaceParent = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        break;

                    case "TargetTableOfContents":
                        hxtParent = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        break;

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

                    case "SuppressExternalNamespaces":
                        suppressExternalNamespaces = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                        break;

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

            pluginVS05 = namespaceParent.Equals("MS_VSIPCC_v80", StringComparison.Ordinal);
            pluginVS08 = namespaceParent.Equals("MS.VSIPCC.v90", StringComparison.Ordinal);

            if (null == namespaceParent)
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "TargetCollection"));
            }

            if (null == feature && (pluginVS05 || pluginVS08) && YesNoType.No == suppressExternalNamespaces)
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "TargetFeature"));
            }

            this.Core.ParseForExtensionElements(node);

            if (!this.Core.EncounteredError)
            {
                Row row = this.Core.CreateRow(sourceLineNumbers, "HelpPlugin");
                row[0] = parentId;
                row[1] = namespaceParent;
                row[2] = hxt;
                row[3] = hxa;
                row[4] = hxtParent;

                if (pluginVS05)
                {
                    if (YesNoType.No == suppressExternalNamespaces)
                    {
                        // Bring in the help 2 base namespace components for VS 2005
                        this.Core.CreateComplexReference(sourceLineNumbers, ComplexReferenceParentType.Feature, feature, String.Empty,
                                                         ComplexReferenceChildType.ComponentGroup, "Help2_VS2005_Namespace_Components", false);
                        // Reference CustomAction since nothing will happen without it
                        this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction",
                                                        "CA_HxMerge_VSIPCC_VSCC");
                    }
                }
                else if (pluginVS08)
                {
                    if (YesNoType.No == suppressExternalNamespaces)
                    {
                        // Bring in the help 2 base namespace components for VS 2008
                        this.Core.CreateComplexReference(sourceLineNumbers, ComplexReferenceParentType.Feature, feature, String.Empty,
                                                         ComplexReferenceChildType.ComponentGroup, "Help2_VS2008_Namespace_Components", false);
                        // Reference CustomAction since nothing will happen without it
                        this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction",
                                                        "CA_ScheduleExtHelpPlugin_VSCC_VSIPCC");
                    }
                }
                else
                {
                    // Reference the parent namespace to enforce the foreign key relationship
                    this.Core.CreateSimpleReference(sourceLineNumbers, "HelpNamespace",
                                                    namespaceParent);
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Parses a Condition element for Bundles.
        /// </summary>
        /// <param name="node">The element to parse.</param>
        private void ParseConditionElement(XmlNode node)
        {
            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string condition = CompilerCore.GetConditionInnerText(node); // condition is the inner text of the element.
            string message   = null;

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    switch (attrib.LocalName)
                    {
                    case "Message":
                        message = this.Core.GetAttributeValue(sourceLineNumbers, attrib, false);
                        break;

                    default:
                        this.Core.UnexpectedAttribute(sourceLineNumbers, attrib);
                        break;
                    }
                }
                else
                {
                    this.Core.UnsupportedExtensionAttribute(sourceLineNumbers, attrib);
                }
            }

            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        this.Core.UnexpectedElement(node, child);
                    }
                    else
                    {
                        this.Core.UnsupportedExtensionElement(node, child);
                    }
                }
            }

            // Error check the values.
            if (String.IsNullOrEmpty(condition))
            {
                this.Core.OnMessage(WixErrors.ConditionExpected(sourceLineNumbers, node.Name));
            }

            if (null == message)
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Message"));
            }

            if (!this.Core.EncounteredError)
            {
                Row row = this.Core.CreateRow(sourceLineNumbers, "WixBalCondition");
                row[0] = condition;
                row[1] = message;

                if (null == this.addedConditionLineNumber)
                {
                    this.addedConditionLineNumber = sourceLineNumbers;
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Include transforms in a patch.
        /// </summary>
        /// <param name="transforms">List of transforms to attach.</param>
        public void AttachTransforms(ArrayList transforms)
        {
            int emptyTransform = 0;

            if (transforms == null || transforms.Count == 0)
            {
                throw new WixException(WixErrors.PatchWithoutTransforms());
            }

            // Get the patch id from the WixPatchId table.
            string patchId         = null;
            Table  wixPatchIdTable = this.patch.Tables["WixPatchId"];

            if (null != wixPatchIdTable && 0 < wixPatchIdTable.Rows.Count)
            {
                Row patchIdRow = wixPatchIdTable.Rows[0];
                if (null != patchIdRow)
                {
                    patchId = patchIdRow[0].ToString();
                }
            }

            // enumerate patch.Media to map diskId to Media row
            Hashtable mediaRows       = new Hashtable();
            Table     patchMediaTable = patch.Tables["Media"];

            if (patchMediaTable != null)
            {
                foreach (MediaRow row in patchMediaTable.Rows)
                {
                    int media = row.DiskId;
                    mediaRows[media] = row;
                }
            }

            // enumerate patch.WixPatchBaseline to map baseline to diskId
            Hashtable baselineMedia      = new Hashtable();
            Table     patchBaselineTable = patch.Tables["WixPatchBaseline"];

            if (patchBaselineTable != null)
            {
                foreach (Row row in patchBaselineTable.Rows)
                {
                    string baseline = (string)row[0];
                    int    media    = (int)row[1];
                    if (baselineMedia.Contains(baseline))
                    {
                        throw new InvalidOperationException(String.Format("PatchBaseline '{0}' authored into multiple Media.", baseline));
                    }
                    baselineMedia[baseline] = media;
                }
            }

            // enumerate transforms
            ArrayList productCodes   = new ArrayList();
            ArrayList transformNames = new ArrayList();
            int       transformCount = 0;

            foreach (PatchTransform mainTransform in transforms)
            {
                string baseline = null;
                int    media    = -1;

                if (baselineMedia.Contains(mainTransform.Baseline))
                {
                    int newMedia = (int)baselineMedia[mainTransform.Baseline];
                    if (media != -1 && media != newMedia)
                    {
                        throw new InvalidOperationException(String.Format("Transform authored into multiple Media '{0}' and '{1}'.", media, newMedia));
                    }
                    baseline = mainTransform.Baseline;
                    media    = newMedia;
                }

                if (media == -1)
                {
                    // transform's baseline not attached to any Media
                    continue;
                }

                Table patchRefTable = patch.Tables["WixPatchRef"];
                if (patchRefTable != null && patchRefTable.Rows.Count > 0)
                {
                    if (!this.ReduceTransform(mainTransform.Transform, patchRefTable))
                    {
                        // transform has none of the content authored into this patch
                        emptyTransform++;
                        continue;
                    }
                }

                // ensure consistent File.Sequence within each Media
                MediaRow mediaRow = (MediaRow)mediaRows[media];
                // TODO: should this be authored rather than inferring it from DiskId?
                mediaRow.LastSequence = mediaRow.DiskId;

                // ignore media table from transform.
                mainTransform.Transform.Tables.Remove("Media");
                mainTransform.Transform.Tables.Remove("WixMedia");
                mainTransform.Transform.Tables.Remove("MsiDigitalSignature");

                string productCode     = null;
                Output pairedTransform = this.BuildPairedTransform(patchId, mainTransform.Transform, mediaRow, ref productCode);
                productCodes.Add(productCode);

                // attach these transforms to the patch object
                // TODO: is this an acceptable way to auto-generate transform stream names?
                string transformName = baseline + "." + (++transformCount).ToString();
                patch.SubStorages.Add(new SubStorage(transformName, mainTransform.Transform));
                patch.SubStorages.Add(new SubStorage("#" + transformName, pairedTransform));
                transformNames.Add(":" + transformName);
                transformNames.Add(":#" + transformName);
            }

            if (emptyTransform == transforms.Count)
            {
                throw new WixException(WixErrors.PatchWithoutValidTransforms());
            }

            // populate MSP summary information
            Table patchSummaryInfo = patch.EnsureTable(this.tableDefinitions["_SummaryInformation"]);

            // remove any existing data for these fields
            for (int i = patchSummaryInfo.Rows.Count - 1; i >= 0; i--)
            {
                Row row = patchSummaryInfo.Rows[i];
                switch ((SummaryInformation.Patch)row[0])
                {
                case SummaryInformation.Patch.ProductCodes:
                case SummaryInformation.Patch.TransformNames:
                case SummaryInformation.Patch.PatchCode:
                case SummaryInformation.Patch.InstallerRequirement:
                    patchSummaryInfo.Rows.RemoveAt(i);
                    break;
                }
            }

            // Semicolon delimited list of the product codes that can accept the patch.
            Row templateRow = patchSummaryInfo.CreateRow(null);

            templateRow[0] = (int)SummaryInformation.Patch.ProductCodes;
            templateRow[1] = String.Join(";", (string[])productCodes.ToArray(typeof(string)));

            // Semicolon delimited list of transform substorage names in the order they are applied.
            Row savedbyRow = patchSummaryInfo.CreateRow(null);

            savedbyRow[0] = (int)SummaryInformation.Patch.TransformNames;
            savedbyRow[1] = String.Join(";", (string[])transformNames.ToArray(typeof(string)));

            // GUID patch code for the patch.
            Row revisionRow = patchSummaryInfo.CreateRow(null);

            revisionRow[0] = (int)SummaryInformation.Patch.PatchCode;
            revisionRow[1] = patchId;

            // Indicates the minimum Windows Installer version that is required to install the patch.
            Row wordsRow = patchSummaryInfo.CreateRow(null);

            wordsRow[0] = (int)SummaryInformation.Patch.InstallerRequirement;
            wordsRow[1] = ((int)SummaryInformation.InstallerRequirement.Version31).ToString();

            Row security = patchSummaryInfo.CreateRow(null);

            security[0] = 19; //PID_SECURITY
            security[1] = "4";

            Table msiPatchMetadataTable = patch.Tables["MsiPatchMetadata"];

            if (null != msiPatchMetadataTable)
            {
                Hashtable metadataTable = new Hashtable();
                foreach (Row row in msiPatchMetadataTable.Rows)
                {
                    metadataTable.Add(row.Fields[1].Data.ToString(), row.Fields[2].Data.ToString());
                }

                if (metadataTable.Contains("DisplayName"))
                {
                    string comment = String.Concat("This patch contains the logic and data required to install ", metadataTable["DisplayName"]);

                    Row title = patchSummaryInfo.CreateRow(null);
                    title[0] = 2; //PID_TITLE
                    title[1] = metadataTable["DisplayName"];

                    Row comments = patchSummaryInfo.CreateRow(null);
                    comments[0] = 6; //PID_COMMENTS
                    comments[1] = comment;
                }

                if (metadataTable.Contains("CodePage"))
                {
                    Row codePage = patchSummaryInfo.CreateRow(null);
                    codePage[0] = 1; //PID_CODEPAGE
                    codePage[1] = metadataTable["CodePage"];
                }

                if (metadataTable.Contains("Description"))
                {
                    Row subject = patchSummaryInfo.CreateRow(null);
                    subject[0] = 3; //PID_SUBJECT
                    subject[1] = metadataTable["Description"];
                }

                if (metadataTable.Contains("ManufacturerName"))
                {
                    Row author = patchSummaryInfo.CreateRow(null);
                    author[0] = 4; //PID_AUTHOR
                    author[1] = metadataTable["ManufacturerName"];
                }
            }
        }
        /// <summary>
        /// Parses a HelpFile element.
        /// </summary>
        /// <param name="node">Element to process.</param>
        /// <param name="fileId">Identifier of the parent file element.</param>
        private void ParseHelpFileElement(XElement node, string fileId)
        {
            SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string           id   = null;
            string           name = null;
            int       language    = CompilerConstants.IntegerNotSet;
            string    hxi         = null;
            string    hxq         = null;
            string    hxr         = null;
            string    samples     = null;
            YesNoType suppressCAs = YesNoType.No;

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

                    case "AttributeIndex":
                        hxr = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        this.Core.CreateSimpleReference(sourceLineNumbers, "File", hxr);
                        break;

                    case "Index":
                        hxi = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        this.Core.CreateSimpleReference(sourceLineNumbers, "File", hxi);
                        break;

                    case "Language":
                        language = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
                        break;

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

                    case "SampleLocation":
                        samples = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        this.Core.CreateSimpleReference(sourceLineNumbers, "File", samples);
                        break;

                    case "Search":
                        hxq = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        this.Core.CreateSimpleReference(sourceLineNumbers, "File", hxq);
                        break;

                    case "SuppressCustomActions":
                        suppressCAs = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                        break;

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

            if (null == id)
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
            }

            if (null == name)
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
            }

            //uninstall will always fail silently, leaving file registered, if Language is not set
            if (CompilerConstants.IntegerNotSet == language)
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Language"));
            }

            this.Core.ParseForExtensionElements(node);

            if (!this.Core.EncounteredError)
            {
                Row row = this.Core.CreateRow(sourceLineNumbers, "HelpFile");
                row[0] = id;
                row[1] = name;
                row[2] = language;
                row[3] = fileId;
                row[4] = hxi;
                row[5] = hxq;
                row[6] = hxr;
                row[7] = samples;

                if (YesNoType.No == suppressCAs)
                {
                    this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "CA_RegisterMicrosoftHelp.3643236F_FC70_11D3_A536_0090278A1BB8");
                }
            }
        }
        /// <summary>
        /// Loads a HeatExtension from a type description string.
        /// </summary>
        /// <param name="extension">The extension type description string.</param>
        /// <returns>The loaded HeatExtension.</returns>
        /// <remarks>
        /// <paramref name="extension"/> can be in several different forms:
        /// <list type="number">
        /// <item><term>AssemblyQualifiedName (TopNamespace.SubNameSpace.ContainingClass+NestedClass, MyAssembly, Version=1.3.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089)</term></item>
        /// <item><term>AssemblyName (MyAssembly, Version=1.3.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089)</term></item>
        /// <item><term>Absolute path to an assembly (C:\MyExtensions\ExtensionAssembly.dll)</term></item>
        /// <item><term>Filename of an assembly in the application directory (ExtensionAssembly.dll)</term></item>
        /// <item><term>Relative path to an assembly (..\..\MyExtensions\ExtensionAssembly.dll)</term></item>
        /// </list>
        /// To specify a particular class to use, prefix the fully qualified class name to the assembly and separate them with a comma.
        /// For example: "TopNamespace.SubNameSpace.ContainingClass+NestedClass, C:\MyExtensions\ExtensionAssembly.dll"
        /// </remarks>
        public static HeatExtension Load(string extension)
        {
            Type   extensionType = null;
            int    commaIndex    = extension.IndexOf(',');
            string className     = String.Empty;
            string assemblyName  = extension;

            if (0 <= commaIndex)
            {
                className    = extension.Substring(0, commaIndex);
                assemblyName = (extension.Length <= commaIndex + 1 ? String.Empty : extension.Substring(commaIndex + 1));
            }

            className    = className.Trim();
            assemblyName = assemblyName.Trim();

            if (null == extensionType && 0 < assemblyName.Length)
            {
                Assembly extensionAssembly;

                // case 3: Absolute path to an assembly
                if (Path.IsPathRooted(assemblyName))
                {
                    extensionAssembly = ExtensionLoadFrom(assemblyName);
                }
                else
                {
                    try
                    {
                        // case 2: AssemblyName
                        extensionAssembly = Assembly.Load(assemblyName);
                    }
                    catch (IOException e)
                    {
                        if (e is FileLoadException || e is FileNotFoundException)
                        {
                            try
                            {
                                // case 4: Filename of an assembly in the application directory
                                extensionAssembly = Assembly.Load(Path.GetFileNameWithoutExtension(assemblyName));
                            }
                            catch (IOException innerE)
                            {
                                if (innerE is FileLoadException || innerE is FileNotFoundException)
                                {
                                    // case 5: Relative path to an assembly

                                    // we want to use Assembly.Load when we can because it has some benefits over Assembly.LoadFrom
                                    // (see the documentation for Assembly.LoadFrom). However, it may fail when the path is a relative
                                    // path, so we should try Assembly.LoadFrom one last time. We could have detected a directory
                                    // separator character and used Assembly.LoadFrom directly, but dealing with path canonicalization
                                    // issues is something we don't want to deal with if we don't have to.
                                    extensionAssembly = ExtensionLoadFrom(assemblyName);
                                }
                                else
                                {
                                    throw new WixException(WixErrors.InvalidExtension(assemblyName, innerE.Message));
                                }
                            }
                        }
                        else
                        {
                            throw new WixException(WixErrors.InvalidExtension(assemblyName, e.Message));
                        }
                    }
                }

                if (0 < className.Length)
                {
                    try
                    {
                        // case 1: AssemblyQualifiedName
                        extensionType = extensionAssembly.GetType(className, true /* throwOnError */, true /* ignoreCase */);
                    }
                    catch (Exception e)
                    {
                        throw new WixException(WixErrors.InvalidExtensionType(assemblyName, className, e.GetType().ToString(), e.Message));
                    }
                }
                else
                {
                    // if no class name was specified, then let's hope the assembly defined a default WixExtension
                    AssemblyDefaultHeatExtensionAttribute extensionAttribute = (AssemblyDefaultHeatExtensionAttribute)Attribute.GetCustomAttribute(extensionAssembly, typeof(AssemblyDefaultHeatExtensionAttribute));

                    if (null != extensionAttribute)
                    {
                        extensionType = extensionAttribute.ExtensionType;
                    }
                    else
                    {
                        throw new WixException(WixErrors.InvalidExtensionType(assemblyName, typeof(AssemblyDefaultHeatExtensionAttribute).ToString()));
                    }
                }
            }

            if (extensionType.IsSubclassOf(typeof(HeatExtension)))
            {
                return(Activator.CreateInstance(extensionType) as HeatExtension);
            }
            else
            {
                throw new WixException(WixErrors.InvalidExtensionType(extension, extensionType.ToString(), typeof(HeatExtension).ToString()));
            }
        }
Beispiel #7
0
        /// <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>
        /// <param name="requiresAction">Whether the Requires custom action should be referenced.</param>
        private void ParseRequiresElement(XElement node, string providerId, bool requiresAction)
        {
            SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            Identifier       id          = null;
            string           providerKey = null;
            string           minVersion  = null;
            string           maxVersion  = null;
            int attributes  = 0;
            int illegalChar = -1;

            foreach (XAttribute attrib in node.Attributes())
            {
                if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == 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 |= DependencyCommon.RequiresAttributesMinVersionInclusive;
                        }
                        break;

                    case "IncludeMaximum":
                        if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                        {
                            attributes |= DependencyCommon.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.Core.OnMessage(WixErrors.ExpectedAttributeWhenElementNotUnderElement(sourceLineNumbers, node.Name.LocalName, "Id", "Provides"));
                    id = Identifier.Invalid;
                }
            }

            if (String.IsNullOrEmpty(providerKey))
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "ProviderKey"));
            }
            // Make sure the key does not contain any illegal characters.
            else if (0 <= (illegalChar = providerKey.IndexOfAny(DependencyCommon.InvalidCharacters)))
            {
                StringBuilder sb = new StringBuilder(DependencyCommon.InvalidCharacters.Length * 2);
                Array.ForEach <char>(DependencyCommon.InvalidCharacters, c => sb.Append(c).Append(" "));

                this.Core.OnMessage(DependencyErrors.IllegalCharactersInProvider(sourceLineNumbers, "ProviderKey", providerKey[illegalChar], sb.ToString()));
            }


            if (!this.Core.EncounteredError)
            {
                // Reference the Require custom action if required.
                if (requiresAction)
                {
                    if (Platform.ARM == this.Core.CurrentPlatform)
                    {
                        // Ensure the ARM version of the CA is referenced.
                        this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "WixDependencyRequire_ARM");
                    }
                    else
                    {
                        // All other supported platforms use x86.
                        this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "WixDependencyRequire");
                    }
                }

                Row row = this.Core.CreateRow(sourceLineNumbers, "WixDependency", id);
                row[1] = providerKey;
                row[2] = minVersion;
                row[3] = maxVersion;

                if (0 != attributes)
                {
                    row[4] = attributes;
                }

                // Create the relationship between this WixDependency row and the WixDependencyProvider row.
                if (!String.IsNullOrEmpty(providerId))
                {
                    // Create the relationship between the WixDependency row and the parent WixDependencyProvider row.
                    row    = this.Core.CreateRow(sourceLineNumbers, "WixDependencyRef");
                    row[0] = providerId;
                    row[1] = id.Id;
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Creates a Row from the XmlReader.
        /// </summary>
        /// <param name="reader">Reader to get data from.</param>
        /// <param name="table">Table for this row.</param>
        /// <returns>New row object.</returns>
        internal static Row Parse(XmlReader reader, Table table)
        {
            Debug.Assert("row" == reader.LocalName);

            bool             empty             = reader.IsEmptyElement;
            RowOperation     operation         = RowOperation.None;
            string           sectionId         = null;
            SourceLineNumber sourceLineNumbers = null;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "op":
                    switch (reader.Value)
                    {
                    case "add":
                        operation = RowOperation.Add;
                        break;

                    case "delete":
                        operation = RowOperation.Delete;
                        break;

                    case "modify":
                        operation = RowOperation.Modify;
                        break;

                    default:
                        throw new WixException(WixErrors.IllegalAttributeValue(SourceLineNumber.CreateFromUri(reader.BaseURI), "row", reader.Name, reader.Value, "Add", "Delete", "Modify"));
                    }
                    break;

                case "sectionId":
                    sectionId = reader.Value;
                    break;

                case "sourceLineNumber":
                    sourceLineNumbers = new SourceLineNumber(reader.Value);
                    break;

                default:
                    if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal))
                    {
                        throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumber.CreateFromUri(reader.BaseURI), "row", reader.Name));
                    }
                    break;
                }
            }

            Row row = table.CreateRow(sourceLineNumbers);

            row.Operation = operation;
            row.SectionId = sectionId;

            // loop through all the fields in a row
            if (!empty)
            {
                bool done  = false;
                int  field = 0;

                // loop through all the fields in a row
                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        switch (reader.LocalName)
                        {
                        case "field":
                            if (row.Fields.Length <= field)
                            {
                                if (!reader.IsEmptyElement)
                                {
                                    throw new WixException(WixErrors.UnexpectedColumnCount(SourceLineNumber.CreateFromUri(reader.BaseURI), table.Name));
                                }
                            }
                            else
                            {
                                row.fields[field].Parse(reader);
                            }
                            ++field;
                            break;

                        default:
                            throw new WixException(WixErrors.UnexpectedElement(SourceLineNumber.CreateFromUri(reader.BaseURI), "row", reader.Name));
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumber.CreateFromUri(reader.BaseURI), "row"));
                }
            }

            return(row);
        }
Beispiel #9
0
        /// <summary>
        /// Assign files to cabinets based on MediaTemplate authoring.
        /// </summary>
        /// <param name="fileRows">FileRowCollection</param>
        private void AutoAssignFiles(Table mediaTable, FileRowCollection fileRows)
        {
            const int MaxCabIndex = 999;

            ulong currentPreCabSize = 0;
            ulong maxPreCabSizeInBytes;
            int   maxPreCabSizeInMB = 0;
            int   currentCabIndex   = 0;

            MediaRow currentMediaRow = null;

            Table mediaTemplateTable = this.output.Tables["WixMediaTemplate"];

            // Auto assign files to cabinets based on maximum uncompressed media size
            mediaTable.Rows.Clear();
            WixMediaTemplateRow mediaTemplateRow = (WixMediaTemplateRow)mediaTemplateTable.Rows[0];

            if (!String.IsNullOrEmpty(mediaTemplateRow.CabinetTemplate))
            {
                this.cabinetNameTemplate = mediaTemplateRow.CabinetTemplate;
            }

            string mumsString = Environment.GetEnvironmentVariable("WIX_MUMS");

            try
            {
                // Override authored mums value if environment variable is authored.
                if (!String.IsNullOrEmpty(mumsString))
                {
                    maxPreCabSizeInMB = Int32.Parse(mumsString);
                }
                else
                {
                    maxPreCabSizeInMB = mediaTemplateRow.MaximumUncompressedMediaSize;
                }

                maxPreCabSizeInBytes = (ulong)maxPreCabSizeInMB * 1024 * 1024;
            }
            catch (FormatException)
            {
                throw new WixException(WixErrors.IllegalEnvironmentVariable("WIX_MUMS", mumsString));
            }
            catch (OverflowException)
            {
                throw new WixException(WixErrors.MaximumUncompressedMediaSizeTooLarge(null, maxPreCabSizeInMB));
            }

            foreach (FileRow fileRow in fileRows)
            {
                // When building a product, if the current file is not to be compressed or if
                // the package set not to be compressed, don't cab it.
                if (OutputType.Product == output.Type &&
                    (YesNoType.No == fileRow.Compressed ||
                     (YesNoType.NotSet == fileRow.Compressed && !this.filesCompressed)))
                {
                    uncompressedFileRows.Add(fileRow);
                    continue;
                }

                FileInfo fileInfo = null;

                // Get the file size
                try
                {
                    fileInfo = new FileInfo(fileRow.Source);
                }
                catch (ArgumentException)
                {
                    this.core.OnMessage(WixErrors.InvalidFileName(fileRow.SourceLineNumbers, fileRow.Source));
                }
                catch (PathTooLongException)
                {
                    this.core.OnMessage(WixErrors.InvalidFileName(fileRow.SourceLineNumbers, fileRow.Source));
                }
                catch (NotSupportedException)
                {
                    this.core.OnMessage(WixErrors.InvalidFileName(fileRow.SourceLineNumbers, fileRow.Source));
                }

                if (fileInfo.Exists)
                {
                    if (fileInfo.Length > Int32.MaxValue)
                    {
                        throw new WixException(WixErrors.FileTooLarge(fileRow.SourceLineNumbers, fileRow.Source));
                    }

                    fileRow.FileSize = Convert.ToInt32(fileInfo.Length, CultureInfo.InvariantCulture);
                }

                if (currentCabIndex == MaxCabIndex)
                {
                    // Associate current file with last cab (irrespective of the size) and cab index is not incremented anymore.
                    FileRowCollection cabinetFileRow = (FileRowCollection)this.cabinets[currentMediaRow];
                    fileRow.DiskId = currentCabIndex;
                    cabinetFileRow.Add(fileRow);
                    continue;
                }

                // Update current cab size.
                currentPreCabSize += (ulong)fileRow.FileSize;

                if (currentPreCabSize > maxPreCabSizeInBytes)
                {
                    // Overflow due to current file
                    currentMediaRow = this.AddMediaRow(mediaTable, ++currentCabIndex, mediaTemplateRow.CompressionLevel);

                    FileRowCollection cabinetFileRow = (FileRowCollection)this.cabinets[currentMediaRow];
                    fileRow.DiskId = currentCabIndex;
                    cabinetFileRow.Add(fileRow);
                    // Now files larger than MaxUncompressedMediaSize will be the only file in its cabinet so as to respect MaxUncompressedMediaSize
                    currentPreCabSize = (ulong)fileRow.FileSize;
                }
                else
                {
                    // File fits in the current cab.
                    if (currentMediaRow == null)
                    {
                        // Create new cab and MediaRow
                        currentMediaRow = this.AddMediaRow(mediaTable, ++currentCabIndex, mediaTemplateRow.CompressionLevel);
                    }

                    // Associate current file with current cab.
                    FileRowCollection cabinetFileRow = (FileRowCollection)this.cabinets[currentMediaRow];
                    fileRow.DiskId = currentCabIndex;
                    cabinetFileRow.Add(fileRow);
                }
            }

            // If there are uncompressed files and no MediaRow, create a default one.
            if (uncompressedFileRows.Count > 0 && mediaTable.Rows.Count == 0)
            {
                MediaRow defaultMediaRow = (MediaRow)mediaTable.CreateRow(null);
                defaultMediaRow.DiskId = 1;
                mediaRows.Add(defaultMediaRow);
            }
        }
        /// <summary>
        /// Main running method for the application.
        /// </summary>
        /// <param name="args">Commandline arguments to the application.</param>
        /// <returns>Returns the application error code.</returns>
        private int Run(string[] args)
        {
            try
            {
                // parse the command line
                this.ParseCommandLine(args);

                // exit if there was an error parsing the command line (otherwise the logo appears after error messages)
                if (Messaging.Instance.EncounteredError)
                {
                    return(Messaging.Instance.LastErrorNumber);
                }

                if (this.showLogo)
                {
                    AppCommon.DisplayToolHeader();
                }

                if (this.showHelp)
                {
                    Console.WriteLine(LuxStrings.HelpMessage);
                    AppCommon.DisplayToolFooter();
                    return(Messaging.Instance.LastErrorNumber);
                }

                foreach (string parameter in this.invalidArgs)
                {
                    Messaging.Instance.OnMessage(WixWarnings.UnsupportedCommandLineArgument(parameter));
                }

                this.invalidArgs = null;

                // gotta have something to do
                if (0 == this.inputFiles.Count || String.IsNullOrEmpty(this.outputFile))
                {
                    Console.WriteLine(LuxStrings.HelpMessage);
                    Messaging.Instance.OnMessage(LuxBuildErrors.MalfunctionNeedInput());
                    return(Messaging.Instance.LastErrorNumber);
                }

                if (String.IsNullOrEmpty(Path.GetExtension(this.outputFile)))
                {
                    this.outputFile = Path.ChangeExtension(this.outputFile, ".wxs");
                }

                // get extensions from lux.exe.config
                AppCommon.ReadConfiguration(this.extensionList);

                Generator.Generate(this.extensionList, this.inputFiles, this.outputFile);
            }
            catch (WixException we)
            {
                Messaging.Instance.OnMessage(we.Error);
            }
            catch (Exception e)
            {
                Messaging.Instance.OnMessage(WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace));
                if (e is NullReferenceException || e is SEHException)
                {
                    throw;
                }
            }

            return(Messaging.Instance.LastErrorNumber);
        }
Beispiel #11
0
        /// <summary>
        /// Replaces parameters in the source text.
        /// </summary>
        /// <param name="sourceLineNumbers">The source line information for the function.</param>
        /// <param name="value">Text that may contain parameters to replace.</param>
        /// <returns>Text after parameters have been replaced.</returns>
        public string PreprocessString(SourceLineNumberCollection sourceLineNumbers, string value)
        {
            StringBuilder sb = new StringBuilder();
            int           currentPosition = 0;
            int           end             = 0;

            while (-1 != (currentPosition = value.IndexOf('$', end)))
            {
                if (end < currentPosition)
                {
                    sb.Append(value, end, currentPosition - end);
                }

                end = currentPosition + 1;
                string remainder = value.Substring(end);
                if (remainder.StartsWith("$"))
                {
                    sb.Append("$");
                    end++;
                }
                else if (remainder.StartsWith("(loc."))
                {
                    currentPosition = remainder.IndexOf(')');
                    if (-1 == currentPosition)
                    {
                        throw new WixException(WixErrors.InvalidPreprocessorVariable(sourceLineNumbers, remainder));
                    }

                    sb.Append("$");   // just put the resource reference back as was
                    sb.Append(remainder, 0, currentPosition + 1);

                    end += currentPosition + 1;
                }
                else if (remainder.StartsWith("("))
                {
                    int  openParenCount    = 1;
                    int  closingParenCount = 0;
                    bool isFunction        = false;
                    bool foundClosingParen = false;

                    // find the closing paren
                    int closingParenPosition;
                    for (closingParenPosition = 1; closingParenPosition < remainder.Length; closingParenPosition++)
                    {
                        switch (remainder[closingParenPosition])
                        {
                        case '(':
                            openParenCount++;
                            isFunction = true;
                            break;

                        case ')':
                            closingParenCount++;
                            break;
                        }
                        if (openParenCount == closingParenCount)
                        {
                            foundClosingParen = true;
                            break;
                        }
                    }

                    // move the currentPosition to the closing paren
                    currentPosition += closingParenPosition;

                    if (!foundClosingParen)
                    {
                        if (isFunction)
                        {
                            throw new WixException(WixErrors.InvalidPreprocessorFunction(sourceLineNumbers, remainder));
                        }
                        else
                        {
                            throw new WixException(WixErrors.InvalidPreprocessorVariable(sourceLineNumbers, remainder));
                        }
                    }

                    string subString = remainder.Substring(1, closingParenPosition - 1);
                    string result    = null;
                    if (isFunction)
                    {
                        result = this.EvaluateFunction(sourceLineNumbers, subString);
                    }
                    else
                    {
                        result = this.GetVariableValue(sourceLineNumbers, subString, false);
                    }

                    if (null == result)
                    {
                        if (isFunction)
                        {
                            throw new WixException(WixErrors.UndefinedPreprocessorFunction(sourceLineNumbers, subString));
                        }
                        else
                        {
                            throw new WixException(WixErrors.UndefinedPreprocessorVariable(sourceLineNumbers, subString));
                        }
                    }
                    sb.Append(result);
                    end += closingParenPosition + 1;
                }
                else   // just a floating "$" so put it in the final string (i.e. leave it alone) and keep processing
                {
                    sb.Append('$');
                }
            }

            if (end < value.Length)
            {
                sb.Append(value.Substring(end));
            }

            return(sb.ToString());
        }
        /// <summary>
        /// Parse the commandline arguments.
        /// </summary>
        /// <param name="args">Commandline arguments.</param>
        private void ParseCommandLine(string[] args)
        {
            for (int i = 0; i < args.Length; ++i)
            {
                string arg = args[i];
                if (null == arg || 0 == arg.Length)
                {
                    // skip blank arguments
                    continue;
                }

                if (1 == arg.Length)
                {
                    // treat '-' and '@' as filenames when by themselves.
                    this.inputFiles.AddRange(CommandLine.GetFiles(arg, "Source"));
                    continue;
                }

                if ('-' == arg[0] || '/' == arg[0])
                {
                    string parameter = arg.Substring(1);
                    if ("ext" == parameter)
                    {
                        if (!CommandLine.IsValidArg(args, ++i))
                        {
                            Messaging.Instance.OnMessage(WixErrors.TypeSpecificationForExtensionRequired("-ext"));
                            return;
                        }

                        this.extensionList.Add(args[i]);
                    }
                    else if ("nologo" == parameter)
                    {
                        this.showLogo = false;
                    }
                    else if ("o" == parameter || "out" == parameter)
                    {
                        string path = CommandLine.GetFileOrDirectory(parameter, args, ++i);

                        if (String.IsNullOrEmpty(path))
                        {
                            return;
                        }
                        else
                        {
                            this.outputFile = path;
                        }
                    }
                    else if ("v" == parameter)
                    {
                        Messaging.Instance.ShowVerboseMessages = true;
                    }
                    else if ("?" == parameter || "help" == parameter)
                    {
                        this.showHelp = true;
                        return;
                    }
                    else
                    {
                        this.invalidArgs.Add(parameter);
                    }
                }
                else if ('@' == arg[0])
                {
                    this.ParseCommandLine(CommandLineResponseFile.Parse(arg.Substring(1)));
                }
                else
                {
                    this.inputFiles.AddRange(CommandLine.GetFiles(arg, "Source"));
                }
            }

            return;
        }
        /// <summary>
        /// Parses a Driver element.
        /// </summary>
        /// <param name="node">Element to parse.</param>
        /// <param name="componentId">Identifier for parent component.</param>
        private void ParseDriverElement(XmlNode node, string componentId)
        {
            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            int attributes = 0;
            int sequence   = CompilerCore.IntegerNotSet;

            // check the number of times a Driver element has been nested under this Component element
            if (null != componentId)
            {
                if (this.components.Contains(componentId))
                {
                    this.Core.OnMessage(WixErrors.TooManyElements(sourceLineNumbers, "Component", node.Name, 1));
                }
                else
                {
                    this.components.Add(componentId, null);
                }
            }

            foreach (XmlAttribute attrib in node.Attributes)
            {
                switch (attrib.LocalName)
                {
                case "AddRemovePrograms":
                    if (YesNoType.No == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                    {
                        attributes |= 0x4;
                    }
                    break;

                case "DeleteFiles":
                    if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                    {
                        attributes |= 0x10;
                    }
                    break;

                case "ForceInstall":
                    if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                    {
                        attributes |= 0x1;
                    }
                    break;

                case "Legacy":
                    if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                    {
                        attributes |= 0x8;
                    }
                    break;

                case "PlugAndPlayPrompt":
                    if (YesNoType.No == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
                    {
                        attributes |= 0x2;
                    }
                    break;

                case "Sequence":
                    sequence = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, int.MaxValue);
                    break;

                default:
                    this.Core.UnexpectedAttribute(sourceLineNumbers, attrib);
                    break;
                }
            }

            if (!this.Core.EncounteredError)
            {
                Row row = this.Core.CreateRow(sourceLineNumbers, "MsiDriverPackages");
                row[0] = componentId;
                row[1] = attributes;
                if (CompilerCore.IntegerNotSet != sequence)
                {
                    row[2] = sequence;
                }

                this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "MsiProcessDrivers");
            }
        }
Beispiel #14
0
        /// <summary>
        /// Parse a localization string.
        /// </summary>
        /// <param name="reader">XmlReader where the localization file is persisted.</param>
        /// <param name="tableDefinitions">Collection containing TableDefinitions to use when loading the localization file.</param>
        /// <param name="localization">The localization being parsed.</param>
        private static void ParseString(XmlReader reader, TableDefinitionCollection tableDefinitions, Localization localization)
        {
            Debug.Assert("String" == reader.LocalName);

            bool empty = reader.IsEmptyElement;
            SourceLineNumberCollection sourceLineNumbers = SourceLineNumberCollection.FromUri(reader.BaseURI);

            string id          = null;
            bool   overridable = false;
            string value       = String.Empty; // default this value to the empty string

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "Id":
                    id = reader.Value;
                    break;

                case "Overridable":
                    overridable = Common.IsYes(sourceLineNumbers, "String", reader.Name, reader.Value);
                    break;

                default:
                    if (!reader.NamespaceURI.StartsWith("http://www.w3.org/"))
                    {
                        throw new WixException(WixErrors.UnexpectedAttribute(sourceLineNumbers, "String", reader.Name));
                    }
                    break;
                }
            }

            if (!empty)
            {
                bool done = false;

                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        throw new WixException(WixErrors.UnexpectedElement(sourceLineNumbers, "String", reader.Name));

                    case XmlNodeType.CDATA:
                    case XmlNodeType.Text:
                        if (0 < reader.Value.Length)
                        {
                            value = reader.Value;
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixException(WixErrors.ExpectedEndElement(sourceLineNumbers, "String"));
                }
            }

            if (null == id)
            {
                throw new WixException(WixErrors.ExpectedAttribute(sourceLineNumbers, "String", "Id"));
            }

            WixVariableRow wixVariableRow = new WixVariableRow(sourceLineNumbers, tableDefinitions["WixVariable"]);

            wixVariableRow.Id          = id;
            wixVariableRow.Overridable = overridable;
            wixVariableRow.Value       = value;

            WixVariableRow existingWixVariableRow = (WixVariableRow)localization.variables[id];

            if (null == existingWixVariableRow || (existingWixVariableRow.Overridable && !overridable))
            {
                localization.variables.Add(id, wixVariableRow);
            }
            else if (!overridable)
            {
                throw new WixException(WixErrors.DuplicateLocalizationIdentifier(sourceLineNumbers, id));
            }
        }
 /// <summary>
 /// Instantiate a new WixInvalidIdtException.
 /// </summary>
 /// <param name="idtFile">The invalid idt file.</param>
 /// <param name="tableName">The table name of the invalid idt file.</param>
 public WixInvalidIdtException(string idtFile, string tableName) :
     base(WixErrors.InvalidIdt(new SourceLineNumber(idtFile), idtFile, tableName))
 {
 }
Beispiel #16
0
        /// <summary>
        /// Assign files to cabinets based on Media authoring.
        /// </summary>
        /// <param name="mediaTable"></param>
        /// <param name="mergeModuleMediaRow"></param>
        /// <param name="fileRows"></param>
        private void ManuallyAssignFiles(Table mediaTable, MediaRow mergeModuleMediaRow, FileRowCollection fileRows)
        {
            if (OutputType.Module != this.output.Type)
            {
                if (null != mediaTable)
                {
                    Dictionary <string, MediaRow> cabinetMediaRows = new Dictionary <string, MediaRow>(StringComparer.InvariantCultureIgnoreCase);
                    foreach (MediaRow mediaRow in mediaTable.Rows)
                    {
                        // If the Media row has a cabinet, make sure it is unique across all Media rows.
                        if (!String.IsNullOrEmpty(mediaRow.Cabinet))
                        {
                            MediaRow existingRow;
                            if (cabinetMediaRows.TryGetValue(mediaRow.Cabinet, out existingRow))
                            {
                                this.core.OnMessage(WixErrors.DuplicateCabinetName(mediaRow.SourceLineNumbers, mediaRow.Cabinet));
                                this.core.OnMessage(WixErrors.DuplicateCabinetName2(existingRow.SourceLineNumbers, existingRow.Cabinet));
                            }
                            else
                            {
                                cabinetMediaRows.Add(mediaRow.Cabinet, mediaRow);
                            }
                        }

                        this.mediaRows.Add(mediaRow);
                    }
                }

                foreach (MediaRow mediaRow in this.mediaRows)
                {
                    if (null != mediaRow.Cabinet)
                    {
                        this.cabinets.Add(mediaRow, new FileRowCollection());
                    }
                }
            }

            foreach (FileRow fileRow in fileRows)
            {
                if (OutputType.Module == output.Type)
                {
                    ((FileRowCollection)this.cabinets[mergeModuleMediaRow]).Add(fileRow);
                }
                else
                {
                    MediaRow mediaRow = this.mediaRows[fileRow.DiskId];

                    if (null == mediaRow)
                    {
                        this.core.OnMessage(WixErrors.MissingMedia(fileRow.SourceLineNumbers, fileRow.DiskId));
                        continue;
                    }

                    // When building a product, if the current file is not to be compressed or if
                    // the package set not to be compressed, don't cab it.
                    if (OutputType.Product == output.Type &&
                        (YesNoType.No == fileRow.Compressed ||
                         (YesNoType.NotSet == fileRow.Compressed && !this.filesCompressed)))
                    {
                        uncompressedFileRows.Add(fileRow);
                    }
                    else // file in a Module or marked compressed
                    {
                        FileRowCollection cabinetFileRow = (FileRowCollection)this.cabinets[mediaRow];

                        if (null != cabinetFileRow)
                        {
                            cabinetFileRow.Add(fileRow);
                        }
                        else
                        {
                            this.core.OnMessage(WixErrors.ExpectedMediaCabinet(fileRow.SourceLineNumbers, fileRow.File, fileRow.DiskId));
                        }
                    }
                }
            }
        }
Beispiel #17
0
        /// <summary>
        /// Parse a table from the xml.
        /// </summary>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="section">Section to populate with persisted data.</param>
        /// <param name="tableDefinitions">TableDefinitions to use in the intermediate.</param>
        /// <returns>The parsed table.</returns>
        internal static Table Parse(XmlReader reader, Section section, TableDefinitionCollection tableDefinitions)
        {
            Debug.Assert("table" == reader.LocalName);

            bool           empty     = reader.IsEmptyElement;
            TableOperation operation = TableOperation.None;
            string         name      = null;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "name":
                    name = reader.Value;
                    break;

                case "op":
                    switch (reader.Value)
                    {
                    case "add":
                        operation = TableOperation.Add;
                        break;

                    case "drop":
                        operation = TableOperation.Drop;
                        break;

                    default:
                        throw new WixException(WixErrors.IllegalAttributeValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "table", reader.Name, reader.Value, "Add", "Drop"));
                    }
                    break;

                default:
                    if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal))
                    {
                        throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "table", reader.Name));
                    }
                    break;
                }
            }

            if (null == name)
            {
                throw new WixException(WixErrors.ExpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "table", "name"));
            }

            TableDefinition tableDefinition = tableDefinitions[name];
            Table           table           = new Table(section, tableDefinition);

            table.Operation = operation;

            if (!empty)
            {
                bool done = false;

                // loop through all the rows in a table
                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        switch (reader.LocalName)
                        {
                        case "row":
                            Row.Parse(reader, table);
                            break;

                        default:
                            throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "table", reader.Name));
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "table"));
                }
            }

            return(table);
        }
Beispiel #18
0
        /// <summary>
        /// Parses ActionRows from the Xml reader.
        /// </summary>
        /// <param name="reader">Xml reader that contains serialized ActionRows.</param>
        /// <returns>The parsed ActionRows.</returns>
        internal static WixActionRow[] Parse(XmlReader reader)
        {
            Debug.Assert("action" == reader.LocalName);

            string id            = null;
            string condition     = null;
            bool   empty         = reader.IsEmptyElement;
            int    sequence      = int.MinValue;
            int    sequenceCount = 0;

            SequenceTable[] sequenceTables = new SequenceTable[Enum.GetValues(typeof(SequenceTable)).Length];

            while (reader.MoveToNextAttribute())
            {
                switch (reader.Name)
                {
                case "name":
                    id = reader.Value;
                    break;

                case "AdminExecuteSequence":
                    if (Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name, reader.Value))
                    {
                        sequenceTables[sequenceCount] = SequenceTable.AdminExecuteSequence;
                        ++sequenceCount;
                    }
                    break;

                case "AdminUISequence":
                    if (Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name, reader.Value))
                    {
                        sequenceTables[sequenceCount] = SequenceTable.AdminUISequence;
                        ++sequenceCount;
                    }
                    break;

                case "AdvtExecuteSequence":
                    if (Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name, reader.Value))
                    {
                        sequenceTables[sequenceCount] = SequenceTable.AdvtExecuteSequence;
                        ++sequenceCount;
                    }
                    break;

                case "condition":
                    condition = reader.Value;
                    break;

                case "InstallExecuteSequence":
                    if (Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name, reader.Value))
                    {
                        sequenceTables[sequenceCount] = SequenceTable.InstallExecuteSequence;
                        ++sequenceCount;
                    }
                    break;

                case "InstallUISequence":
                    if (Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name, reader.Value))
                    {
                        sequenceTables[sequenceCount] = SequenceTable.InstallUISequence;
                        ++sequenceCount;
                    }
                    break;

                case "sequence":
                    sequence = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture);
                    break;

                default:
                    if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal))
                    {
                        throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name));
                    }
                    break;
                }
            }

            if (null == id)
            {
                throw new WixException(WixErrors.ExpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", "name"));
            }

            if (int.MinValue == sequence)
            {
                throw new WixException(WixErrors.ExpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", "sequence"));
            }
            else if (1 > sequence)
            {
                throw new WixException(WixErrors.IntegralValueOutOfRange(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", "sequence", sequence, 1, int.MaxValue));
            }

            if (0 == sequenceCount)
            {
                throw new WixException(WixErrors.ExpectedAttributes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", "AdminExecuteSequence", "AdminUISequence", "AdvtExecuteSequence", "InstallExecuteSequence", "InstallUISequence"));
            }

            if (!empty && reader.Read() && XmlNodeType.EndElement != reader.MoveToContent())
            {
                throw new WixException(WixErrors.UnexpectedContentNode(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.NodeType.ToString()));
            }

            // create the actions
            WixActionRow[] actionRows = new WixActionRow[sequenceCount];
            for (int i = 0; i < sequenceCount; i++)
            {
                WixActionRow actionRow = new WixActionRow(sequenceTables[i], id, condition, sequence);
                actionRows[i] = actionRow;
            }

            return(actionRows);
        }
Beispiel #19
0
        /// <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 "None" if building an MSI package.</param>
        /// <param name="keyPath">Explicit key path.</param>
        /// <param name="parentId">The identifier of the parent component or package.</param>
        /// <returns>The type of key path if set.</returns>
        private ComponentKeyPath ParseProvidesElement(XElement node, PackageType packageType, string parentId)
        {
            SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            ComponentKeyPath keyPath           = null;
            Identifier       id          = null;
            string           key         = null;
            string           version     = null;
            string           displayName = null;
            int attributes  = 0;
            int illegalChar = -1;

            foreach (XAttribute attrib in node.Attributes())
            {
                if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == 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))
            {
                // Make sure the key does not contain any illegal characters or values.
                if (0 <= (illegalChar = key.IndexOfAny(DependencyCommon.InvalidCharacters)))
                {
                    StringBuilder sb = new StringBuilder(DependencyCommon.InvalidCharacters.Length * 2);
                    Array.ForEach <char>(DependencyCommon.InvalidCharacters, c => sb.Append(c).Append(" "));

                    this.Core.OnMessage(DependencyErrors.IllegalCharactersInProvider(sourceLineNumbers, "Key", key[illegalChar], sb.ToString()));
                }
                else if ("ALL" == key)
                {
                    this.Core.OnMessage(DependencyErrors.ReservedValue(sourceLineNumbers, node.Name.LocalName, "Key", key));
                }
            }
            else if (PackageType.ExePackage == packageType || PackageType.MsuPackage == packageType)
            {
                // Must specify the provider key when authored for a package.
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key"));
            }
            else if (PackageType.None == packageType)
            {
                // Make sure the ProductCode is authored and set the key.
                this.Core.CreateSimpleReference(sourceLineNumbers, "Property", "ProductCode");
                key = "!(bind.property.ProductCode)";
            }

            // The Version attribute should not be authored in or for an MSI package.
            if (!String.IsNullOrEmpty(version))
            {
                switch (packageType)
                {
                case PackageType.None:
                    this.Core.OnMessage(DependencyWarnings.DiscouragedVersionAttribute(sourceLineNumbers));
                    break;

                case PackageType.MsiPackage:
                    this.Core.OnMessage(DependencyWarnings.DiscouragedVersionAttribute(sourceLineNumbers, parentId));
                    break;
                }
            }
            else if (PackageType.MspPackage == packageType || PackageType.MsuPackage == packageType)
            {
                // Must specify the Version when authored for packages that do not contain a version.
                this.Core.OnMessage(WixErrors.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 (XElement child in node.Elements())
            {
                if (this.Namespace == child.Name.Namespace)
                {
                    switch (child.Name.LocalName)
                    {
                    case "Requires":
                        this.ParseRequiresElement(child, id.Id, PackageType.None == packageType);
                        break;

                    case "RequiresRef":
                        this.ParseRequiresRefElement(child, id.Id, PackageType.None == packageType);
                        break;

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

            if (!this.Core.EncounteredError)
            {
                // Create the row in the provider table.
                Row row = this.Core.CreateRow(sourceLineNumbers, "WixDependencyProvider", id);
                row[1] = parentId;
                row[2] = key;

                if (!String.IsNullOrEmpty(version))
                {
                    row[3] = version;
                }

                if (!String.IsNullOrEmpty(displayName))
                {
                    row[4] = displayName;
                }

                if (0 != attributes)
                {
                    row[5] = attributes;
                }

                if (PackageType.None == packageType)
                {
                    // Reference the Check custom action to check for dependencies on the current provider.
                    if (Platform.ARM == this.Core.CurrentPlatform)
                    {
                        // Ensure the ARM version of the CA is referenced.
                        this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "WixDependencyCheck_ARM");
                    }
                    else
                    {
                        // All other supported platforms use x86.
                        this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "WixDependencyCheck");
                    }

                    // Generate registry rows for the provider using binder properties.
                    string keyProvides = String.Concat(DependencyCommon.RegistryRoot, key);

                    row    = this.Core.CreateRow(sourceLineNumbers, "Registry", this.Core.CreateIdentifier("reg", id.Id, "(Default)"));
                    row[1] = -1;
                    row[2] = keyProvides;
                    row[3] = null;
                    row[4] = "[ProductCode]";
                    row[5] = parentId;

                    // Use the Version registry value and use that as a potential key path.
                    Identifier idVersion = this.Core.CreateIdentifier("reg", id.Id, "Version");
                    keyPath = new ComponentKeyPath()
                    {
                        Id = idVersion.Id, Explicit = false, Type = ComponentKeyPathType.Registry
                    };

                    row    = this.Core.CreateRow(sourceLineNumbers, "Registry", idVersion);
                    row[1] = -1;
                    row[2] = keyProvides;
                    row[3] = "Version";
                    row[4] = !String.IsNullOrEmpty(version) ? version : "[ProductVersion]";
                    row[5] = parentId;

                    row    = this.Core.CreateRow(sourceLineNumbers, "Registry", this.Core.CreateIdentifier("reg", id.Id, "DisplayName"));
                    row[1] = -1;
                    row[2] = keyProvides;
                    row[3] = "DisplayName";
                    row[4] = !String.IsNullOrEmpty(displayName) ? displayName : "[ProductName]";
                    row[5] = parentId;

                    if (0 != attributes)
                    {
                        row    = this.Core.CreateRow(sourceLineNumbers, "Registry", this.Core.CreateIdentifier("reg", id.Id, "Attributes"));
                        row[1] = -1;
                        row[2] = keyProvides;
                        row[3] = "Attributes";
                        row[4] = String.Concat("#", attributes.ToString(CultureInfo.InvariantCulture.NumberFormat));
                        row[5] = parentId;
                    }
                }
            }

            return(keyPath);
        }
        /// <summary>
        /// Parse a field from the xml.
        /// </summary>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        internal override void Parse(XmlReader reader)
        {
            Debug.Assert("field" == reader.LocalName);

            bool empty = reader.IsEmptyElement;

            this.baseUri = reader.BaseURI;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "cabinetFileId":
                    this.cabinetFileId = reader.Value;
                    break;

                case "modified":
                    this.Modified = Common.IsYes(SourceLineNumber.CreateFromUri(reader.BaseURI), "field", reader.Name, reader.Value);
                    break;

                case "previousData":
                    this.PreviousData = reader.Value;
                    break;

                case "unresolvedPreviousData":
                    this.unresolvedPreviousData = reader.Value;
                    break;

                case "unresolvedData":
                    this.unresolvedData = reader.Value;
                    break;

                case "previousCabinetFileId":
                    this.previousCabinetFileId = reader.Value;
                    break;

                default:
                    if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal))
                    {
                        throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumber.CreateFromUri(reader.BaseURI), "field", reader.Name));
                    }
                    break;
                }
            }

            if (!empty)
            {
                bool done = false;

                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        throw new WixException(WixErrors.UnexpectedElement(SourceLineNumber.CreateFromUri(reader.BaseURI), "field", reader.Name));

                    case XmlNodeType.CDATA:
                    case XmlNodeType.Text:
                        if (0 < reader.Value.Length)
                        {
                            this.Data = reader.Value;
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumber.CreateFromUri(reader.BaseURI), "field"));
                }
            }
        }
Beispiel #21
0
 /// <summary>
 /// Indicates the decompiler encountered and unexpected table to decompile.
 /// </summary>
 /// <param name="table">Unknown decompiled table.</param>
 public void UnexpectedTable(Table table)
 {
     this.OnMessage(WixErrors.TableDecompilationUnimplemented(table.Name));
 }
Beispiel #22
0
        /// <summary>
        /// Parses a UrlAce element.
        /// </summary>
        /// <param name="node">The element to parse.</param>
        /// <param name="urlReservationId">The URL reservation ID.</param>
        /// <param name="defaultSecurityPrincipal">The default security principal.</param>
        private void ParseUrlAceElement(XmlNode node, string urlReservationId, string defaultSecurityPrincipal)
        {
            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string id = null;
            string securityPrincipal = defaultSecurityPrincipal;
            int    rights            = HttpConstants.GENERIC_ALL;
            string rightsValue       = null;

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (String.IsNullOrEmpty(attrib.NamespaceURI) || this.schema.TargetNamespace == attrib.NamespaceURI)
                {
                    switch (attrib.LocalName)
                    {
                    case "Id":
                        id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        break;

                    case "SecurityPrincipal":
                        securityPrincipal = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        break;

                    case "Rights":
                        rightsValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        switch (rightsValue)
                        {
                        case "all":
                            rights = HttpConstants.GENERIC_ALL;
                            break;

                        case "delegate":
                            rights = HttpConstants.GENERIC_WRITE;
                            break;

                        case "register":
                            rights = HttpConstants.GENERIC_EXECUTE;
                            break;

                        default:
                            this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.LocalName, "Rights", rightsValue, "all", "delegate", "register"));
                            break;
                        }
                        break;

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

            // Generate Id now if not authored.
            if (null == id)
            {
                id = this.Core.GenerateIdentifier("ace", urlReservationId, securityPrincipal, rightsValue);
            }

            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (this.Schema.TargetNamespace == child.NamespaceURI)
                    {
                        this.Core.UnexpectedElement(node, child);
                    }
                    else
                    {
                        this.Core.ParseExtensionElement(sourceLineNumbers, (XmlElement)node, (XmlElement)child);
                    }
                }
            }

            // SecurityPrincipal is required.
            if (null == securityPrincipal)
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.LocalName, "SecurityPrincipal"));
            }

            if (!this.Core.EncounteredError)
            {
                Row row = this.Core.CreateRow(sourceLineNumbers, "WixHttpUrlAce");
                row[0] = id;
                row[1] = urlReservationId;
                row[2] = securityPrincipal;
                row[3] = rights;
            }
        }
Beispiel #23
0
        /// <summary>
        /// Run a Light unit test.
        /// </summary>
        /// <param name="element">The unit test element.</param>
        /// <param name="previousUnitResults">The previous unit test results.</param>
        /// <param name="update">Indicates whether to give the user the option to fix a failing test.</param>
        /// <param name="args">The command arguments passed to WixUnit.</param>
        public static void RunUnitTest(XmlElement element, UnitResults previousUnitResults, bool update, ICommandArgs args)
        {
            string arguments              = element.GetAttribute("Arguments");
            string expectedErrors         = element.GetAttribute("ExpectedErrors");
            string expectedResult         = element.GetAttribute("ExpectedResult");
            string expectedWarnings       = element.GetAttribute("ExpectedWarnings");
            string extensions             = element.GetAttribute("Extensions");
            string outputFile             = element.GetAttribute("OutputFile");
            string intermediateOutputType = element.GetAttribute("IntermediateOutputType");
            string suppressExtensions     = element.GetAttribute("SuppressExtensions");
            string tempDirectory          = element.GetAttribute("TempDirectory");
            string testName          = element.ParentNode.Attributes["Name"].Value;
            string toolsDirectory    = element.GetAttribute("ToolsDirectory");
            bool   usePreviousOutput = ("true" == element.GetAttribute("UsePreviousOutput"));

            if (expectedErrors.Length == 0 && expectedResult.Length == 0 && intermediateOutputType.Length == 0 && outputFile.Length == 0)
            {
                throw new WixException(WixErrors.ExpectedAttributes(null, element.Name, "ExpectedErrors", "ExpectedResult", "IntermediateOutputType", "OutputFile", null));
            }

            if (expectedErrors.Length > 0 && (expectedResult.Length > 0 || intermediateOutputType.Length > 0 || outputFile.Length > 0))
            {
                throw new WixException(WixErrors.IllegalAttributeWithOtherAttributes(null, element.Name, "ExpectedErrors", "ExpectedResult", "IntermediateOutputType", "OutputFile", null));
            }
            else if (expectedResult.Length > 0 && (intermediateOutputType.Length > 0 || outputFile.Length > 0))
            {
                throw new WixException(WixErrors.IllegalAttributeWithOtherAttributes(null, element.Name, "ExpectedResult", "IntermediateOutputType", "OutputFile"));
            }
            else if (intermediateOutputType.Length > 0 && outputFile.Length > 0)
            {
                throw new WixException(WixErrors.IllegalAttributeWithOtherAttributes(null, element.Name, "IntermediateOutputType", "OutputFile", null));
            }

            string        toolFile    = Path.Combine(toolsDirectory, "light.exe");
            StringBuilder commandLine = new StringBuilder(arguments);

            commandLine.Append(" -b \"%WIX%\\examples\\data\"");

            // handle wixunit arguments
            if (args.NoTidy)
            {
                commandLine.Append(" -notidy");
            }

            // handle extensions
            if (!String.IsNullOrEmpty(extensions))
            {
                string[] suppressedExtensionArray = suppressExtensions.Split(';');
                foreach (string extension in extensions.Split(';'))
                {
                    if (0 > Array.BinarySearch(suppressedExtensionArray, extension))
                    {
                        commandLine.AppendFormat(" -ext \"{0}\"", extension);
                    }
                }
            }

            // handle any previous outputs
            if (usePreviousOutput)
            {
                foreach (string inputFile in previousUnitResults.OutputFiles)
                {
                    commandLine.AppendFormat(" \"{0}\"", inputFile);
                }
            }
            previousUnitResults.OutputFiles.Clear();

            // handle child elements
            foreach (XmlNode node in element.ChildNodes)
            {
                if (node.NodeType == XmlNodeType.Element)
                {
                    switch (node.LocalName)
                    {
                    case "LibraryFile":
                        string libraryFile = node.InnerText.Trim();

                        commandLine.AppendFormat(" \"{0}\"", libraryFile);
                        break;

                    case "LocalizationFile":
                        string localizationFile = node.InnerText.Trim();

                        commandLine.AppendFormat(" -loc \"{0}\"", localizationFile);
                        break;
                    }
                }
            }

            if (outputFile.Length > 0)
            {
                // outputFile has been explicitly set
            }
            else if (expectedResult.Length > 0)
            {
                outputFile = Path.Combine(tempDirectory, Path.GetFileName(expectedResult));
            }
            else if (intermediateOutputType.Length > 0)
            {
                string intermediateFile = String.Concat("intermediate.", intermediateOutputType);

                outputFile = Path.Combine(tempDirectory, intermediateFile);
            }
            else
            {
                outputFile = Path.Combine(tempDirectory, "ShouldNotBeCreated.msi");
            }
            commandLine.AppendFormat("{0} -out \"{1}\"", (Path.GetExtension(outputFile) == ".wixout" ? " -xo" : String.Empty), outputFile);
            previousUnitResults.OutputFiles.Add(outputFile);

            // run the tool
            ArrayList output = ToolUtility.RunTool(toolFile, commandLine.ToString());

            previousUnitResults.Errors.AddRange(ToolUtility.GetErrors(output, expectedErrors, expectedWarnings));
            previousUnitResults.Output.AddRange(output);

            // check the output file
            if (previousUnitResults.Errors.Count == 0)
            {
                if (expectedResult.Length > 0)
                {
                    ArrayList differences = CompareUnit.CompareResults(expectedResult, outputFile, testName, update);

                    previousUnitResults.Errors.AddRange(differences);
                    previousUnitResults.Output.AddRange(differences);
                }
                else if (expectedErrors.Length > 0 && File.Exists(outputFile)) // ensure the output doesn't exist
                {
                    string error = String.Format(CultureInfo.InvariantCulture, "Expected failure, but the unit test created output file \"{0}\".", outputFile);

                    previousUnitResults.Errors.Add(error);
                    previousUnitResults.Output.Add(error);
                }
            }
        }
Beispiel #24
0
        /// <summary>
        /// Parses a UrlReservation element.
        /// </summary>
        /// <param name="node">The element to parse.</param>
        /// <param name="componentId">Identifier of the component that owns this URL reservation.</param>
        /// <param name="securityPrincipal">The security principal of the parent element (null if nested under Component).</param>
        private void ParseUrlReservationElement(XmlNode node, string componentId, string securityPrincipal)
        {
            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string id                  = null;
            int    handleExisting      = HttpConstants.heReplace;
            string handleExistingValue = null;
            string sddl                = null;
            string url                 = null;
            bool   foundACE            = false;

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (String.IsNullOrEmpty(attrib.NamespaceURI) || this.schema.TargetNamespace == attrib.NamespaceURI)
                {
                    switch (attrib.LocalName)
                    {
                    case "Id":
                        id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        break;

                    case "HandleExisting":
                        handleExistingValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        switch (handleExistingValue)
                        {
                        case "replace":
                            handleExisting = HttpConstants.heReplace;
                            break;

                        case "ignore":
                            handleExisting = HttpConstants.heIgnore;
                            break;

                        case "fail":
                            handleExisting = HttpConstants.heFail;
                            break;

                        default:
                            this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.LocalName, "HandleExisting", handleExistingValue, "replace", "ignore", "fail"));
                            break;
                        }
                        break;

                    case "Sddl":
                        sddl = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        break;

                    case "Url":
                        url = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        break;

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

            // Need the element ID for child element processing, so generate now if not authored.
            if (null == id)
            {
                id = this.Core.GenerateIdentifier("url", componentId, securityPrincipal, url);
            }

            // Parse UrlAce children.
            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (this.Schema.TargetNamespace == child.NamespaceURI)
                    {
                        switch (child.LocalName)
                        {
                        case "UrlAce":
                            if (null != sddl)
                            {
                                this.Core.OnMessage(WixErrors.IllegalParentAttributeWhenNested(sourceLineNumbers, "UrlReservation", "Sddl", "UrlAce"));
                            }
                            else
                            {
                                foundACE = true;
                                this.ParseUrlAceElement(child, id, securityPrincipal);
                            }
                            break;

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

            // Url is required.
            if (null == url)
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.LocalName, "Url"));
            }

            // Security is required.
            if (null == sddl && !foundACE)
            {
                this.Core.OnMessage(HttpErrors.NoSecuritySpecified(sourceLineNumbers));
            }

            if (!this.Core.EncounteredError)
            {
                Row row = this.Core.CreateRow(sourceLineNumbers, "WixHttpUrlReservation");
                row[0] = id;
                row[1] = handleExisting;
                row[2] = sddl;
                row[3] = url;
                row[4] = componentId;

                if (this.Core.CurrentPlatform == Platform.ARM)
                {
                    // Ensure ARM version of the CA is referenced.
                    this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "WixSchedHttpUrlReservationsInstall_ARM");
                    this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "WixSchedHttpUrlReservationsUninstall_ARM");
                }
                else
                {
                    // All other supported platforms use x86.
                    this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "WixSchedHttpUrlReservationsInstall");
                    this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "WixSchedHttpUrlReservationsUninstall");
                }
            }
        }
        /// <summary>
        /// Parses a HelpFilter element.
        /// </summary>
        /// <param name="node">Element to process.</param>
        private void ParseHelpFilterElement(XElement node)
        {
            SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string           id = null;
            string           filterDefinition = null;
            string           name             = null;
            YesNoType        suppressCAs      = YesNoType.No;

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

                    case "FilterDefinition":
                        filterDefinition = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        break;

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

                    case "SuppressCustomActions":
                        suppressCAs = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                        break;

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

            if (null == id)
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
            }

            if (null == name)
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
            }

            this.Core.ParseForExtensionElements(node);

            if (!this.Core.EncounteredError)
            {
                Row row = this.Core.CreateRow(sourceLineNumbers, "HelpFilter");
                row[0] = id;
                row[1] = name;
                row[2] = filterDefinition;

                if (YesNoType.No == suppressCAs)
                {
                    this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "CA_RegisterMicrosoftHelp.3643236F_FC70_11D3_A536_0090278A1BB8");
                }
            }
        }
Beispiel #26
0
        /// <summary>
        /// Run a Wixproj unit test.
        /// </summary>
        /// <param name="element">The unit test element.</param>
        /// <param name="previousUnitResults">The previous unit test results.</param>
        /// <param name="verbose">The level of verbosity for the MSBuild logging.</param>
        /// <param name="skipValidation">Tells light to skip validation.</param>
        /// <param name="update">Indicates whether to give the user the option to fix a failing test.</param>
        /// <param name="args">The command arguments passed to WixUnit.</param>
        public static void RunUnitTest(XmlElement element, UnitResults previousUnitResults, bool verbose, bool skipValidation, bool update, ICommandArgs args)
        {
            string arguments                = element.GetAttribute("Arguments");
            string expectedErrors           = element.GetAttribute("ExpectedErrors");
            string expectedResult           = element.GetAttribute("ExpectedResult");
            string expectedWarnings         = element.GetAttribute("ExpectedWarnings");
            string extensions               = element.GetAttribute("Extensions");
            bool   noOutputName             = XmlConvert.ToBoolean(element.GetAttribute("NoOutputName"));
            bool   noOutputPath             = XmlConvert.ToBoolean(element.GetAttribute("NoOutputPath"));
            bool   defineSolutionProperties = XmlConvert.ToBoolean(element.GetAttribute("DefineSolutionProperties"));
            string suppressExtensions       = element.GetAttribute("SuppressExtensions");
            string tempDirectory            = element.GetAttribute("TempDirectory");
            string testName            = element.ParentNode.Attributes["Name"].Value;
            string toolsDirectory      = element.GetAttribute("ToolsDirectory");
            string msBuildDirectory    = Environment.GetEnvironmentVariable("WixTestMSBuildDirectory");
            string msBuildToolsVersion = Environment.GetEnvironmentVariable("WixTestMSBuildToolsVersion");

            // check the combinations of attributes
            if (expectedErrors.Length > 0 && expectedResult.Length > 0)
            {
                throw new WixException(WixErrors.IllegalAttributeWithOtherAttribute(null, element.Name, "ExpectedErrors", "ExpectedResult"));
            }

            // we'll run MSBuild on the .wixproj to generate the output
            if (null == msBuildDirectory)
            {
                msBuildDirectory = Path.Combine(Environment.GetEnvironmentVariable("SystemRoot"), @"Microsoft.NET\Framework\v3.5");
            }

            string        toolFile    = Path.Combine(msBuildDirectory, "MSBuild.exe");
            StringBuilder commandLine = new StringBuilder(arguments);

            // rebuild by default
            commandLine.AppendFormat(" /target:Rebuild /verbosity:{0}", verbose ? "detailed" : "normal");

            if (skipValidation)
            {
                commandLine.Append(" /property:SuppressValidation=true");
            }

            // add DefineSolutionProperties
            commandLine.AppendFormat(" /property:DefineSolutionProperties={0}", defineSolutionProperties);

            // make sure the tools directory ends in a single backslash
            if (toolsDirectory[toolsDirectory.Length - 1] != Path.DirectorySeparatorChar)
            {
                toolsDirectory = String.Concat(toolsDirectory, Path.DirectorySeparatorChar);
            }

            // handle the wix-specific directories and files
            commandLine.AppendFormat(" /property:WixToolPath=\"{0}\\\"", toolsDirectory);
            commandLine.AppendFormat(" /property:WixExtDir=\"{0}\\\"", toolsDirectory);
            commandLine.AppendFormat(" /property:WixTargetsPath=\"{0}\"", Path.Combine(toolsDirectory, "wix.targets"));
            commandLine.AppendFormat(" /property:WixTasksPath=\"{0}\"", Path.Combine(toolsDirectory, "WixTasks.dll"));
            commandLine.AppendFormat(" /property:BaseIntermediateOutputPath=\"{0}\\\\\"", Path.Combine(tempDirectory, "obj"));

            // handle extensions
            string[]      suppressedExtensionArray = suppressExtensions.Split(';');
            StringBuilder extensionsToUse          = new StringBuilder();

            foreach (string extension in extensions.Split(';'))
            {
                if (0 > Array.BinarySearch(suppressedExtensionArray, extension))
                {
                    if (extensionsToUse.Length > 0)
                    {
                        extensionsToUse.Append(";");
                    }
                    extensionsToUse.Append(extension);
                }
            }
            commandLine.AppendFormat(" /property:WixExtension=\"{0}\"", extensionsToUse.ToString());

            previousUnitResults.OutputFiles.Clear();

            // handle the source file
            string sourceFile = element.GetAttribute("SourceFile").Trim();

            // handle the expected result output file
            string outputFile;

            if (expectedResult.Length > 0)
            {
                outputFile = Path.Combine(tempDirectory, Path.GetFileName(expectedResult));
            }
            else
            {
                outputFile = Path.Combine(tempDirectory, "ShouldNotBeCreated.msi");
            }

            if (!noOutputName)
            {
                commandLine.AppendFormat(" /property:OutputName=\"{0}\"", Path.GetFileNameWithoutExtension(outputFile));
            }

            if (!noOutputPath)
            {
                commandLine.AppendFormat(" /property:OutputPath=\"{0}\\\\\"", Path.GetDirectoryName(outputFile));
            }
            previousUnitResults.OutputFiles.Add(outputFile);

            if (!String.IsNullOrEmpty(msBuildToolsVersion))
            {
                commandLine.AppendFormat(" /tv:{0}", msBuildToolsVersion);
            }

            // add the source file as the last parameter
            commandLine.AppendFormat(" \"{0}\"", sourceFile);

            // run one msbuild process at a time due to multiproc issues
            ArrayList output = null;

            try
            {
                mutex.WaitOne();
                output = ToolUtility.RunTool(toolFile, commandLine.ToString());
            }
            finally
            {
                mutex.ReleaseMutex();
            }

            previousUnitResults.Errors.AddRange(ToolUtility.GetErrors(output, expectedErrors, expectedWarnings));
            previousUnitResults.Output.AddRange(output);

            // check the output file
            if (previousUnitResults.Errors.Count == 0)
            {
                if (expectedResult.Length > 0)
                {
                    ArrayList differences = CompareUnit.CompareResults(expectedResult, outputFile, testName, update);

                    previousUnitResults.Errors.AddRange(differences);
                    previousUnitResults.Output.AddRange(differences);
                }
                else if (expectedErrors.Length > 0 && File.Exists(outputFile)) // ensure the output doesn't exist
                {
                    string error = String.Format(CultureInfo.InvariantCulture, "Expected failure, but the unit test created output file \"{0}\".", outputFile);

                    previousUnitResults.Errors.Add(error);
                    previousUnitResults.Output.Add(error);
                }
            }
        }
        /// <summary>
        /// Parses a VsixPackage element.
        /// </summary>
        /// <param name="node">Element to process.</param>
        /// <param name="componentId">Identifier of the parent Component element.</param>
        /// <param name="fileId">Identifier of the parent File element.</param>
        private void ParseVsixPackageElement(XElement node, string componentId, string fileId)
        {
            SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string           propertyId        = "VS_VSIX_INSTALLER_PATH";
            string           packageId         = null;
            YesNoType        permanent         = YesNoType.NotSet;
            string           target            = null;
            string           targetVersion     = null;
            YesNoType        vital             = YesNoType.NotSet;

            foreach (XAttribute attrib in node.Attributes())
            {
                if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
                {
                    switch (attrib.Name.LocalName)
                    {
                    case "File":
                        if (String.IsNullOrEmpty(fileId))
                        {
                            fileId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        }
                        else
                        {
                            this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "File", "File"));
                        }
                        break;

                    case "PackageId":
                        packageId = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        break;

                    case "Permanent":
                        permanent = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                        break;

                    case "Target":
                        target = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
                        switch (target.ToLowerInvariant())
                        {
                        case "integrated":
                        case "integratedshell":
                            target = "IntegratedShell";
                            break;

                        case "professional":
                            target = "Pro";
                            break;

                        case "premium":
                            target = "Premium";
                            break;

                        case "ultimate":
                            target = "Ultimate";
                            break;

                        case "vbexpress":
                            target = "VBExpress";
                            break;

                        case "vcexpress":
                            target = "VCExpress";
                            break;

                        case "vcsexpress":
                            target = "VCSExpress";
                            break;

                        case "vwdexpress":
                            target = "VWDExpress";
                            break;
                        }
                        break;

                    case "TargetVersion":
                        targetVersion = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
                        break;

                    case "Vital":
                        vital = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                        break;

                    case "VsixInstallerPathProperty":
                        propertyId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        break;

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

            if (String.IsNullOrEmpty(fileId))
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "File"));
            }

            if (String.IsNullOrEmpty(packageId))
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "PackageId"));
            }

            if (!String.IsNullOrEmpty(target) && String.IsNullOrEmpty(targetVersion))
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "TargetVersion", "Target"));
            }
            else if (String.IsNullOrEmpty(target) && !String.IsNullOrEmpty(targetVersion))
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Target", "TargetVersion"));
            }

            this.Core.ParseForExtensionElements(node);

            if (!this.Core.EncounteredError)
            {
                // Ensure there is a reference to the AppSearch Property that will find the VsixInstaller.exe.
                this.Core.CreateSimpleReference(sourceLineNumbers, "Property", propertyId);

                // Ensure there is a reference to the package file (even if we are a child under it).
                this.Core.CreateSimpleReference(sourceLineNumbers, "File", fileId);

                string cmdlinePrefix = "/q ";

                if (!String.IsNullOrEmpty(target))
                {
                    cmdlinePrefix = String.Format("{0} /skuName:{1} /skuVersion:{2}", cmdlinePrefix, target, targetVersion);
                }

                string installAfter     = "WriteRegistryValues"; // by default, come after the registry key registration.
                int    installExtraBits = VSCompiler.MsidbCustomActionTypeInScript;

                // If the package is not vital, mark the install action as continue.
                if (vital == YesNoType.No)
                {
                    installExtraBits |= VSCompiler.MsidbCustomActionTypeContinue;
                }
                else // the package is vital so ensure there is a rollback action scheduled.
                {
                    Identifier rollbackNamePerUser         = this.Core.CreateIdentifier("vru", componentId, fileId, "per-user", target ?? String.Empty, targetVersion ?? String.Empty);
                    Identifier rollbackNamePerMachine      = this.Core.CreateIdentifier("vrm", componentId, fileId, "per-machine", target ?? String.Empty, targetVersion ?? String.Empty);
                    string     rollbackCmdLinePerUser      = String.Concat(cmdlinePrefix, " /u:\"", packageId, "\"");
                    string     rollbackCmdLinePerMachine   = String.Concat(rollbackCmdLinePerUser, " /admin");
                    int        rollbackExtraBitsPerUser    = VSCompiler.MsidbCustomActionTypeContinue | VSCompiler.MsidbCustomActionTypeRollback | VSCompiler.MsidbCustomActionTypeInScript;
                    int        rollbackExtraBitsPerMachine = rollbackExtraBitsPerUser | VSCompiler.MsidbCustomActionTypeNoImpersonate;
                    string     rollbackConditionPerUser    = String.Format("NOT ALLUSERS AND NOT Installed AND ${0}=2 AND ?{0}>2", componentId); // NOT Installed && Component being installed but not installed already.
                    string     rollbackConditionPerMachine = String.Format("ALLUSERS AND NOT Installed AND ${0}=2 AND ?{0}>2", componentId);     // NOT Installed && Component being installed but not installed already.

                    this.SchedulePropertyExeAction(sourceLineNumbers, rollbackNamePerUser, propertyId, rollbackCmdLinePerUser, rollbackExtraBitsPerUser, rollbackConditionPerUser, null, installAfter);
                    this.SchedulePropertyExeAction(sourceLineNumbers, rollbackNamePerMachine, propertyId, rollbackCmdLinePerMachine, rollbackExtraBitsPerMachine, rollbackConditionPerMachine, null, rollbackNamePerUser.Id);

                    installAfter = rollbackNamePerMachine.Id;
                }

                Identifier installNamePerUser         = this.Core.CreateIdentifier("viu", componentId, fileId, "per-user", target ?? String.Empty, targetVersion ?? String.Empty);
                Identifier installNamePerMachine      = this.Core.CreateIdentifier("vim", componentId, fileId, "per-machine", target ?? String.Empty, targetVersion ?? String.Empty);
                string     installCmdLinePerUser      = String.Format("{0} \"[#{1}]\"", cmdlinePrefix, fileId);
                string     installCmdLinePerMachine   = String.Concat(installCmdLinePerUser, " /admin");
                string     installConditionPerUser    = String.Format("NOT ALLUSERS AND ${0}=3", componentId); // only execute if the Component being installed.
                string     installConditionPerMachine = String.Format("ALLUSERS AND ${0}=3", componentId);     // only execute if the Component being installed.

                this.SchedulePropertyExeAction(sourceLineNumbers, installNamePerUser, propertyId, installCmdLinePerUser, installExtraBits, installConditionPerUser, null, installAfter);
                this.SchedulePropertyExeAction(sourceLineNumbers, installNamePerMachine, propertyId, installCmdLinePerMachine, installExtraBits | VSCompiler.MsidbCustomActionTypeNoImpersonate, installConditionPerMachine, null, installNamePerUser.Id);

                // If not permanent, schedule the uninstall custom action.
                if (permanent != YesNoType.Yes)
                {
                    Identifier uninstallNamePerUser         = this.Core.CreateIdentifier("vuu", componentId, fileId, "per-user", target ?? String.Empty, targetVersion ?? String.Empty);
                    Identifier uninstallNamePerMachine      = this.Core.CreateIdentifier("vum", componentId, fileId, "per-machine", target ?? String.Empty, targetVersion ?? String.Empty);
                    string     uninstallCmdLinePerUser      = String.Concat(cmdlinePrefix, " /u:\"", packageId, "\"");
                    string     uninstallCmdLinePerMachine   = String.Concat(uninstallCmdLinePerUser, " /admin");
                    int        uninstallExtraBitsPerUser    = VSCompiler.MsidbCustomActionTypeContinue | VSCompiler.MsidbCustomActionTypeInScript;
                    int        uninstallExtraBitsPerMachine = uninstallExtraBitsPerUser | VSCompiler.MsidbCustomActionTypeNoImpersonate;
                    string     uninstallConditionPerUser    = String.Format("NOT ALLUSERS AND ${0}=2 AND ?{0}>2", componentId); // Only execute if component is being uninstalled.
                    string     uninstallConditionPerMachine = String.Format("ALLUSERS AND ${0}=2 AND ?{0}>2", componentId);     // Only execute if component is being uninstalled.

                    this.SchedulePropertyExeAction(sourceLineNumbers, uninstallNamePerUser, propertyId, uninstallCmdLinePerUser, uninstallExtraBitsPerUser, uninstallConditionPerUser, "InstallFinalize", null);
                    this.SchedulePropertyExeAction(sourceLineNumbers, uninstallNamePerMachine, propertyId, uninstallCmdLinePerMachine, uninstallExtraBitsPerMachine, uninstallConditionPerMachine, "InstallFinalize", null);
                }
            }
        }
Beispiel #28
0
        /// <summary>
        /// Processes the RequiresRef element.
        /// </summary>
        /// <param name="node">The XML node for the RequiresRef element.</param>
        /// <param name="providerId">The parent provider identifier.</param>
        /// <param name="requiresAction">Whether the Requires custom action should be referenced.</param>
        private void ParseRequiresRefElement(XmlNode node, string providerId, bool requiresAction)
        {
            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string id = null;

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    switch (attrib.LocalName)
                    {
                    case "Id":
                        id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
                        break;

                    default:
                        this.Core.UnexpectedAttribute(sourceLineNumbers, attrib);
                        break;
                    }
                }
                else
                {
                    this.Core.UnsupportedExtensionAttribute(sourceLineNumbers, attrib);
                }
            }

            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        this.Core.UnexpectedElement(node, child);
                    }
                    else
                    {
                        this.Core.UnsupportedExtensionElement(node, child);
                    }
                }
            }

            if (String.IsNullOrEmpty(id))
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.LocalName, "Id"));
            }

            if (!this.Core.EncounteredError)
            {
                // Reference the Require custom action if required.
                if (requiresAction)
                {
                    if (Platform.ARM == this.Core.CurrentPlatform)
                    {
                        // Ensure the ARM version of the CA is referenced.
                        this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "WixDependencyRequire_ARM");
                    }
                    else
                    {
                        // All other supported platforms use x86.
                        this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "WixDependencyRequire");
                    }
                }

                // Create a link dependency on the row that contains information we'll need during bind.
                this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "WixDependency", id);

                // Create the relationship between the WixDependency row and the parent WixDependencyProvider row.
                Row row = this.Core.CreateRow(sourceLineNumbers, "WixDependencyRef");
                row[0] = providerId;
                row[1] = id;
            }
        }
Beispiel #29
0
        /// <summary>
        /// Parses a WixStandardBootstrapperApplication element for Bundles.
        /// </summary>
        /// <param name="node">The element to parse.</param>
        private void ParseWixStandardBootstrapperApplicationElement(XmlNode node)
        {
            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
            string    licenseFile              = null;
            string    licenseUrl               = null;
            string    logoFile                 = null;
            string    themeFile                = null;
            string    localizationFile         = null;
            YesNoType suppressOptionsUI        = YesNoType.NotSet;
            YesNoType suppressDowngradeFailure = YesNoType.NotSet;

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace)
                {
                    switch (attrib.LocalName)
                    {
                    case "LicenseFile":
                        licenseFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib, false);
                        break;

                    case "LicenseUrl":
                        licenseUrl = this.Core.GetAttributeValue(sourceLineNumbers, attrib, false);
                        break;

                    case "LogoFile":
                        logoFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib, false);
                        break;

                    case "ThemeFile":
                        themeFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib, false);
                        break;

                    case "LocalizationFile":
                        localizationFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib, false);
                        break;

                    case "SuppressOptionsUI":
                        suppressOptionsUI = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                        break;

                    case "SuppressDowngradeFailure":
                        suppressDowngradeFailure = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
                        break;

                    default:
                        this.Core.UnexpectedAttribute(sourceLineNumbers, attrib);
                        break;
                    }
                }
                else
                {
                    this.Core.UnsupportedExtensionAttribute(sourceLineNumbers, attrib);
                }
            }

            foreach (XmlNode child in node.ChildNodes)
            {
                if (XmlNodeType.Element == child.NodeType)
                {
                    if (child.NamespaceURI == this.schema.TargetNamespace)
                    {
                        this.Core.UnexpectedElement(node, child);
                    }
                    else
                    {
                        this.Core.UnsupportedExtensionElement(node, child);
                    }
                }
            }

            if (String.IsNullOrEmpty(licenseFile) == String.IsNullOrEmpty(licenseUrl))
            {
                this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "LicenseFile", "LicenseUrl", true));
            }

            if (!this.Core.EncounteredError)
            {
                if (!String.IsNullOrEmpty(licenseFile))
                {
                    this.Core.CreateWixVariableRow(sourceLineNumbers, "WixStdbaLicenseRtf", licenseFile, false);
                }

                if (!String.IsNullOrEmpty(licenseUrl))
                {
                    this.Core.CreateWixVariableRow(sourceLineNumbers, "WixStdbaLicenseUrl", licenseUrl, false);
                }

                if (!String.IsNullOrEmpty(logoFile))
                {
                    this.Core.CreateWixVariableRow(sourceLineNumbers, "WixStdbaLogo", logoFile, false);
                }

                if (!String.IsNullOrEmpty(themeFile))
                {
                    this.Core.CreateWixVariableRow(sourceLineNumbers, "WixStdbaThemeXml", themeFile, false);
                }

                if (!String.IsNullOrEmpty(localizationFile))
                {
                    this.Core.CreateWixVariableRow(sourceLineNumbers, "WixStdbaThemeWxl", localizationFile, false);
                }

                if (YesNoType.Yes == suppressOptionsUI || YesNoType.Yes == suppressDowngradeFailure)
                {
                    Row row = this.Core.CreateRow(sourceLineNumbers, "WixStdbaOptions");
                    if (YesNoType.Yes == suppressOptionsUI)
                    {
                        row[0] = 1;
                    }

                    if (YesNoType.Yes == suppressDowngradeFailure)
                    {
                        row[1] = 1;
                    }
                }
            }
        }
        private void ParseFileElement(XmlNode node)
        {
            SourceLineNumberCollection sourceLineNumber = Preprocessor.GetSourceLineNumbers(node);

            string    superElementId = null;
            string    file           = null;
            string    arguments      = null;
            var       elevated       = YesNoType.No;
            YesNoType ignoreErrors   = YesNoType.No;
            int       order          = 1000000000 + sourceLineNumber[0].LineNumber;

            foreach (XmlAttribute attribute in node.Attributes)
            {
                if (attribute.NamespaceURI.Length == 0 ||
                    attribute.NamespaceURI == _schema.TargetNamespace)
                {
                    switch (attribute.LocalName)
                    {
                    case "Id":
                        superElementId = Core.GetAttributeIdentifierValue(sourceLineNumber, attribute);
                        break;

                    case "File":
                        file = Core.GetAttributeValue(sourceLineNumber, attribute, false);
                        break;

                    case "Arguments":
                        arguments = Core.GetAttributeValue(sourceLineNumber, attribute);
                        break;

                    case "Elevated":
                        elevated = Core.GetAttributeYesNoValue(sourceLineNumber, attribute);
                        break;

                    case "IgnoreErrors":
                        ignoreErrors = Core.GetAttributeYesNoValue(sourceLineNumber, attribute);
                        break;

                    case "Order":
                        order = Core.GetAttributeIntegerValue(sourceLineNumber, attribute, 0, 1000000000);
                        break;

                    default:
                        Core.UnexpectedAttribute(sourceLineNumber, attribute);
                        break;
                    }
                }
                else
                {
                    Core.UnsupportedExtensionAttribute(sourceLineNumber, attribute);
                }
            }

            if (string.IsNullOrEmpty(superElementId))
            {
                Core.OnMessage(
                    WixErrors.ExpectedAttribute(sourceLineNumber, node.Name, "Id"));
            }

            if (string.IsNullOrEmpty(file))
            {
                Core.OnMessage(
                    WixErrors.ExpectedElement(sourceLineNumber, node.Name, "File"));
            }

            if (!Core.EncounteredError)
            {
                Row superElementRow = Core.CreateRow(sourceLineNumber, "PowerShellFiles");

                superElementRow[0] = superElementId;
                superElementRow[1] = file;
                superElementRow[2] = arguments;
                superElementRow[3] = elevated == YesNoType.Yes ? 1 : 0;
                superElementRow[4] = (ignoreErrors == YesNoType.Yes) ? 1 : 0;
                superElementRow[5] = order;
            }

            Core.CreateWixSimpleReferenceRow(sourceLineNumber, "CustomAction", "PowerShellFilesImmediate");
        }