public string GetAttributeLongFilename(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool allowWildcards, bool allowRelative) { if (null == attribute) { throw new ArgumentNullException("attribute"); } var value = this.GetAttributeValue(sourceLineNumbers, attribute); if (0 < value.Length) { if (!this.IsValidLongFilename(value, allowWildcards, allowRelative) && !this.IsValidLocIdentifier(value)) { if (allowRelative) { this.Messaging.Write(ErrorMessages.IllegalRelativeLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); } else { this.Messaging.Write(ErrorMessages.IllegalLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); } } else if (allowRelative) { value = this.GetCanonicalRelativePath(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value); } else if (CompilerCore.IsAmbiguousFilename(value)) { this.Messaging.Write(WarningMessages.AmbiguousFileOrDirectoryName(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); } } return(value); }
public void _MemberToString_ThrowsForNonBoolNonProp() { var str = "stringy"; Expression <Func <TestLdapModel, object> > expr = (TestLdapModel m) => str; var cc = new CompilerCore(new CompilerOptions()); Assert.Throws <NotImplementedException>(() => cc._MemberToString(expr.Body as MemberExpression, expr.Parameters)); }
/// <summary> /// Creates a stable and unique Directory table identifier by combining a prefix with a component identifier (Id, not GUID). /// </summary> /// <param name="sourceLineNumbers">Source line number for the parent element.</param> /// <param name="prefix">A prefix that "uniquifies" the generated identifier.</param> /// <param name="componentId">The owning component's identifier.</param> /// <returns>The generated Directory table identifier.</returns> private string GetTaskDirectoryId(SourceLineNumberCollection sourceLineNumbers, string prefix, string componentId) { string id = String.Concat(prefix, "_", componentId); if (72 < id.Length || !CompilerCore.IsIdentifier(id)) { this.Core.OnMessage(GamingErrors.IllegalGameTaskDirectoryIdentifier(sourceLineNumbers, id)); } return(id); }
/// <summary> /// Parses a PlayTask element for Game Explorer task registration. /// </summary> /// <param name="node">The element to parse.</param> /// <param name="gameId">The game's instance identifier.</param> /// <param name="fileId">The file identifier of the game executable.</param> /// <param name="componentId">The component identifier of the game executable.</param> /// <param name="taskOrder">The order this play task should appear in Game Explorer.</param> private void ParsePlayTaskElement(XElement node, string gameId, string fileId, string componentId, int taskOrder, string componentDirectoryId) { SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); string name = null; string arguments = null; foreach (XAttribute attrib in node.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Name": name = this.Core.GetAttributeValue(sourceLineNumbers, attrib, false); break; case "Arguments": arguments = this.Core.GetAttributeValue(sourceLineNumbers, attrib, false); break; default: this.Core.UnexpectedAttribute(sourceLineNumbers, attrib); break; } } else { this.Core.ParseExtensionAttribute(node, attrib); } } this.Core.ParseForExtensionElements(node); if (null == name) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); } if (!this.Core.EncounteredError) { // create Shortcut rows pointing to the parent File string directoryId = this.CreateTaskDirectoryRow(sourceLineNumbers, componentId, TaskType.Play, taskOrder); Row row = this.Core.CreateRow(sourceLineNumbers, "Shortcut"); row[0] = directoryId; // just need something unique-and-stable row[1] = directoryId; row[2] = CompilerCore.IsValidShortFilename(name, false) ? name : String.Concat(this.Core.GenerateShortName(name, true, false, directoryId, name), "|", name); row[3] = componentId; row[4] = String.Format(CultureInfo.InvariantCulture, "[#{0}]", fileId); row[5] = arguments; // skipping Description, Hotkey, Icon_, IconIndex, ShowCmd row[11] = componentDirectoryId; } }
/// <summary> /// Parses a Condition element for Bundles. /// </summary> /// <param name="node">The element to parse.</param> private void ParseConditionElement(XElement node) { SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); string condition = CompilerCore.GetConditionInnerText(node); // condition is the inner text of the element. string message = null; foreach (XAttribute attrib in node.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Message": message = this.Core.GetAttributeValue(sourceLineNumbers, attrib, false); break; default: this.Core.UnexpectedAttribute(sourceLineNumbers, attrib); break; } } else { this.Core.ParseExtensionAttribute(node, attrib); } } this.Core.ParseForExtensionElements(node); // Error check the values. if (String.IsNullOrEmpty(condition)) { this.Core.OnMessage(WixErrors.ConditionExpected(sourceLineNumbers, node.Name.LocalName)); } if (null == message) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "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; } } }
/// <summary> /// Parses a RemoteAddress element /// </summary> /// <param name="node">The element to parse.</param> private void ParseRemoteAddressElement(XmlNode node, ref string remoteAddresses) { SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); // no attributes foreach (XmlAttribute attrib in node.Attributes) { if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace) { this.Core.UnexpectedAttribute(sourceLineNumbers, attrib); } else { this.Core.UnsupportedExtensionAttribute(sourceLineNumbers, attrib); } } // no children 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); } } } string address = CompilerCore.GetTrimmedInnerText(node); if (String.IsNullOrEmpty(address)) { this.Core.OnMessage(FirewallErrors.IllegalEmptyRemoteAddress(sourceLineNumbers)); } else { if (String.IsNullOrEmpty(remoteAddresses)) { remoteAddresses = address; } else { remoteAddresses = String.Concat(remoteAddresses, ",", address); } } }
public override string EvaluateFunction(string prefix, string function, string[] args) { switch (function) { case "VarNullOrEmpty": if (args.Length != 1 || string.IsNullOrEmpty(args[0])) { throw new WixException(WixErrors.InvalidPreprocessorFunction(null, function)); } string val = Core.GetVariableValue(null, args[0], true); return(string.IsNullOrEmpty(val) ? "1" : "0"); case "AutoGuid": if (args.Length == 0) { throw new WixException(WixErrors.InvalidPreprocessorFunction(null, function)); } string key = args.Aggregate((a, c) => $"{a}\\{c}"); string guid = CompilerCore.NewGuid(new Guid("{F026BBCE-4776-402C-BF36-352781805165}"), key); return(guid); case "FileExists": if (args.Length != 1 || string.IsNullOrEmpty(args[0])) { throw new WixException(WixErrors.InvalidPreprocessorFunction(null, function)); } return(File.Exists(args[0]) ? "1" : "0"); case "DirExists": if (args.Length != 1 || string.IsNullOrEmpty(args[0])) { throw new WixException(WixErrors.InvalidPreprocessorFunction(null, function)); } return(Directory.Exists(args[0]) ? "1" : "0"); case "DirEmpty": if (args.Length != 1 || string.IsNullOrEmpty(args[0])) { throw new WixException(WixErrors.InvalidPreprocessorFunction(null, function)); } return((Directory.Exists(args[0]) && (Directory.GetFiles(args[0], "*", SearchOption.AllDirectories).Length > 0)) ? "0" : "1"); default: return(null); } }
/// <summary> /// Harvest a performance category. /// </summary> /// <param name="category">The name of the performance category.</param> /// <returns>A harvested file.</returns> public Util.PerformanceCategory HarvestPerformanceCategory(string category) { if (null == category) { throw new ArgumentNullException("category"); } if (PerformanceCounterCategory.Exists(category)) { Util.PerformanceCategory perfCategory = new Util.PerformanceCategory(); // Get the performance counter category and set the appropriate WiX attributes PerformanceCounterCategory pcc = PerformanceCounterCategory.GetCategories().Single(c => string.Equals(c.CategoryName, category)); perfCategory.Id = CompilerCore.GetIdentifierFromName(pcc.CategoryName); perfCategory.Name = pcc.CategoryName; perfCategory.Help = pcc.CategoryHelp; if (PerformanceCounterCategoryType.MultiInstance == pcc.CategoryType) { perfCategory.MultiInstance = Util.YesNoType.yes; } // If it's multi-instance, check if there are any instances and get counters from there; else we get // the counters straight up. For multi-instance, GetCounters() fails if there are any instances. If there // are no instances, then GetCounters(instance) can't be called since there is no instance. Instances // will exist for each counter even if only one of the counters was "intialized." string[] instances = pcc.GetInstanceNames(); bool hasInstances = instances.Length > 0; PerformanceCounter[] counters = hasInstances ? pcc.GetCounters(instances.First()) : pcc.GetCounters(); foreach (PerformanceCounter counter in counters) { Util.PerformanceCounter perfCounter = new Util.PerformanceCounter(); // Get the performance counter and set the appropriate WiX attributes perfCounter.Name = counter.CounterName; perfCounter.Type = CounterTypeToWix(counter.CounterType); perfCounter.Help = counter.CounterHelp; perfCategory.AddChild(perfCounter); } return(perfCategory); } else { throw new WixException(UtilErrors.PerformanceCategoryNotFound(category)); } }
private Util.PerformanceCategory GetPerformanceCategory(string categoryName) { Console.WriteLine($"Getting counters for CategoryName: {categoryName}"); try { var category = PerformanceCounterCategory.GetCategories() .Single(c => string.Equals(categoryName, c.CategoryName, StringComparison.OrdinalIgnoreCase)); var isMultiInstance = category.CategoryType == PerformanceCounterCategoryType.MultiInstance; Trace.WriteLine($"Found category={categoryName}, MultiInstance={isMultiInstance}"); // If it's multi-instance, check if there are any instances and get counters from there; else we get // the counters straight up. For multi-instance, GetCounters() fails if there are any instances. If there // are no instances, then GetCounters(instance) can't be called since there is no instance. Instances // will exist for each counter even if only one of the counters was "intialized." var hasInstances = category.GetInstanceNames().Length > 0; var counters = hasInstances ? category.GetCounters(category.GetInstanceNames().First()) : category.GetCounters(); Trace.WriteLine($"Found {counters.Length} counters"); var result = new Util.PerformanceCategory { Id = CompilerCore.GetIdentifierFromName(category.CategoryName), Name = category.CategoryName, Help = category.CategoryHelp, MultiInstance = isMultiInstance ? Util.YesNoType.yes : Util.YesNoType.no }; foreach (var counter in counters) { Console.WriteLine($"Counter={counter.CounterName}, Type={counter.CounterType}"); result.AddChild(new Util.PerformanceCounter { Name = counter.CounterName, Type = CounterTypeToWix(counter.CounterType), Help = counter.CounterHelp, }); } return(result); } catch (Exception ex) { Trace.WriteLine(ex.Message); throw new WixException(UtilErrors.PerformanceCategoryNotFound(categoryName)); } }
public override Fragment[] Harvest(string categoryName) { var component = new Component { KeyPath = YesNoType.yes, Id = string.IsNullOrEmpty(ComponentId) ? CompilerCore.GetIdentifierFromName(categoryName) : ComponentId.Trim(), Directory = string.IsNullOrEmpty(DirectoryId) ? "TARGETDIR" : DirectoryId.Trim() }; component.AddChild(GetPerformanceCategory(categoryName)); var fragment = new Fragment(); fragment.AddChild(component); return(new [] { fragment }); }
/// <summary> /// Harvest a performance category. /// </summary> /// <param name="category">The name of the performance category.</param> /// <returns>A harvested file.</returns> public Util.PerformanceCategory HarvestPerformanceCategory(string category) { if (null == category) { throw new ArgumentNullException("category"); } if (PerformanceCounterCategory.Exists(category)) { Util.PerformanceCategory perfCategory = new Util.PerformanceCategory(); // Get the performance counter category and set the appropriate WiX attributes PerformanceCounterCategory pcc = new PerformanceCounterCategory(category); perfCategory.Id = CompilerCore.GetIdentifierFromName(pcc.CategoryName); perfCategory.Name = pcc.CategoryName; perfCategory.Help = pcc.CategoryHelp; if (PerformanceCounterCategoryType.MultiInstance == pcc.CategoryType) { perfCategory.MultiInstance = Util.YesNoType.yes; } foreach (InstanceDataCollection counter in pcc.ReadCategory().Values) { Util.PerformanceCounter perfCounter = new Util.PerformanceCounter(); // Get the performance counter and set the appropriate WiX attributes PerformanceCounter pc = new PerformanceCounter(pcc.CategoryName, counter.CounterName); perfCounter.Name = pc.CounterName; perfCounter.Type = CounterTypeToWix(pc.CounterType); perfCounter.Help = pc.CounterHelp; perfCategory.AddChild(perfCounter); } return(perfCategory); } else { throw new WixException(UtilErrors.PerformanceCategoryNotFound(category)); } }
public string GetAttributeLongFilename(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool allowWildcards, bool allowRelative) { if (null == attribute) { throw new ArgumentNullException("attribute"); } string value = this.GetAttributeValue(sourceLineNumbers, attribute); if (0 < value.Length) { if (!this.IsValidLongFilename(value, allowWildcards, allowRelative) && !this.IsValidLocIdentifier(value)) { if (allowRelative) { this.Messaging.Write(ErrorMessages.IllegalRelativeLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); } else { this.Messaging.Write(ErrorMessages.IllegalLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); } } else if (allowRelative) { string normalizedPath = value.Replace('\\', '/'); if (normalizedPath.StartsWith("../", StringComparison.Ordinal) || normalizedPath.Contains("/../")) { this.Messaging.Write(ErrorMessages.PayloadMustBeRelativeToCache(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); } } else if (CompilerCore.IsAmbiguousFilename(value)) { this.Messaging.Write(WarningMessages.AmbiguousFileOrDirectoryName(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, value)); } } return(value); }
/// <summary> /// Parses a RemoteAddress element /// </summary> /// <param name="node">The element to parse.</param> private void ParseRemoteAddressElement(XElement node, ref string remoteAddresses) { SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); // no attributes foreach (XAttribute attrib in node.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { this.Core.UnexpectedAttribute(sourceLineNumbers, attrib); } else { this.Core.ParseExtensionAttribute(node, attrib); } } this.Core.ParseForExtensionElements(node); string address = CompilerCore.GetTrimmedInnerText(node); if (String.IsNullOrEmpty(address)) { this.Core.OnMessage(FirewallErrors.IllegalEmptyRemoteAddress(sourceLineNumbers)); } else { if (String.IsNullOrEmpty(remoteAddresses)) { remoteAddresses = address; } else { remoteAddresses = String.Concat(remoteAddresses, ",", address); } } }
/// <summary> /// Harvest a performance category. /// </summary> /// <param name="argument">The name of the performance category.</param> /// <returns>A harvested performance category.</returns> public override Wix.Fragment[] Harvest(string argument) { if (null == argument) { throw new ArgumentNullException("argument"); } Util.PerformanceCategory perf = this.HarvestPerformanceCategory(argument); Wix.Component component = new Wix.Component(); component.Id = CompilerCore.GetIdentifierFromName(argument); component.KeyPath = Wix.YesNoType.yes; component.AddChild(perf); Wix.Directory directory = new Wix.Directory(); directory.Id = "TARGETDIR"; //directory.Name = directory.Id; directory.AddChild(component); Wix.Fragment fragment = new Wix.Fragment(); fragment.AddChild(directory); return(new Wix.Fragment[] { fragment }); }
public CompilerPayload(CompilerCore core, SourceLineNumber sourceLineNumbers, XElement element) { this.Core = core; this.Element = element; this.SourceLineNumbers = sourceLineNumbers; }
/// <summary> /// Gets the modularized version of the field data. /// </summary> /// <param name="field">The field to modularize.</param> /// <param name="modularizationGuid">String containing the GUID of the Merge Module to append the the field value, if appropriate.</param> /// <param name="suppressModularizationIdentifiers">Optional collection of identifiers that should not be modularized.</param> /// <remarks>moduleGuid is expected to be null when not being used to compile a Merge Module.</remarks> /// <returns>The modularized version of the field data.</returns> internal string GetModularizedValue(Field field, string modularizationGuid, Hashtable suppressModularizationIdentifiers) { Debug.Assert(null != field.Data && 0 < ((string)field.Data).Length); string fieldData = Convert.ToString(field.Data, CultureInfo.InvariantCulture); if (null != modularizationGuid && ColumnModularizeType.None != field.Column.ModularizeType && !(Util.IsStandardAction(fieldData) || Util.IsStandardProperty(fieldData))) { StringBuilder sb; int start; ColumnModularizeType modularizeType = field.Column.ModularizeType; // special logic for the ControlEvent table's Argument column // this column requires different modularization methods depending upon the value of the Event column if (ColumnModularizeType.ControlEventArgument == field.Column.ModularizeType) { switch (this[2].ToString()) { case "CheckExistingTargetPath": // redirectable property name case "CheckTargetPath": case "DoAction": // custom action name case "NewDialog": // dialog name case "SelectionBrowse": case "SetTargetPath": case "SpawnDialog": case "SpawnWaitDialog": if (CompilerCore.IsIdentifier(fieldData)) { modularizeType = ColumnModularizeType.Column; } else { modularizeType = ColumnModularizeType.Property; } break; default: // formatted modularizeType = ColumnModularizeType.Property; break; } } else if (ColumnModularizeType.ControlText == field.Column.ModularizeType) { // icons are stored in the Binary table, so they get column-type modularization if (("Bitmap" == this[2].ToString() || "Icon" == this[2].ToString()) && CompilerCore.IsIdentifier(fieldData)) { modularizeType = ColumnModularizeType.Column; } else { modularizeType = ColumnModularizeType.Property; } } switch (modularizeType) { case ColumnModularizeType.Column: // ensure the value is an identifier (otherwise it shouldn't be modularized this way) if (!CompilerCore.IsIdentifier(fieldData)) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_CannotModularizeIllegalID, fieldData)); } // if we're not supposed to suppress modularization of this identifier if (null == suppressModularizationIdentifiers || !suppressModularizationIdentifiers.Contains(fieldData)) { fieldData = String.Concat(fieldData, ".", modularizationGuid); } break; case ColumnModularizeType.Property: case ColumnModularizeType.Condition: Regex regex; if (ColumnModularizeType.Property == modularizeType) { regex = new Regex(@"\[(?<identifier>[#$!]?[a-zA-Z_][a-zA-Z0-9_\.]*)]", RegexOptions.Singleline | RegexOptions.ExplicitCapture); } else { Debug.Assert(ColumnModularizeType.Condition == modularizeType); // This heinous looking regular expression is actually quite an elegant way // to shred the entire condition into the identifiers that need to be // modularized. Let's break it down piece by piece: // // 1. Look for the operators: NOT, EQV, XOR, OR, AND, IMP. Note that the // regular expression is case insensitive so we don't have to worry about // all the permutations of these strings. // 2. Look for quoted strings. Quoted strings are just text and are ignored // outright. // 3. Look for environment variables. These look like identifiers we might // otherwise be interested in but start with a percent sign. Like quoted // strings these enviroment variable references are ignored outright. // 4. Match all identifiers that are things that need to be modularized. Note // the special characters (!, $, ?, &) that denote Component and Feature states. regex = new Regex(@"NOT|EQV|XOR|OR|AND|IMP|"".*?""|%[a-zA-Z_][a-zA-Z0-9_\.]*|(?<identifier>[!$\?&]?[a-zA-Z_][a-zA-Z0-9_\.]*)", RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); // less performant version of the above with captures showing where everything lives // regex = new Regex(@"(?<operator>NOT|EQV|XOR|OR|AND|IMP)|(?<string>"".*?"")|(?<environment>%[a-zA-Z_][a-zA-Z0-9_\.]*)|(?<identifier>[!$\?&]?[a-zA-Z_][a-zA-Z0-9_\.]*)",RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); } MatchCollection matches = regex.Matches(fieldData); sb = new StringBuilder(fieldData); // notice how this code walks backward through the list // because it modifies the string as we through it for (int i = matches.Count - 1; 0 <= i; i--) { Group group = matches[i].Groups["identifier"]; if (group.Success) { string identifier = group.Value; if (!Util.IsStandardProperty(identifier) && (null == suppressModularizationIdentifiers || !suppressModularizationIdentifiers.Contains(identifier))) { sb.Insert(group.Index + group.Length, '.'); sb.Insert(group.Index + group.Length + 1, modularizationGuid); } } } fieldData = sb.ToString(); break; case ColumnModularizeType.CompanionFile: // if we're not supposed to ignore this identifier and the value does not start with // a digit, we must have a companion file so modularize it if ((null == suppressModularizationIdentifiers || !suppressModularizationIdentifiers.Contains(fieldData)) && 0 < fieldData.Length && !Char.IsDigit(fieldData, 0)) { fieldData = String.Concat(fieldData, ".", modularizationGuid); } break; case ColumnModularizeType.Icon: if (null == suppressModularizationIdentifiers || !suppressModularizationIdentifiers.Contains(fieldData)) { start = fieldData.LastIndexOf(".", StringComparison.Ordinal); if (-1 == start) { fieldData = String.Concat(fieldData, ".", modularizationGuid); } else { fieldData = String.Concat(fieldData.Substring(0, start), ".", modularizationGuid, fieldData.Substring(start)); } } break; case ColumnModularizeType.SemicolonDelimited: string[] keys = fieldData.Split(';'); for (int i = 0; i < keys.Length; ++i) { keys[i] = String.Concat(keys[i], ".", modularizationGuid); } fieldData = String.Join(";", keys); break; } } return(fieldData); }
/// <summary> /// Creates the rows needed for WixInternetShortcut to work. /// </summary> /// <param name="core">The CompilerCore object used to create rows.</param> /// <param name="sourceLineNumbers">Source line information about the owner element.</param> /// <param name="componentId">Identifier of parent component.</param> /// <param name="directoryId">Identifier of directory containing shortcut.</param> /// <param name="id">Identifier of shortcut.</param> /// <param name="name">Name of shortcut without extension.</param> /// <param name="target">Target URL of shortcut.</param> public static void CreateWixInternetShortcut(CompilerCore core, SourceLineNumberCollection sourceLineNumbers, string componentId, string directoryId, string shortcutId, string name, string target, InternetShortcutType type) { // add the appropriate extension based on type of shortcut name = String.Concat(name, InternetShortcutType.Url == type ? ".url" : ".lnk"); Row row = core.CreateRow(sourceLineNumbers, "WixInternetShortcut"); row[0] = shortcutId; row[1] = componentId; row[2] = directoryId; row[3] = name; row[4] = target; row[5] = (int)type; // Reference custom action because nothing will happen without it core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "WixSchedInternetShortcuts"); // make sure we have a CreateFolder table so that the immediate CA can add temporary rows to handle installation and uninstallation core.EnsureTable(sourceLineNumbers, "CreateFolder"); // use built-in MSI functionality to remove the shortcuts rather than doing so via CA row = core.CreateRow(sourceLineNumbers, "RemoveFile"); row[0] = shortcutId; row[1] = componentId; row[2] = CompilerCore.IsValidShortFilename(name, false) ? name : String.Concat(core.GenerateShortName(name, true, false, directoryId, name), "|", name); row[3] = directoryId; row[4] = 2; // msidbRemoveFileInstallModeOnRemove }
/// <summary> /// Parses a PatchFamily element. /// </summary> /// <param name="node">The element to parse.</param> /// <param name="parentType"></param> /// <param name="parentId"></param> private void ParsePatchFamilyElement(XElement node, ComplexReferenceParentType parentType, string parentId) { var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); Identifier id = null; string productCode = null; string version = null; var attributes = 0; foreach (var attrib in node.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Id": id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib); break; case "ProductCode": productCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); break; case "Version": version = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib); break; case "Supersede": if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= 0x1; } break; default: this.Core.UnexpectedAttribute(node, attrib); break; } } else { this.Core.ParseExtensionAttribute(node, attrib); } } if (null == id) { this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); id = Identifier.Invalid; } if (String.IsNullOrEmpty(version)) { this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version")); } else if (!CompilerCore.IsValidProductVersion(version)) { this.Core.Write(ErrorMessages.InvalidProductVersion(sourceLineNumbers, version)); } // find unexpected child elements foreach (var child in node.Elements()) { if (CompilerCore.WixNamespace == child.Name.Namespace) { switch (child.Name.LocalName) { case "All": this.ParseAllElement(child); break; case "BinaryRef": this.ParsePatchChildRefElement(child, "Binary"); break; case "ComponentRef": this.ParsePatchChildRefElement(child, "Component"); break; case "CustomActionRef": this.ParsePatchChildRefElement(child, "CustomAction"); break; case "DirectoryRef": this.ParsePatchChildRefElement(child, "Directory"); break; case "DigitalCertificateRef": this.ParsePatchChildRefElement(child, "MsiDigitalCertificate"); break; case "FeatureRef": this.ParsePatchChildRefElement(child, "Feature"); break; case "IconRef": this.ParsePatchChildRefElement(child, "Icon"); break; case "PropertyRef": this.ParsePatchChildRefElement(child, "Property"); break; case "SoftwareTagRef": this.ParseTagRefElement(child); break; case "UIRef": this.ParsePatchChildRefElement(child, "WixUI"); break; default: this.Core.UnexpectedElement(node, child); break; } } else { this.Core.ParseExtensionElement(node, child); } } if (!this.Core.EncounteredError) { this.Core.AddSymbol(new MsiPatchSequenceSymbol(sourceLineNumbers) { PatchFamily = id.Id, ProductCode = productCode, Sequence = version, Attributes = attributes }); if (ComplexReferenceParentType.Unknown != parentType) { this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamily, id.Id, ComplexReferenceParentType.Patch == parentType); } } }
/// <summary> /// Parses a UnitTest element to create Lux unit tests. /// </summary> /// <param name="node">The element to parse.</param> /// <param name="args">Used while parsing multi-value property tests to pass values from the parent element.</param> private void ParseUnitTestElement(XmlNode node, string mutation, params string[] args) { SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); bool multiValue = 0 < args.Length; string id = null; string action = multiValue ? args[0] : null; string property = multiValue ? args[1] : null; string op = null; Operator oper = Operator.NotSet; string value = null; string expression = null; string valueSep = multiValue ? args[2] : null; string nameValueSep = multiValue ? args[3] : null; string condition = null; string index = null; foreach (XmlAttribute attrib in node.Attributes) { if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace) { switch (attrib.LocalName) { case "CustomAction": case "Property": case "Expression": case "ValueSeparator": case "NameValueSeparator": if (multiValue) { this.Core.OnMessage(LuxErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.LocalName, attrib.LocalName)); } break; } switch (attrib.LocalName) { case "Id": id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); break; case "CustomAction": action = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); break; case "Property": property = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); break; case "Operator": op = this.Core.GetAttributeValue(sourceLineNumbers, attrib); if (0 < op.Length) { switch (op) { case "equal": oper = Operator.Equal; break; case "notEqual": oper = Operator.NotEqual; break; case "caseInsensitiveEqual": oper = Operator.CaseInsensitiveEqual; break; case "caseInsensitiveNotEqual": oper = Operator.CaseInsensitiveNotEqual; break; default: this.Core.OnMessage(WixErrors.IllegalAttributeValue(sourceLineNumbers, node.LocalName, attrib.LocalName, op, "equal", "notEqual", "caseInsensitiveEqual", "caseInsensitiveNotEqual")); break; } } break; case "Value": value = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "ValueSeparator": valueSep = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "NameValueSeparator": nameValueSep = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "Index": if (!multiValue) { this.Core.OnMessage(LuxErrors.IllegalAttributeWhenNotNested(sourceLineNumbers, node.LocalName, attrib.LocalName)); } index = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; default: this.Core.UnexpectedAttribute(sourceLineNumbers, attrib); break; } } else { this.Core.UnsupportedExtensionAttribute(sourceLineNumbers, attrib); } } bool isParent = false; foreach (XmlNode child in node.ChildNodes) { if (XmlNodeType.Element == child.NodeType) { if (child.NamespaceURI == this.schema.TargetNamespace) { switch (child.LocalName) { case "Condition": // the condition should not be empty condition = CompilerCore.GetConditionInnerText(child); if (null == condition || 0 == condition.Length) { condition = null; this.Core.OnMessage(WixErrors.ConditionExpected(sourceLineNumbers, child.Name)); } break; case "Expression": // the expression should not be empty expression = CompilerCore.GetConditionInnerText(child); if (null == expression || 0 == expression.Length) { expression = null; this.Core.OnMessage(WixErrors.ConditionExpected(sourceLineNumbers, child.Name)); } break; case "UnitTest": if (multiValue) { SourceLineNumberCollection childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); this.Core.OnMessage(LuxErrors.ElementTooDeep(childSourceLineNumbers, child.LocalName, node.LocalName)); } this.ParseUnitTestElement(child, mutation, action, property, valueSep, nameValueSep); isParent = true; break; default: this.Core.UnexpectedElement(node, child); break; } } else { this.Core.UnsupportedExtensionElement(node, child); } } } if (isParent) { if (!String.IsNullOrEmpty(value)) { this.Core.OnMessage(LuxErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.LocalName, "Value")); } } else { // the children generate multi-value unit test rows; the parent doesn't generate anything if (!String.IsNullOrEmpty(property) && String.IsNullOrEmpty(value)) { this.Core.OnMessage(WixErrors.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.LocalName, "Property", "Value")); } if (!String.IsNullOrEmpty(property) && !String.IsNullOrEmpty(expression)) { this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.LocalName, "Property", "Expression")); } if (multiValue && String.IsNullOrEmpty(valueSep) && String.IsNullOrEmpty(nameValueSep)) { this.Core.OnMessage(LuxErrors.MissingRequiredParentAttribute(sourceLineNumbers, node.LocalName, "ValueSeparator", "NameValueSeparator")); } if (!String.IsNullOrEmpty(valueSep) && !String.IsNullOrEmpty(nameValueSep)) { this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.LocalName, "ValueSeparator", "NameValueSeparator")); } if (!this.Core.EncounteredError) { if (String.IsNullOrEmpty(id)) { id = this.Core.GenerateIdentifier("lux", action, property, index, condition, mutation); } if (Operator.NotSet == oper) { oper = Operator.Equal; } Row row = this.Core.CreateRow(sourceLineNumbers, "WixUnitTest"); row[0] = id; row[1] = action; row[2] = property; row[3] = (int)oper; row[4] = value; row[5] = expression; row[6] = condition; row[7] = valueSep; row[8] = nameValueSep; row[9] = index; if (!string.IsNullOrEmpty(mutation)) { row[10] = mutation; } this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", action); this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "WixRunImmediateUnitTests"); } } }
/// <summary> /// Parses a Tag element for Software Id Tag registration under a Bundle element. /// </summary> /// <param name="node">The element to parse.</param> private void ParseBundleTagElement(XmlNode node) { SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); string name = null; string regid = null; YesNoType licensed = YesNoType.NotSet; string type = null; foreach (XmlAttribute attrib in node.Attributes) { if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace) { switch (attrib.LocalName) { case "Name": name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false); break; case "Regid": regid = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "Licensed": licensed = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); break; case "Type": type = this.ParseTagTypeAttribute(sourceLineNumbers, node, 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(name)) { XmlAttribute productNameAttribute = node.ParentNode.Attributes["Name"]; if (null != productNameAttribute) { name = productNameAttribute.Value; } else { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Name")); } } if (!String.IsNullOrEmpty(name) && !CompilerCore.IsValidLongFilename(name, false)) { this.Core.OnMessage(TagErrors.IllegalName(sourceLineNumbers, node.ParentNode.LocalName, name)); } if (String.IsNullOrEmpty(regid)) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Regid")); } if (!this.Core.EncounteredError) { string fileName = String.Concat(regid, " ", name, ".swidtag"); Row tagRow = this.Core.CreateRow(sourceLineNumbers, "WixBundleTag"); tagRow[0] = fileName; tagRow[1] = regid; tagRow[2] = name; if (YesNoType.Yes == licensed) { tagRow[3] = 1; } // field 4 is the TagXml set by the binder. tagRow[5] = type; } }
/// <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.sourceFiles.AddRange(AppCommon.GetFiles(arg, "Source")); continue; } if ('-' == arg[0] || '/' == arg[0]) { string parameter = arg.Substring(1); if ("allowPerSourceOutputSpecification" == parameter) { // This is a *long* parameter name; but we want it to be painful because it's // non-standard and we don't really want to have it at all. this.messageHandler.Display(this, WixWarnings.DeprecatedCommandLineSwitch("allowPerSourceOutputSpecification")); this.allowPerSourceOutputSpecification = true; } else if ('d' == parameter[0]) { if (1 >= parameter.Length || '=' == parameter[1]) { this.messageHandler.Display(this, WixErrors.InvalidVariableDefinition(arg)); return; } parameter = arg.Substring(2); string[] value = parameter.Split("=".ToCharArray(), 2); if (this.parameters.ContainsKey(value[0])) { this.messageHandler.Display(this, WixErrors.DuplicateVariableDefinition(value[0], (1 == value.Length) ? String.Empty : value[1], (string)this.parameters[value[0]])); return; } if (1 == value.Length) { this.parameters.Add(value[0], String.Empty); } else { this.parameters.Add(value[0], value[1]); } } else if ("fips" == parameter) { this.fipsCompliant = true; } else if ('I' == parameter[0]) { this.includeSearchPaths.Add(parameter.Substring(1)); } else if ("ext" == parameter) { if (!CommandLine.IsValidArg(args, ++i)) { this.messageHandler.Display(this, WixErrors.TypeSpecificationForExtensionRequired("-ext")); return; } else { this.extensionList.Add(args[i]); } } else if ("nologo" == parameter) { this.showLogo = false; } else if ("o" == parameter || "out" == parameter) { string path = CommandLine.GetFileOrDirectory(parameter, this.messageHandler, args, ++i); if (!String.IsNullOrEmpty(path)) { if (path.EndsWith("\\", StringComparison.Ordinal) || path.EndsWith("/", StringComparison.Ordinal)) { this.outputDirectory = path; } else { this.outputFile = path; } } else { return; } } else if ("pedantic" == parameter) { this.showPedanticMessages = true; } else if ("platform" == parameter || "arch" == parameter) { if ("platform" == parameter) { this.messageHandler.Display(this, WixWarnings.DeprecatedCommandLineSwitch("platform", "arch")); } if (!CommandLine.IsValidArg(args, ++i)) { this.messageHandler.Display(this, WixErrors.InvalidPlatformParameter(parameter, String.Empty)); return; } if (String.Equals(args[i], "intel", StringComparison.OrdinalIgnoreCase) || String.Equals(args[i], "x86", StringComparison.OrdinalIgnoreCase)) { this.platform = Platform.X86; } else if (String.Equals(args[i], "x64", StringComparison.OrdinalIgnoreCase)) { this.platform = Platform.X64; } else if (String.Equals(args[i], "intel64", StringComparison.OrdinalIgnoreCase) || String.Equals(args[i], "ia64", StringComparison.OrdinalIgnoreCase)) { this.platform = Platform.IA64; } else { this.messageHandler.Display(this, WixErrors.InvalidPlatformParameter(parameter, args[i])); } } else if ('p' == parameter[0]) { String file = arg.Substring(2); this.preprocessFile = file; this.preprocessToStdout = (0 == file.Length); } else if ("sfdvital" == parameter) { this.suppressFilesVitalByDefault = true; } else if ("ss" == parameter) { this.suppressSchema = true; } else if ("swall" == parameter) { this.messageHandler.Display(this, WixWarnings.DeprecatedCommandLineSwitch("swall", "sw")); this.messageHandler.SuppressAllWarnings = true; } else if (parameter.StartsWith("sw", StringComparison.Ordinal)) { string paramArg = parameter.Substring(2); try { if (0 == paramArg.Length) { this.messageHandler.SuppressAllWarnings = true; } else { int suppressWarning = Convert.ToInt32(paramArg, CultureInfo.InvariantCulture.NumberFormat); if (0 >= suppressWarning) { this.messageHandler.Display(this, WixErrors.IllegalSuppressWarningId(paramArg)); } this.messageHandler.SuppressWarningMessage(suppressWarning); } } catch (FormatException) { this.messageHandler.Display(this, WixErrors.IllegalSuppressWarningId(paramArg)); } catch (OverflowException) { this.messageHandler.Display(this, WixErrors.IllegalSuppressWarningId(paramArg)); } } else if ("wxall" == parameter) { this.messageHandler.Display(this, WixWarnings.DeprecatedCommandLineSwitch("wxall", "wx")); this.messageHandler.WarningAsError = true; } else if (parameter.StartsWith("wx", StringComparison.Ordinal)) { string paramArg = parameter.Substring(2); try { if (0 == paramArg.Length) { this.messageHandler.WarningAsError = true; } else { int elevateWarning = Convert.ToInt32(paramArg, CultureInfo.InvariantCulture.NumberFormat); if (0 >= elevateWarning) { this.messageHandler.Display(this, WixErrors.IllegalWarningIdAsError(paramArg)); } this.messageHandler.ElevateWarningMessage(elevateWarning); } } catch (FormatException) { this.messageHandler.Display(this, WixErrors.IllegalWarningIdAsError(paramArg)); } catch (OverflowException) { this.messageHandler.Display(this, WixErrors.IllegalWarningIdAsError(paramArg)); } } else if ("trace" == parameter) { this.messageHandler.SourceTrace = true; } else if ("v" == parameter) { this.messageHandler.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 { string sourceArg = arg; string targetArg = null; if (this.allowPerSourceOutputSpecification) { string[] parts = arg.Split(Candle.sourceOutputSeparator, 2); if (2 == parts.Length) { sourceArg = parts[0]; targetArg = parts[1]; } } string[] files = AppCommon.GetFiles(sourceArg, "Source"); if (this.allowPerSourceOutputSpecification && null != targetArg) { // files should contain only one item! if (1 < files.Length) { string sourceList = CompilerCore.CreateValueList(ValueListKind.None, files); this.messageHandler.Display(this, WixErrors.MultipleFilesMatchedWithOutputSpecification(arg, sourceList)); } else { this.sourceFiles.Add(string.Concat(files[0], Candle.sourceOutputSeparator[0], targetArg)); } } else { this.sourceFiles.AddRange(files); } } } return; }
/// <summary> /// Parses a Tag element for Software Id Tag registration under a Product element. /// </summary> /// <param name="node">The element to parse.</param> private void ParseProductTagElement(XmlNode node) { SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); string name = null; string regid = null; string feature = "WixSwidTag"; YesNoType licensed = YesNoType.NotSet; string type = null;; foreach (XmlAttribute attrib in node.Attributes) { if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace) { switch (attrib.LocalName) { case "Name": name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false); break; case "Regid": regid = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "Feature": feature = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); break; case "Licensed": licensed = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); break; case "Type": type = this.ParseTagTypeAttribute(sourceLineNumbers, node, 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(name)) { XmlAttribute productNameAttribute = node.ParentNode.Attributes["Name"]; if (null != productNameAttribute) { name = productNameAttribute.Value; } else { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Name")); } } if (!String.IsNullOrEmpty(name) && !CompilerCore.IsValidLongFilename(name, false)) { this.Core.OnMessage(TagErrors.IllegalName(sourceLineNumbers, node.ParentNode.LocalName, name)); } if (String.IsNullOrEmpty(regid)) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Regid")); } if (!this.Core.EncounteredError) { string directoryId = "WixTagRegidFolder"; string fileId = this.Core.GenerateIdentifier("tag", regid, ".product.tag"); string fileName = String.Concat(regid, " ", name, ".swidtag"); string shortName = this.Core.GenerateShortName(fileName, false, false); this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "Directory", directoryId); ComponentRow componentRow = (ComponentRow)this.Core.CreateRow(sourceLineNumbers, "Component"); componentRow.Component = fileId; componentRow.Guid = "*"; componentRow[3] = 0; componentRow.Directory = directoryId; componentRow.IsLocalOnly = true; componentRow.KeyPath = fileId; this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "Feature", feature); this.Core.CreateComplexReference(sourceLineNumbers, ComplexReferenceParentType.Feature, feature, null, ComplexReferenceChildType.Component, fileId, true); FileRow fileRow = (FileRow)this.Core.CreateRow(sourceLineNumbers, "File"); fileRow.File = fileId; fileRow.Component = fileId; fileRow.FileName = String.Concat(shortName, "|", fileName); WixFileRow wixFileRow = (WixFileRow)this.Core.CreateRow(sourceLineNumbers, "WixFile"); wixFileRow.Directory = directoryId; wixFileRow.File = fileId; wixFileRow.DiskId = 1; wixFileRow.Attributes = 1; wixFileRow.Source = String.Concat("%TEMP%\\", fileName); this.Core.EnsureTable(sourceLineNumbers, "SoftwareIdentificationTag"); Row row = this.Core.CreateRow(sourceLineNumbers, "WixProductTag"); row[0] = fileId; row[1] = regid; row[2] = name; if (YesNoType.Yes == licensed) { row[3] = 1; } row[4] = type; this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "File", fileId); } }
public LdapFilterCompilerTests() { FilterCompiler = new LdapFilterCompiler(); Core = new CompilerCore(new CompilerOptions()); }
/// <summary> /// Parses a CfgException element. /// </summary> /// <param name="node">The element to parse.</param> private void ParseCfgProductElement(XElement node) { SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); string name = null; string version = null; string publickey = null; string feature = null; foreach (XAttribute attrib in node.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Name": name = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "Version": version = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "PublicKey": publickey = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "Feature": feature = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; default: this.Core.UnexpectedAttribute(sourceLineNumbers, attrib); break; } } else { this.Core.ParseExtensionAttribute(node, attrib); } } // Id and Name are required if (null == name) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); } if (null == version) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version")); } if (null == publickey) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "PublicKey")); } if (null == feature) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Feature")); } this.Core.ParseForExtensionElements(node); if (!this.Core.EncounteredError) { string componentGuid = CompilerCore.NewGuid(CfgConstants.wixCfgGuidNamespace, name + "_" + version + "_" + publickey); string componentId = "Cfg_" + componentGuid.Substring(1, componentGuid.Length - 2).Replace("-", "_"); // Cutoff the curly braces and switch dashes to underscrores to get the componentID string regId = "Reg_" + componentId; Row componentRow = this.Core.CreateRow(sourceLineNumbers, "Component"); componentRow[0] = componentId; componentRow[1] = componentGuid; componentRow[2] = "TARGETDIR"; componentRow[3] = MsidbComponentAttributesRegistryKeyPath; componentRow[4] = ""; componentRow[5] = regId; Row featureComponentRow = this.Core.CreateRow(sourceLineNumbers, "FeatureComponents"); featureComponentRow[0] = feature; featureComponentRow[1] = componentId; Row cfgRow = this.Core.CreateRow(sourceLineNumbers, "WixCfgProducts"); cfgRow[0] = name; cfgRow[1] = version; cfgRow[2] = publickey; cfgRow[3] = componentId; Row regRow = this.Core.CreateRow(sourceLineNumbers, "Registry"); regRow[0] = regId; regRow[1] = MsidbRegistryRootLocalMachine; regRow[2] = "SOFTWARE\\Wix\\SettingsStore\\Products"; regRow[3] = name + ", " + version + ", " + publickey; regRow[4] = "#1"; regRow[5] = componentId; this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "Feature", feature); this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "SchedCfgProductsInstall"); this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "SchedCfgProductsUninstall"); } }
/// <summary> /// Parses a sql database element /// </summary> /// <param name="node">Element to parse.</param> /// <param name="componentId">Identifier for parent component.</param> private void ParseSqlDatabaseElement(XElement node, string componentId) { SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); string id = null; int attributes = 0; string database = null; string fileSpec = null; string instance = null; string logFileSpec = null; string server = null; string user = null; 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 "ConfirmOverwrite": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); } if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= DbConfirmOverwrite; } break; case "ContinueOnError": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); } if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= DbContinueOnError; } break; case "CreateOnInstall": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); } if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= DbCreateOnInstall; } break; case "CreateOnReinstall": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); } if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= DbCreateOnReinstall; } break; case "CreateOnUninstall": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); } if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= DbCreateOnUninstall; } break; case "Database": database = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "DropOnInstall": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); } if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= DbDropOnInstall; } break; case "DropOnReinstall": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); } if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= DbDropOnReinstall; } break; case "DropOnUninstall": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); } if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= DbDropOnUninstall; } break; case "Instance": instance = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "Server": server = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "User": user = this.Core.GetAttributeValue(sourceLineNumbers, attrib); if (!CompilerCore.ContainsProperty(user)) { user = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "User", user); } break; default: this.Core.UnexpectedAttribute(sourceLineNumbers, attrib); break; } } else { this.Core.ParseExtensionAttribute(node, attrib); } } if (null == id) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); } if (null == database) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Database")); } else if (128 < database.Length) { this.Core.OnMessage(WixErrors.IdentifierTooLongError(sourceLineNumbers, node.Name.LocalName, "Database", database, 128)); } if (null == server) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Server")); } if (0 == attributes && null != componentId) { this.Core.OnMessage(SqlErrors.OneOfAttributesRequiredUnderComponent(sourceLineNumbers, node.Name.LocalName, "CreateOnInstall", "CreateOnUninstall", "DropOnInstall", "DropOnUninstall")); } foreach (XElement child in node.Elements()) { if (this.Namespace == child.Name.Namespace) { SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); switch (child.Name.LocalName) { case "SqlScript": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); } this.ParseSqlScriptElement(child, componentId, id); break; case "SqlString": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); } this.ParseSqlStringElement(child, componentId, id); break; case "SqlFileSpec": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); } else if (null != fileSpec) { this.Core.OnMessage(WixErrors.TooManyElements(sourceLineNumbers, node.Name.LocalName, child.Name.LocalName, 1)); } fileSpec = this.ParseSqlFileSpecElement(child); break; case "SqlLogFileSpec": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); } else if (null != logFileSpec) { this.Core.OnMessage(WixErrors.TooManyElements(sourceLineNumbers, node.Name.LocalName, child.Name.LocalName, 1)); } logFileSpec = this.ParseSqlFileSpecElement(child); break; default: this.Core.UnexpectedElement(node, child); break; } } else { this.Core.ParseExtensionElement(node, child); } } if (null != componentId) { // Reference InstallSqlData and UninstallSqlData since nothing will happen without it this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "InstallSqlData"); this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "UninstallSqlData"); } if (!this.Core.EncounteredError) { Row row = this.Core.CreateRow(sourceLineNumbers, "SqlDatabase"); row[0] = id; row[1] = server; row[2] = instance; row[3] = database; row[4] = componentId; row[5] = user; row[6] = fileSpec; row[7] = logFileSpec; if (0 != attributes) { row[8] = attributes; } } }
/// <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; } } }
/// <summary> /// Parses a module element. /// </summary> /// <param name="node">Element to parse.</param> private void ParseModuleElement(XElement node) { var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); var codepage = 0; string moduleId = null; string version = null; var setCodepage = false; var setPackageName = false; var setKeywords = false; var ignoredForMergeModules = false; this.GetDefaultPlatformAndInstallerVersion(out var platform, out var msiVersion); this.activeName = null; this.activeLanguage = null; foreach (var attrib in node.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Id": this.activeName = this.Core.GetAttributeValue(sourceLineNumbers, attrib); if ("PUT-MODULE-NAME-HERE" == this.activeName) { this.Core.Write(WarningMessages.PlaceholderValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, this.activeName)); } else { this.activeName = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); } break; case "Codepage": codepage = this.Core.GetAttributeCodePageValue(sourceLineNumbers, attrib); break; case "Guid": moduleId = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); break; case "InstallerVersion": msiVersion = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, Int32.MaxValue); break; case "Language": this.activeLanguage = this.Core.GetAttributeLocalizableIntegerValue(sourceLineNumbers, attrib, 0, Int16.MaxValue); break; case "Version": version = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib); break; default: this.Core.UnexpectedAttribute(node, attrib); break; } } else { this.Core.ParseExtensionAttribute(node, attrib); } } if (null == this.activeName) { this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); } if (null == moduleId) { this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Guid")); } if (null == this.activeLanguage) { this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Language")); } if (null == version) { this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version")); } else if (!CompilerCore.IsValidModuleOrBundleVersion(version)) { this.Core.Write(WarningMessages.InvalidModuleOrBundleVersion(sourceLineNumbers, "Module", version)); } try { this.compilingModule = true; // notice that we are actually building a Merge Module here this.Core.CreateActiveSection(this.activeName, SectionType.Module, codepage, this.Context.CompilationId); foreach (var child in node.Elements()) { if (CompilerCore.WixNamespace == child.Name.Namespace) { switch (child.Name.LocalName) { case "AdminExecuteSequence": this.ParseSequenceElement(child, SequenceTable.AdminExecuteSequence); break; case "AdminUISequence": this.ParseSequenceElement(child, SequenceTable.AdminUISequence); break; case "AdvertiseExecuteSequence": this.ParseSequenceElement(child, SequenceTable.AdvertiseExecuteSequence); break; case "InstallExecuteSequence": this.ParseSequenceElement(child, SequenceTable.InstallExecuteSequence); break; case "InstallUISequence": this.ParseSequenceElement(child, SequenceTable.InstallUISequence); break; case "AppId": this.ParseAppIdElement(child, null, YesNoType.Yes, null, null, null); break; case "Binary": this.ParseBinaryElement(child); break; case "Component": this.ParseComponentElement(child, ComplexReferenceParentType.Module, this.activeName, this.activeLanguage, CompilerConstants.IntegerNotSet, null, null); break; case "ComponentGroupRef": this.ParseComponentGroupRefElement(child, ComplexReferenceParentType.Module, this.activeName, this.activeLanguage); break; case "ComponentRef": this.ParseComponentRefElement(child, ComplexReferenceParentType.Module, this.activeName, this.activeLanguage); break; case "Configuration": this.ParseConfigurationElement(child); break; case "CustomAction": this.ParseCustomActionElement(child); break; case "CustomActionRef": this.ParseSimpleRefElement(child, SymbolDefinitions.CustomAction); break; case "CustomTable": this.ParseCustomTableElement(child); break; case "CustomTableRef": this.ParseCustomTableRefElement(child); break; case "Dependency": this.ParseDependencyElement(child); break; case "Directory": this.ParseDirectoryElement(child, null, CompilerConstants.IntegerNotSet, String.Empty); break; case "DirectoryRef": this.ParseDirectoryRefElement(child); break; case "EmbeddedChainer": this.ParseEmbeddedChainerElement(child); break; case "EmbeddedChainerRef": this.ParseSimpleRefElement(child, SymbolDefinitions.MsiEmbeddedChainer); break; case "EnsureTable": this.ParseEnsureTableElement(child); break; case "Exclusion": this.ParseExclusionElement(child); break; case "Icon": this.ParseIconElement(child); break; case "IgnoreTable": this.ParseIgnoreTableElement(child); break; case "Property": this.ParsePropertyElement(child); break; case "PropertyRef": this.ParseSimpleRefElement(child, SymbolDefinitions.Property); break; case "SetDirectory": this.ParseSetDirectoryElement(child); break; case "SetProperty": this.ParseSetPropertyElement(child); break; case "SFPCatalog": string parentName = null; this.ParseSFPCatalogElement(child, ref parentName); break; case "Substitution": this.ParseSubstitutionElement(child); break; case "SummaryInformation": this.ParseSummaryInformationElement(child, ref setCodepage, ref setPackageName, ref setKeywords, ref ignoredForMergeModules); break; case "UI": this.ParseUIElement(child); break; case "UIRef": this.ParseSimpleRefElement(child, SymbolDefinitions.WixUI); break; case "WixVariable": this.ParseWixVariableElement(child); break; default: this.Core.UnexpectedElement(node, child); break; } } else { this.Core.ParseExtensionElement(node, child); } } if (!this.Core.EncounteredError) { if (!setCodepage) { this.Core.AddSymbol(new SummaryInformationSymbol(sourceLineNumbers) { PropertyId = SummaryInformationType.Codepage, Value = "1252" }); } if (!setPackageName) { this.Core.AddSymbol(new SummaryInformationSymbol(sourceLineNumbers) { PropertyId = SummaryInformationType.Subject, Value = this.activeName }); } if (!setKeywords) { this.Core.AddSymbol(new SummaryInformationSymbol(sourceLineNumbers) { PropertyId = SummaryInformationType.Keywords, Value = "Installer" }); } var symbol = this.Core.AddSymbol(new ModuleSignatureSymbol(sourceLineNumbers, new Identifier(AccessModifier.Public, this.activeName, this.activeLanguage)) { ModuleID = this.activeName, Version = version }); symbol.Set((int)ModuleSignatureSymbolFields.Language, this.activeLanguage); this.Core.AddSymbol(new SummaryInformationSymbol(sourceLineNumbers) { PropertyId = SummaryInformationType.PackageCode, Value = moduleId }); this.ValidateAndAddCommonSummaryInformationSymbols(sourceLineNumbers, msiVersion, platform); } } finally { this.compilingModule = false; // notice that we are no longer building a Merge Module here } }
/// <summary> /// Parses a Tag element for Software Id Tag registration under a Product element. /// </summary> /// <param name="node">The element to parse.</param> private void ParseProductTagElement(XmlNode node) { SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); string name = null; string regid = null; string feature = "WixSwidTag"; string installDirectory = null; bool win64 = (Platform.IA64 == this.Core.CurrentPlatform || Platform.X64 == this.Core.CurrentPlatform); foreach (XmlAttribute attrib in node.Attributes) { if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace) { switch (attrib.LocalName) { case "Name": name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false); break; case "Regid": regid = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "Feature": feature = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); break; case "InstallDirectory": installDirectory = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); break; case "InstallPath": this.Core.OnMessage(WixErrors.ExpectedParentWithAttribute(sourceLineNumbers, node.Name, attrib.Name, "Bundle")); break; case "Licensed": this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name, attrib.Name)); break; case "Type": this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name, attrib.Name)); break; case "Win64": win64 = (YesNoType.Yes == 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(name)) { XmlAttribute productNameAttribute = node.ParentNode.Attributes["Name"]; if (null != productNameAttribute) { name = productNameAttribute.Value; } else { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Name")); } } if (!String.IsNullOrEmpty(name) && !CompilerCore.IsValidLongFilename(name, false)) { this.Core.OnMessage(TagErrors.IllegalName(sourceLineNumbers, node.ParentNode.LocalName, name)); } if (String.IsNullOrEmpty(regid)) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Regid")); } else if (regid.StartsWith("regid.")) { this.Core.OnMessage(TagWarnings.DeprecatedRegidFormat(sourceLineNumbers, regid)); return; } else if (regid.Equals("example.com", StringComparison.OrdinalIgnoreCase)) { this.Core.OnMessage(TagErrors.ExampleRegid(sourceLineNumbers, regid)); return; } if (String.IsNullOrEmpty(installDirectory)) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "InstallDirectory")); } if (!this.Core.EncounteredError) { string fileId = this.Core.GenerateIdentifier("tag", regid, ".product.tag"); string fileName = String.Concat(name, ".swidtag"); string shortName = this.Core.GenerateShortName(fileName, false, false); Row directoryRow = this.Core.CreateRow(sourceLineNumbers, "Directory"); directoryRow[0] = "WixTagInstallFolder"; directoryRow[1] = installDirectory; directoryRow[2] = "."; this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "Directory", installDirectory); ComponentRow componentRow = (ComponentRow)this.Core.CreateRow(sourceLineNumbers, "Component"); componentRow.Component = fileId; componentRow.Guid = "*"; componentRow[3] = (win64 ? TagCompiler.MsidbComponentAttributes64bit : 0); componentRow.Directory = TagCompiler.TagFolderId; componentRow.IsLocalOnly = true; componentRow.KeyPath = fileId; this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "Directory", TagCompiler.TagFolderId); this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "Feature", feature); this.Core.CreateComplexReference(sourceLineNumbers, ComplexReferenceParentType.Feature, feature, null, ComplexReferenceChildType.Component, fileId, true); FileRow fileRow = (FileRow)this.Core.CreateRow(sourceLineNumbers, "File"); fileRow.File = fileId; fileRow.Component = fileId; fileRow.FileName = String.Concat(shortName, "|", fileName); WixFileRow wixFileRow = (WixFileRow)this.Core.CreateRow(sourceLineNumbers, "WixFile"); wixFileRow.Directory = TagCompiler.TagFolderId; wixFileRow.File = fileId; wixFileRow.DiskId = 1; wixFileRow.Attributes = 1; wixFileRow.Source = fileName; this.Core.EnsureTable(sourceLineNumbers, "SoftwareIdentificationTag"); Row row = this.Core.CreateRow(sourceLineNumbers, "WixProductTag"); row[0] = fileId; row[1] = regid; row[2] = name; this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "File", fileId); } }
private List <Element> construct(string code) { List <string> toks = CompilerCore.AdcancedSplit(code.Trim(' ', '\t', '\r')); //整理代码,中缀运算符改后缀 List <Element> restok = new List <Element>(); Stack <string> elestack = new Stack <string>(); foreach (string data in toks) { if (data.Length == 0) { continue; } Element tmpEle; if (data.Contains("(") && data.Contains(")")) //是函数 { tmpEle = new FunctionElement(data, Element.Function); restok.Add(tmpEle); } else if (data.Contains("[") && data.Contains("]")) //是数组 { tmpEle = new Element(data, Element.Array); restok.Add(tmpEle); } else if (data[0] >= '0' && data[0] <= '9') //是数字 { tmpEle = new Element(data, Element.Number); restok.Add(tmpEle); } else if (data[0] >= 'a' && data[0] <= 'z' || data[0] >= 'A' && data[0] <= 'Z') //是一个变量 { tmpEle = new Element(data, Element.Variable); restok.Add(tmpEle); } else if (data[0] == '"') //是字符串 { tmpEle = new Element(data, Element.String); restok.Add(tmpEle); } else //是符号 { if (elestack.Count == 0 || data == "(") { elestack.Push(data); } else { if (data == ")") { while (elestack.Peek() != "(" && elestack.Count > 0) { restok.Add(new Element(elestack.Pop(), Element.Symbol)); } if (elestack.Count == 0) { throw new SyntaxErrorException("syntax error,the number of '(' and ')' don't match!"); } elestack.Pop(); } else { if (CompilerCore.operator_priority[data] >= CompilerCore.operator_priority[elestack.Peek()]) { elestack.Push(data); } else { if (elestack.Peek() == "(") { elestack.Push(data); } else { while (CompilerCore.operator_priority[data] < CompilerCore.operator_priority[elestack.Peek()] && elestack.Count > 0) { if (elestack.Peek() == "(") { elestack.Pop(); break; } restok.Add(new Element(elestack.Pop(), Element.Symbol)); } elestack.Push(data); } } } } } } //将栈中的剩余运算符按序插入到表达式后面 while (elestack.Count > 0) { if (elestack.Peek() == "(") { elestack.Pop(); continue; } restok.Add(new Element(elestack.Pop(), Element.Symbol)); } return(restok); }
/// <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 (this.messageHandler.EncounteredError) { return(this.messageHandler.LastErrorNumber); } if (!this.fipsCompliant) { try { System.Security.Cryptography.MD5.Create(); } catch (TargetInvocationException) { this.messageHandler.Display(this, WixErrors.UseFipsArgument()); return(this.messageHandler.LastErrorNumber); } } if (0 == this.sourceFiles.Count) { this.showHelp = true; } else if (1 < this.sourceFiles.Count && null != this.outputFile) { throw new ArgumentException(CandleStrings.CannotSpecifyMoreThanOneSourceFileForSingleTargetFile, "-out"); } if (this.showLogo) { AppCommon.DisplayToolHeader(); } if (this.showHelp) { Console.WriteLine(CandleStrings.HelpMessage); AppCommon.DisplayToolFooter(); return(this.messageHandler.LastErrorNumber); } foreach (string parameter in this.invalidArgs) { this.messageHandler.Display(this, WixWarnings.UnsupportedCommandLineArgument(parameter)); } this.invalidArgs = null; // create the preprocessor and compiler Preprocessor preprocessor = new Preprocessor(); preprocessor.Message += new MessageEventHandler(this.messageHandler.Display); for (int i = 0; i < this.includeSearchPaths.Count; ++i) { preprocessor.IncludeSearchPaths.Add(this.includeSearchPaths[i]); } preprocessor.CurrentPlatform = this.platform; Compiler compiler = new Compiler(); compiler.Message += new MessageEventHandler(this.messageHandler.Display); compiler.SuppressFilesVitalByDefault = this.suppressFilesVitalByDefault; compiler.ShowPedanticMessages = this.showPedanticMessages; compiler.SuppressValidate = this.suppressSchema; compiler.CurrentPlatform = this.platform; compiler.FipsCompliant = this.fipsCompliant; // load any extensions foreach (string extension in this.extensionList) { WixExtension wixExtension = WixExtension.Load(extension); preprocessor.AddExtension(wixExtension); compiler.AddExtension(wixExtension); } // preprocess then compile each source file Dictionary <string, List <string> > sourcesForOutput = new Dictionary <string, List <string> >(StringComparer.OrdinalIgnoreCase); foreach (string sourceFileOrig in this.sourceFiles) { string sourceFile = sourceFileOrig; string targetFile = null; if (this.allowPerSourceOutputSpecification) { string[] parts = sourceFileOrig.Split(Candle.sourceOutputSeparator, 2); if (2 == parts.Length) { sourceFile = parts[0]; targetFile = parts[1]; } } string sourceFilePath = Path.GetFullPath(sourceFile); string sourceFileName = Path.GetFileName(sourceFile); if (null == targetFile) { if (null != this.outputFile) { targetFile = this.outputFile; } else if (null != this.outputDirectory) { targetFile = Path.Combine(this.outputDirectory, Path.ChangeExtension(sourceFileName, ".wixobj")); } else { targetFile = Path.ChangeExtension(sourceFileName, ".wixobj"); } } else if (!Path.IsPathRooted(targetFile) && null != this.outputDirectory) { targetFile = Path.Combine(this.outputDirectory, targetFile); } // print friendly message saying what file is being compiled Console.WriteLine(sourceFileName); // preprocess the source XmlDocument sourceDocument; try { if (this.preprocessToStdout) { preprocessor.PreprocessOut = Console.Out; } else if (null != this.preprocessFile) { preprocessor.PreprocessOut = new StreamWriter(this.preprocessFile); } sourceDocument = preprocessor.Process(sourceFilePath, this.parameters); } finally { if (null != preprocessor.PreprocessOut && Console.Out != preprocessor.PreprocessOut) { preprocessor.PreprocessOut.Close(); } } // if we're not actually going to compile anything, move on to the next file if (null == sourceDocument || this.preprocessToStdout || null != this.preprocessFile) { continue; } // and now we do what we came here to do... Intermediate intermediate = compiler.Compile(sourceDocument); // save the intermediate to disk if no errors were found for this source file if (null != intermediate) { intermediate.Save(targetFile); } // Track which source files result in a given output file, to ensure we aren't // overwriting the output. List <string> sources = null; string targetPath = Path.GetFullPath(targetFile); if (!sourcesForOutput.TryGetValue(targetPath, out sources)) { sources = new List <string>(); sourcesForOutput.Add(targetPath, sources); } sources.Add(sourceFile); } // Show an error for every output file that had more than 1 source file. foreach (KeyValuePair <string, List <string> > outputSources in sourcesForOutput) { if (1 < outputSources.Value.Count) { string sourceFiles = CompilerCore.CreateValueList(ValueListKind.None, outputSources.Value); this.messageHandler.Display(this, WixErrors.DuplicateSourcesForOutput(sourceFiles, outputSources.Key)); } } } catch (WixException we) { this.messageHandler.Display(this, we.Error); } catch (Exception e) { this.messageHandler.Display(this, WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace)); if (e is NullReferenceException || e is SEHException) { throw; } } return(this.messageHandler.LastErrorNumber); }
/// <summary> /// Parses a Tag element for Software Id Tag registration under a Bundle element. /// </summary> /// <param name="node">The element to parse.</param> private void ParseBundleTagElement(XmlNode node) { SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); string name = null; string regid = null; string installPath = null; foreach (XmlAttribute attrib in node.Attributes) { if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace) { switch (attrib.LocalName) { case "Name": name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false); break; case "Regid": regid = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "InstallDirectory": case "Win64": this.Core.OnMessage(WixErrors.ExpectedParentWithAttribute(sourceLineNumbers, node.Name, attrib.Name, "Product")); break; case "InstallPath": installPath = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "Licensed": this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name, attrib.Name)); break; case "Type": this.Core.OnMessage(WixWarnings.DeprecatedAttribute(sourceLineNumbers, node.Name, attrib.Name)); 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(name)) { XmlAttribute productNameAttribute = node.ParentNode.Attributes["Name"]; if (null != productNameAttribute) { name = productNameAttribute.Value; } else { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Name")); } } if (!String.IsNullOrEmpty(name) && !CompilerCore.IsValidLongFilename(name, false)) { this.Core.OnMessage(TagErrors.IllegalName(sourceLineNumbers, node.ParentNode.LocalName, name)); } if (String.IsNullOrEmpty(regid)) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Regid")); } else if (regid.StartsWith("regid.")) { this.Core.OnMessage(TagWarnings.DeprecatedRegidFormat(sourceLineNumbers, regid)); return; } else if (regid.Equals("example.com", StringComparison.OrdinalIgnoreCase)) { this.Core.OnMessage(TagErrors.ExampleRegid(sourceLineNumbers, regid)); return; } if (String.IsNullOrEmpty(installPath)) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "InstallPath")); } if (!this.Core.EncounteredError) { string fileName = String.Concat(name, ".swidtag"); Row tagRow = this.Core.CreateRow(sourceLineNumbers, "WixBundleTag"); tagRow[0] = fileName; tagRow[1] = regid; tagRow[2] = name; tagRow[3] = installPath; } }