@joebigelow / wix / commits / 860f77f7

Introduce "Subdirectory" which simplifies inline directory syntax

Completes wixtoolset/issues#4727

Rob Mensching committed Apr 5, 2021 at 12:55 UTC 860f77f7c9d522074dc7e44cfe11281efd20687f
19 files changed +346 -283
src/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs
+51 -7
@@ -18,6 +18,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
18
19 internal class CreateWindowsInstallerDataFromIRCommand
20 {
21 + private static readonly char[] PathSeparatorChars = new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar };
22 +
23 public CreateWindowsInstallerDataFromIRCommand(IMessaging messaging, IntermediateSection section, TableDefinitionCollection tableDefinitions, int codepage, IEnumerable<IWindowsInstallerBackendBinderExtension> backendExtensions, IWindowsInstallerBackendHelper backendHelper)
24 {
25 this.Messaging = messaging;
@@ -488,18 +490,23 @@ namespace WixToolset.Core.WindowsInstaller.Bind
490
491 private void AddDirectorySymbol(DirectorySymbol symbol)
492 {
491 - if (String.IsNullOrEmpty(symbol.ShortName) && symbol.Name != null && !symbol.Name.Equals(".") && !symbol.Name.Equals("SourceDir") && !this.BackendHelper.IsValidShortFilename(symbol.Name, false))
493 + (var name, var parentDir) = this.AddDirectorySubdirectories(symbol);
494 +
495 + var shortName = symbol.ShortName;
496 + var sourceShortname = symbol.SourceShortName;
497 +
498 + if (String.IsNullOrEmpty(shortName) && name != null && name != "." && name != "SourceDir" && !this.BackendHelper.IsValidShortFilename(name, false))
499 {
493 - symbol.ShortName = this.CreateShortName(symbol.Name, false, "Directory", symbol.ParentDirectoryRef);
500 + shortName = this.CreateShortName(name, false, "Directory", symbol.ParentDirectoryRef);
501 }
502
496 - if (String.IsNullOrEmpty(symbol.SourceShortName) && !String.IsNullOrEmpty(symbol.SourceName) && !this.BackendHelper.IsValidShortFilename(symbol.SourceName, false))
503 + if (String.IsNullOrEmpty(sourceShortname) && !String.IsNullOrEmpty(symbol.SourceName) && !this.BackendHelper.IsValidShortFilename(symbol.SourceName, false))
504 {
498 - symbol.SourceShortName = this.CreateShortName(symbol.SourceName, false, "Directory", symbol.ParentDirectoryRef);
505 + sourceShortname = this.CreateShortName(symbol.SourceName, false, "Directory", symbol.ParentDirectoryRef);
506 }
507
501 - var sourceName = CreateMsiFilename(symbol.SourceShortName, symbol.SourceName);
502 - var targetName = CreateMsiFilename(symbol.ShortName, symbol.Name);
508 + var sourceName = CreateMsiFilename(sourceShortname, symbol.SourceName);
509 + var targetName = CreateMsiFilename(shortName, name);
510
511 if (String.IsNullOrEmpty(targetName))
512 {
@@ -510,7 +517,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
517
518 var row = this.CreateRow(symbol, "Directory");
519 row[0] = symbol.Id.Id;
513 - row[1] = symbol.ParentDirectoryRef;
520 + row[1] = parentDir;
521 row[2] = defaultDir;
522
523 if (OutputType.Module == this.Data.Type)
@@ -1267,6 +1274,43 @@ namespace WixToolset.Core.WindowsInstaller.Bind
1274 }
1275 }
1276
1277 + private (string, string) AddDirectorySubdirectories(DirectorySymbol symbol)
1278 + {
1279 + var directory = symbol.Name.Trim(PathSeparatorChars);
1280 + var parentDir = symbol.ParentDirectoryRef ?? (symbol.Id.Id == "TARGETDIR" ? null : "TARGETDIR");
1281 +
1282 + var start = 0;
1283 + var end = directory.IndexOfAny(PathSeparatorChars);
1284 + var path = String.Empty;
1285 +
1286 + while (start <= end)
1287 + {
1288 + var subdirectoryName = directory.Substring(start, end - start);
1289 +
1290 + if (!String.IsNullOrEmpty(subdirectoryName))
1291 + {
1292 + path = Path.Combine(path, subdirectoryName);
1293 +
1294 + var id = this.BackendHelper.GenerateIdentifier("d", symbol.ParentDirectoryRef, path);
1295 + var shortnameSubdirectory = this.BackendHelper.IsValidShortFilename(subdirectoryName, false) ? null : this.CreateShortName(subdirectoryName, false, "Directory", symbol.ParentDirectoryRef);
1296 +
1297 + var subdirectoryRow = this.CreateRow(symbol, "Directory");
1298 + subdirectoryRow[0] = id;
1299 + subdirectoryRow[1] = parentDir;
1300 + subdirectoryRow[2] = CreateMsiFilename(shortnameSubdirectory, subdirectoryName);
1301 +
1302 + parentDir = id;
1303 + }
1304 +
1305 + start = end + 1;
1306 + end = symbol.Name.IndexOfAny(PathSeparatorChars, start);
1307 + }
1308 +
1309 + var name = (start == 0) ? directory : directory.Substring(start);
1310 +
1311 + return (name, parentDir);
1312 + }
1313 +
1314 private void EnsureRequiredTables()
1315 {
1316 // check for missing table and add them or display an error as appropriate
src/WixToolset.Core/Compiler.cs
+112 -87
@@ -5,7 +5,6 @@ namespace WixToolset.Core
5 using System;
6 using System.Collections.Generic;
7 using System.Diagnostics;
8 - using System.Diagnostics.CodeAnalysis;
8 using System.Globalization;
9 using System.IO;
10 using System.Linq;
@@ -2107,6 +2106,7 @@ namespace WixToolset.Core
2106
2107 var comPlusBits = CompilerConstants.IntegerNotSet;
2108 string condition = null;
2109 + string subdirectory = null;
2110 var encounteredODBCDataSource = false;
2111 var files = 0;
2112 var guid = "*";
@@ -2163,16 +2163,16 @@ namespace WixToolset.Core
2163 break;
2164 case "DisableRegistryReflection":
2165 disableRegistryReflection = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2166 - //if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2167 - //{
2168 - // bits |= MsiInterop.MsidbComponentAttributesDisableRegistryReflection;
2169 - //}
2166 break;
2167 case "Condition":
2168 condition = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2169 break;
2170 case "Directory":
2175 - directoryId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, directoryId);
2171 + directoryId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2172 + this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, directoryId);
2173 + break;
2174 + case "Subdirectory":
2175 + subdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
2176 break;
2177 case "DiskId":
2178 diskId = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, Int16.MaxValue);
@@ -2196,14 +2196,12 @@ namespace WixToolset.Core
2196 {
2197 case "either":
2198 location = ComponentLocation.Either;
2199 - //bits |= MsiInterop.MsidbComponentAttributesOptional;
2199 break;
2200 case "local": // this is the default
2201 location = ComponentLocation.LocalOnly;
2202 break;
2203 case "source":
2204 location = ComponentLocation.SourceOnly;
2206 - //bits |= MsiInterop.MsidbComponentAttributesSourceOnly;
2205 break;
2206 case "":
2207 break;
@@ -2217,45 +2215,21 @@ namespace WixToolset.Core
2215 break;
2216 case "NeverOverwrite":
2217 neverOverwrite = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2220 - //if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2221 - //{
2222 - // bits |= MsiInterop.MsidbComponentAttributesNeverOverwrite;
2223 - //}
2218 break;
2219 case "Permanent":
2220 permanent = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2227 - //if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2228 - //{
2229 - // bits |= MsiInterop.MsidbComponentAttributesPermanent;
2230 - //}
2221 break;
2222 case "Shared":
2223 shared = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2234 - //if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2235 - //{
2236 - // bits |= MsiInterop.MsidbComponentAttributesShared;
2237 - //}
2224 break;
2225 case "SharedDllRefCount":
2226 sharedDllRefCount = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2241 - //if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2242 - //{
2243 - // bits |= MsiInterop.MsidbComponentAttributesSharedDllRefCount;
2244 - //}
2227 break;
2228 case "Transitive":
2229 transitive = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2248 - //if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2249 - //{
2250 - // bits |= MsiInterop.MsidbComponentAttributesTransitive;
2251 - //}
2230 break;
2231 case "UninstallWhenSuperseded":
2232 uninstallWhenSuperseded = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2255 - //if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
2256 - //{
2257 - // bits |= MsiInterop.MsidbComponentAttributesUninstallOnSupersedence;
2258 - //}
2233 break;
2234 default:
2235 this.Core.UnexpectedAttribute(node, attrib);
@@ -2275,17 +2249,22 @@ namespace WixToolset.Core
2249 id = new Identifier(AccessModifier.Section, componentIdPlaceholder);
2250 }
2251
2278 - if (null == directoryId)
2252 + if (String.IsNullOrEmpty(directoryId))
2253 {
2254 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Directory"));
2255 }
2256
2283 - if (String.IsNullOrEmpty(guid) && shared /*MsiInterop.MsidbComponentAttributesShared == (bits & MsiInterop.MsidbComponentAttributesShared)*/)
2257 + if (!String.IsNullOrEmpty(subdirectory))
2258 + {
2259 + directoryId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, directoryId, subdirectory);
2260 + }
2261 +
2262 + if (String.IsNullOrEmpty(guid) && shared)
2263 {
2264 this.Core.Write(ErrorMessages.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Shared", "yes", "Guid", ""));
2265 }
2266
2288 - if (String.IsNullOrEmpty(guid) && permanent /*MsiInterop.MsidbComponentAttributesPermanent == (bits & MsiInterop.MsidbComponentAttributesPermanent)*/)
2267 + if (String.IsNullOrEmpty(guid) && permanent)
2268 {
2269 this.Core.Write(ErrorMessages.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Permanent", "yes", "Guid", ""));
2270 }
@@ -2587,6 +2566,7 @@ namespace WixToolset.Core
2566 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
2567 Identifier id = null;
2568 string directoryId = null;
2569 + string subdirectory = null;
2570 string source = null;
2571
2572 foreach (var attrib in node.Attributes())
@@ -2599,9 +2579,11 @@ namespace WixToolset.Core
2579 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
2580 break;
2581 case "Directory":
2602 - // If the inline syntax is invalid it returns null. Use a static error identifier so the null
2603 - // directory identifier here doesn't trickle down false errors into child elements.
2604 - directoryId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null) ?? "ErrorParsingInlineSyntax";
2582 + directoryId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2583 + this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, directoryId);
2584 + break;
2585 + case "Subdirectory":
2586 + subdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
2587 break;
2588 case "Source":
2589 source = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
@@ -2623,6 +2605,8 @@ namespace WixToolset.Core
2605 id = Identifier.Invalid;
2606 }
2607
2608 + directoryId = this.HandleSubdirectory(sourceLineNumbers, node, directoryId, subdirectory, "Directory", "Subdirectory");
2609 +
2610 if (!String.IsNullOrEmpty(source) && !source.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
2611 {
2612 source = String.Concat(source, Path.DirectorySeparatorChar);
@@ -2898,18 +2882,24 @@ namespace WixToolset.Core
2882 private string ParseCreateFolderElement(XElement node, string componentId, string directoryId, bool win64Component)
2883 {
2884 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
2885 + string subdirectory = null;
2886 +
2887 foreach (var attrib in node.Attributes())
2888 {
2889 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
2890 {
2891 switch (attrib.Name.LocalName)
2892 {
2907 - case "Directory":
2908 - directoryId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, directoryId);
2909 - break;
2910 - default:
2911 - this.Core.UnexpectedAttribute(node, attrib);
2912 - break;
2893 + case "Directory":
2894 + directoryId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2895 + this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, directoryId);
2896 + break;
2897 + case "Subdirectory":
2898 + subdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
2899 + break;
2900 + default:
2901 + this.Core.UnexpectedAttribute(node, attrib);
2902 + break;
2903 }
2904 }
2905 else
@@ -2918,24 +2908,26 @@ namespace WixToolset.Core
2908 }
2909 }
2910
2911 + directoryId = this.HandleSubdirectory(sourceLineNumbers, node, directoryId, subdirectory, "Directory", "Subdirectory");
2912 +
2913 foreach (var child in node.Elements())
2914 {
2915 if (CompilerCore.WixNamespace == child.Name.Namespace)
2916 {
2917 switch (child.Name.LocalName)
2918 {
2927 - case "Shortcut":
2928 - this.ParseShortcutElement(child, componentId, node.Name.LocalName, directoryId, YesNoType.No);
2929 - break;
2930 - case "Permission":
2931 - this.ParsePermissionElement(child, directoryId, "CreateFolder");
2932 - break;
2933 - case "PermissionEx":
2934 - this.ParsePermissionExElement(child, directoryId, "CreateFolder");
2935 - break;
2936 - default:
2937 - this.Core.UnexpectedElement(node, child);
2938 - break;
2919 + case "Shortcut":
2920 + this.ParseShortcutElement(child, componentId, node.Name.LocalName, directoryId, YesNoType.No);
2921 + break;
2922 + case "Permission":
2923 + this.ParsePermissionElement(child, directoryId, "CreateFolder");
2924 + break;
2925 + case "PermissionEx":
2926 + this.ParsePermissionExElement(child, directoryId, "CreateFolder");
2927 + break;
2928 + default:
2929 + this.Core.UnexpectedElement(node, child);
2930 + break;
2931 }
2932 }
2933 else
@@ -2969,10 +2961,12 @@ namespace WixToolset.Core
2961 Identifier id = null;
2962 var delete = false;
2963 string destinationDirectory = null;
2964 + string destinationSubdirectory = null;
2965 string destinationName = null;
2966 string destinationShortName = null;
2967 string destinationProperty = null;
2968 string sourceDirectory = null;
2969 + string sourceSubdirectory = null;
2970 string sourceFolder = null;
2971 string sourceName = null;
2972 string sourceProperty = null;
@@ -2990,16 +2984,20 @@ namespace WixToolset.Core
2984 delete = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2985 break;
2986 case "DestinationDirectory":
2993 - destinationDirectory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null);
2987 + destinationDirectory = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2988 + this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, destinationDirectory);
2989 + break;
2990 + case "DestinationSubdirectory":
2991 + destinationSubdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
2992 break;
2993 case "DestinationName":
2996 - destinationName = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false);
2994 + destinationName = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib);
2995 break;
2996 case "DestinationProperty":
2997 destinationProperty = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2998 break;
2999 case "DestinationShortName":
3002 - destinationShortName = this.Core.GetAttributeShortFilename(sourceLineNumbers, attrib, false);
3000 + destinationShortName = this.Core.GetAttributeShortFilename(sourceLineNumbers, attrib);
3001 break;
3002 case "FileId":
3003 if (null != fileId)
@@ -3010,7 +3008,11 @@ namespace WixToolset.Core
3008 this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.File, fileId);
3009 break;
3010 case "SourceDirectory":
3013 - sourceDirectory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null);
3011 + sourceDirectory = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3012 + this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, sourceDirectory);
3013 + break;
3014 + case "SourceSubdirectory":
3015 + sourceSubdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
3016 break;
3017 case "SourceName":
3018 sourceName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
@@ -3044,11 +3046,15 @@ namespace WixToolset.Core
3046 this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "SourceProperty", "SourceDirectory"));
3047 }
3048
3049 + sourceDirectory = this.HandleSubdirectory(sourceLineNumbers, node, sourceDirectory, sourceSubdirectory, "SourceDirectory", "SourceSubdirectory");
3050 +
3051 if (null != destinationDirectory && null != destinationProperty) // DestinationDirectory and DestinationProperty cannot coexist
3052 {
3053 this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DestinationProperty", "DestinationDirectory"));
3054 }
3055
3056 + destinationDirectory = this.HandleSubdirectory(sourceLineNumbers, node, destinationDirectory, destinationSubdirectory, "DestinationDirectory", "DestinationSubdirectory");
3057 +
3058 if (null == id)
3059 {
3060 id = this.Core.CreateIdentifier("cf", sourceFolder, sourceDirectory, sourceProperty, destinationDirectory, destinationProperty, destinationName);
@@ -3139,6 +3145,7 @@ namespace WixToolset.Core
3145 var explicitWin64 = false;
3146
3147 string scriptFile = null;
3148 + string subdirectory = null;
3149
3150 CustomActionSourceType? sourceType = null;
3151 CustomActionTargetType? targetType = null;
@@ -3194,8 +3201,9 @@ namespace WixToolset.Core
3201 {
3202 this.Core.Write(ErrorMessages.CustomActionMultipleSources(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "BinaryKey", "Directory", "FileRef", "Property", "Script"));
3203 }
3197 - source = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null);
3204 + source = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
3205 sourceType = CustomActionSourceType.Directory;
3206 + this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, source);
3207 break;
3208 case "DllEntry":
3209 if (null != target)
@@ -3355,6 +3363,9 @@ namespace WixToolset.Core
3363 case "ScriptSourceFile":
3364 scriptFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
3365 break;
3366 + case "Subdirectory":
3367 + subdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
3368 + break;
3369 case "SuppressModularization":
3370 suppressModularization = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
3371 break;
@@ -3399,6 +3410,18 @@ namespace WixToolset.Core
3410 win64 = true;
3411 }
3412
3413 + if (!String.IsNullOrEmpty(subdirectory))
3414 + {
3415 + if (sourceType == CustomActionSourceType.Directory)
3416 + {
3417 + source = this.HandleSubdirectory(sourceLineNumbers, node, source, subdirectory, "Directory", "Subdirectory");
3418 + }
3419 + else
3420 + {
3421 + this.Core.Write(ErrorMessages.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "Subdirectory", "Directory"));
3422 + }
3423 + }
3424 +
3425 // if we have an in-lined Script CustomAction ensure no source or target attributes were provided
3426 if (inlineScript)
3427 {
@@ -4168,7 +4191,6 @@ namespace WixToolset.Core
4191 var fileSourceAttribSet = false;
4192 XAttribute nameAttribute = null;
4193 var name = "."; // default to parent directory.
4171 - string inlineSyntax = null;
4194 string shortName = null;
4195 string sourceName = null;
4196 string shortSourceName = null;
@@ -4194,7 +4216,7 @@ namespace WixToolset.Core
4216 fileSourceAttribSet = true;
4217 break;
4218 case "Name":
4197 - name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
4219 + name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
4220 nameAttribute = attrib;
4221 break;
4222 case "ShortName":
@@ -4268,37 +4290,22 @@ namespace WixToolset.Core
4290 }
4291 }
4292
4271 - // Create the directory rows for the inline.
4272 - if (nameAttribute != null)
4293 + if (null == id)
4294 {
4274 - var lastSlash = name.LastIndexOf('\\');
4275 - if (lastSlash > 0)
4276 - {
4277 - inlineSyntax = name;
4278 - name = inlineSyntax.Substring(lastSlash + 1);
4279 -
4280 - parentId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, nameAttribute, parentId, inlineSyntax.Substring(0, lastSlash));
4281 -
4282 - if (!this.Core.IsValidLongFilename(name, false, false))
4283 - {
4284 - this.Messaging.Write(ErrorMessages.IllegalLongFilename(sourceLineNumbers, node.Name.LocalName, nameAttribute.Name.LocalName, nameAttribute.Value, name));
4285 - }
4286 - }
4295 + id = this.Core.CreateIdentifier("d", parentId, name, shortName, sourceName, shortSourceName);
4296 }
4288 -
4289 - if (null == id)
4297 + else if (WindowsInstallerStandard.IsStandardDirectory(id.Id))
4298 {
4291 - id = this.Core.CreateIdentifier("dir", parentId, name, shortName, sourceName, shortSourceName);
4292 -
4293 - if (!String.IsNullOrEmpty(inlineSyntax))
4299 + if (String.IsNullOrEmpty(sourceName))
4300 {
4295 - this.Core.AddInlineDirectoryId(inlineSyntax, id.Id);
4301 + this.Core.Write(CompilerWarnings.DefiningStandardDirectoryDeprecated(sourceLineNumbers, id.Id));
4302 }
4297 - }
4298 - else if ("TARGETDIR".Equals(id.Id, StringComparison.Ordinal) && !("SourceDir".Equals(name, StringComparison.Ordinal) && shortName == null && shortSourceName == null && sourceName == null))
4303 +
4304 + if (id.Id == "TARGETDIR" && name != "SourceDir" && shortName == null && shortSourceName == null && sourceName == null)
4305 {
4306 this.Core.Write(ErrorMessages.IllegalTargetDirDefaultDir(sourceLineNumbers, name));
4307 }
4308 + }
4309
4310 // Update the file source path appropriately.
4311 if (fileSourceAttribSet)
@@ -4761,7 +4768,8 @@ namespace WixToolset.Core
4768 disallowAdvertise = (this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib) == YesNoType.No);
4769 break;
4770 case "ConfigurableDirectory":
4764 - configurableDirectory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null);
4771 + configurableDirectory = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
4772 + this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, configurableDirectory);
4773 break;
4774 case "Description":
4775 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
@@ -8403,5 +8411,22 @@ namespace WixToolset.Core
8411 }
8412 }
8413 }
8414 +
8415 + private string HandleSubdirectory(SourceLineNumber sourceLineNumbers, XElement element, string directoryId, string subdirectory, string directoryAttributeName, string subdirectoryAttributename)
8416 + {
8417 + if (!String.IsNullOrEmpty(subdirectory))
8418 + {
8419 + if (String.IsNullOrEmpty(directoryId))
8420 + {
8421 + this.Core.Write(ErrorMessages.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, element.Name.LocalName, subdirectoryAttributename, directoryAttributeName));
8422 + }
8423 + else
8424 + {
8425 + directoryId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, directoryId, subdirectory);
8426 + }
8427 + }
8428 +
8429 + return directoryId;
8430 + }
8431 }
8432 }
src/WixToolset.Core/CompilerCore.cs
+3 -14
@@ -386,13 +386,12 @@ namespace WixToolset.Core
386 /// Creates directories using the inline directory syntax.
387 /// </summary>
388 /// <param name="sourceLineNumbers">Source line information.</param>
389 - /// <param name="attribute">Attribute containing the inline syntax.</param>
389 /// <param name="parentId">Optional identifier of parent directory.</param>
390 /// <param name="inlineSyntax">Optional inline syntax to override attribute's value.</param>
391 /// <returns>Identifier of the leaf directory created.</returns>
393 - public string CreateDirectoryReferenceFromInlineSyntax(SourceLineNumber sourceLineNumbers, XAttribute attribute, string parentId, string inlineSyntax = null)
392 + public string CreateDirectoryReferenceFromInlineSyntax(SourceLineNumber sourceLineNumbers, string parentId, string inlineSyntax = null)
393 {
395 - return this.parseHelper.CreateDirectoryReferenceFromInlineSyntax(this.ActiveSection, sourceLineNumbers, attribute, parentId, inlineSyntax, this.activeSectionCachedInlinedDirectoryIds);
394 + return this.parseHelper.CreateDirectoryReferenceFromInlineSyntax(this.ActiveSection, sourceLineNumbers, attribute: null, parentId, inlineSyntax, this.activeSectionCachedInlinedDirectoryIds);
395 }
396
397 /// <summary>
@@ -784,7 +783,7 @@ namespace WixToolset.Core
783 /// <param name="attribute">The attribute containing the value to get.</param>
784 /// <param name="allowWildcards">true if wildcards are allowed in the filename.</param>
785 /// <returns>The attribute's short filename value.</returns>
787 - public string GetAttributeShortFilename(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool allowWildcards)
786 + public string GetAttributeShortFilename(SourceLineNumber sourceLineNumbers, XAttribute attribute, bool allowWildcards = false)
787 {
788 if (null == attribute)
789 {
@@ -1021,16 +1020,6 @@ namespace WixToolset.Core
1020 }
1021 }
1022
1024 - /// <summary>
1025 - /// Adds inline directory syntax generated identifier.
1026 - /// </summary>
1027 - /// <param name="inlineSyntax">Inline directory syntax the identifier was generated.</param>
1028 - /// <param name="id">Generated identifier for inline syntax.</param>
1029 - internal void AddInlineDirectoryId(string inlineSyntax, string id)
1030 - {
1031 - this.activeSectionCachedInlinedDirectoryIds.Add(inlineSyntax, id);
1032 - }
1033 -
1023 /// <summary>
1024 /// Creates a new section and makes it the active section in the core.
1025 /// </summary>
src/WixToolset.Core/Compiler_Package.cs
+85 -31
@@ -2146,11 +2146,12 @@ namespace WixToolset.Core
2146 {
2147 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
2148 Identifier id = null;
2149 - string directory = null;
2149 + string directoryId = null;
2150 + string subdirectory = null;
2151 string name = null;
2152 bool? onInstall = null;
2153 bool? onUninstall = null;
2153 - string property = null;
2154 + string propertyId = null;
2155 string shortName = null;
2156
2157 foreach (var attrib in node.Attributes())
@@ -2163,7 +2164,11 @@ namespace WixToolset.Core
2164 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
2165 break;
2166 case "Directory":
2166 - directory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, parentDirectory);
2167 + directoryId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2168 + this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, directoryId);
2169 + break;
2170 + case "Subdirectory":
2171 + directoryId = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
2172 break;
2173 case "Name":
2174 name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, true);
@@ -2185,7 +2190,7 @@ namespace WixToolset.Core
2190 }
2191 break;
2192 case "Property":
2188 - property = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2193 + propertyId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2194 break;
2195 case "ShortName":
2196 shortName = this.Core.GetAttributeShortFilename(sourceLineNumbers, attrib, true);
@@ -2211,15 +2216,23 @@ namespace WixToolset.Core
2216 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "On"));
2217 }
2218
2214 - if (null != directory && null != property)
2219 + if (String.IsNullOrEmpty(propertyId))
2220 + {
2221 + directoryId = this.HandleSubdirectory(sourceLineNumbers, node, directoryId ?? parentDirectory, subdirectory, "Directory", "Subdirectory");
2222 + }
2223 + else if (!String.IsNullOrEmpty(directoryId))
2224 + {
2225 + this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Property", "Directory", directoryId));
2226 + }
2227 + else if (!String.IsNullOrEmpty(subdirectory))
2228 {
2216 - this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Property", "Directory", directory));
2229 + this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Property", "Subdirectory", subdirectory));
2230 }
2231
2232 if (null == id)
2233 {
2234 var on = (onInstall == true && onUninstall == true) ? 3 : (onUninstall == true) ? 2 : (onInstall == true) ? 1 : 0;
2222 - id = this.Core.CreateIdentifier("rmf", directory ?? property ?? parentDirectory, LowercaseOrNull(shortName), LowercaseOrNull(name), on.ToString());
2235 + id = this.Core.CreateIdentifier("rmf", directoryId ?? propertyId ?? parentDirectory, LowercaseOrNull(shortName), LowercaseOrNull(name), on.ToString());
2236 }
2237
2238 this.Core.ParseForExtensionElements(node);
@@ -2231,7 +2244,7 @@ namespace WixToolset.Core
2244 ComponentRef = componentId,
2245 FileName = name,
2246 ShortFileName = shortName,
2234 - DirPropertyRef = directory ?? property ?? parentDirectory,
2247 + DirPropertyRef = directoryId ?? propertyId ?? parentDirectory,
2248 OnInstall = onInstall,
2249 OnUninstall = onUninstall,
2250 });
@@ -2248,10 +2261,11 @@ namespace WixToolset.Core
2261 {
2262 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
2263 Identifier id = null;
2251 - string directory = null;
2264 + string directoryId = null;
2265 + string subdirectory = null;
2266 bool? onInstall = null;
2267 bool? onUninstall = null;
2254 - string property = null;
2268 + string propertyId = null;
2269
2270 foreach (var attrib in node.Attributes())
2271 {
@@ -2263,7 +2277,11 @@ namespace WixToolset.Core
2277 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
2278 break;
2279 case "Directory":
2266 - directory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, parentDirectory);
2280 + directoryId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2281 + this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, directoryId);
2282 + break;
2283 + case "Subdirectory":
2284 + subdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
2285 break;
2286 case "On":
2287 var onValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
@@ -2282,7 +2300,7 @@ namespace WixToolset.Core
2300 }
2301 break;
2302 case "Property":
2285 - property = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2303 + propertyId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2304 break;
2305 default:
2306 this.Core.UnexpectedAttribute(node, attrib);
@@ -2300,15 +2318,23 @@ namespace WixToolset.Core
2318 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "On"));
2319 }
2320
2303 - if (null != directory && null != property)
2321 + if (String.IsNullOrEmpty(propertyId))
2322 + {
2323 + directoryId = this.HandleSubdirectory(sourceLineNumbers, node, directoryId ?? parentDirectory, subdirectory, "Directory", "Subdirectory");
2324 + }
2325 + else if (!String.IsNullOrEmpty(directoryId))
2326 + {
2327 + this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Property", "Directory", directoryId));
2328 + }
2329 + else if (!String.IsNullOrEmpty(subdirectory))
2330 {
2305 - this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Property", "Directory", directory));
2331 + this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Property", "Subdirectory", subdirectory));
2332 }
2333
2334 if (null == id)
2335 {
2336 var on = (onInstall == true && onUninstall == true) ? 3 : (onUninstall == true) ? 2 : (onInstall == true) ? 1 : 0;
2311 - id = this.Core.CreateIdentifier("rmf", directory ?? property ?? parentDirectory, on.ToString());
2337 + id = this.Core.CreateIdentifier("rmf", directoryId ?? propertyId, on.ToString());
2338 }
2339
2340 this.Core.ParseForExtensionElements(node);
@@ -2318,7 +2344,7 @@ namespace WixToolset.Core
2344 this.Core.AddSymbol(new RemoveFileSymbol(sourceLineNumbers, id)
2345 {
2346 ComponentRef = componentId,
2321 - DirPropertyRef = directory ?? property ?? parentDirectory,
2347 + DirPropertyRef = directoryId ?? propertyId,
2348 OnInstall = onInstall,
2349 OnUninstall = onUninstall
2350 });
@@ -2335,6 +2361,7 @@ namespace WixToolset.Core
2361 {
2362 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
2363 Identifier id = null;
2364 + string subdirectory = null;
2365 var runFromSource = CompilerConstants.IntegerNotSet;
2366 var runLocal = CompilerConstants.IntegerNotSet;
2367
@@ -2348,7 +2375,11 @@ namespace WixToolset.Core
2375 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
2376 break;
2377 case "Directory":
2351 - directoryId = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, directoryId);
2378 + directoryId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
2379 + this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, directoryId);
2380 + break;
2381 + case "Subdirectory":
2382 + subdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
2383 break;
2384 case "RunFromSource":
2385 runFromSource = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, Int32.MaxValue);
@@ -2367,6 +2398,8 @@ namespace WixToolset.Core
2398 }
2399 }
2400
2401 + directoryId = this.HandleSubdirectory(sourceLineNumbers, node, directoryId, subdirectory, "Directory", "Subdirectory");
2402 +
2403 if (null == id)
2404 {
2405 id = this.Core.CreateIdentifier("rc", componentId, directoryId);
@@ -4001,7 +4034,8 @@ namespace WixToolset.Core
4034 string description = null;
4035 string descriptionResourceDll = null;
4036 int? descriptionResourceId = null;
4004 - string directory = null;
4037 + string directoryId = null;
4038 + string subdirectory = null;
4039 string displayResourceDll = null;
4040 int? displayResourceId = null;
4041 int? hotkey = null;
@@ -4011,7 +4045,8 @@ namespace WixToolset.Core
4045 string shortName = null;
4046 ShortcutShowType? show = null;
4047 string target = null;
4014 - string workingDirectory = null;
4048 + string workingDirectoryId = null;
4049 + string workingSubdirectory = null;
4050
4051 foreach (var attrib in node.Attributes())
4052 {
@@ -4038,7 +4073,11 @@ namespace WixToolset.Core
4073 descriptionResourceId = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, Int16.MaxValue);
4074 break;
4075 case "Directory":
4041 - directory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null);
4076 + directoryId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
4077 + this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, directoryId);
4078 + break;
4079 + case "Subdirectory":
4080 + subdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
4081 break;
4082 case "DisplayResourceDll":
4083 displayResourceDll = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
@@ -4086,7 +4125,11 @@ namespace WixToolset.Core
4125 target = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
4126 break;
4127 case "WorkingDirectory":
4089 - workingDirectory = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
4128 + workingDirectoryId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
4129 + this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, workingDirectoryId);
4130 + break;
4131 + case "WorkingSubdirectory":
4132 + workingSubdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
4133 break;
4134 default:
4135 this.Core.UnexpectedAttribute(node, attrib);
@@ -4104,11 +4147,11 @@ namespace WixToolset.Core
4147 this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "Target", "Advertise", "yes"));
4148 }
4149
4107 - if (null == directory)
4150 + if (null == directoryId)
4151 {
4152 if ("Component" == parentElementLocalName)
4153 {
4111 - directory = defaultTarget;
4154 + directoryId = defaultTarget;
4155 }
4156 else
4157 {
@@ -4116,6 +4159,8 @@ namespace WixToolset.Core
4159 }
4160 }
4161
4162 + directoryId = this.HandleSubdirectory(sourceLineNumbers, node, directoryId, subdirectory, "Directory", "Subdirectory");
4163 +
4164 if (null != descriptionResourceDll)
4165 {
4166 if (!descriptionResourceId.HasValue)
@@ -4151,6 +4196,8 @@ namespace WixToolset.Core
4196 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
4197 }
4198
4199 + workingDirectoryId = this.HandleSubdirectory(sourceLineNumbers, node, workingDirectoryId, workingSubdirectory, "WorkingDirectory", "WorkingSubdirectory");
4200 +
4201 if ("Component" != parentElementLocalName && null != target)
4202 {
4203 this.Core.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "Target", parentElementLocalName));
@@ -4158,7 +4205,7 @@ namespace WixToolset.Core
4205
4206 if (null == id)
4207 {
4161 - id = this.Core.CreateIdentifier("sct", directory, LowercaseOrNull(name));
4208 + id = this.Core.CreateIdentifier("sct", directoryId, LowercaseOrNull(name));
4209 }
4210
4211 foreach (var child in node.Elements())
@@ -4209,7 +4256,7 @@ namespace WixToolset.Core
4256
4257 this.Core.AddSymbol(new ShortcutSymbol(sourceLineNumbers, id)
4258 {
4212 - DirectoryRef = directory,
4259 + DirectoryRef = directoryId,
4260 Name = name,
4261 ShortName = shortName,
4262 ComponentRef = componentId,
@@ -4220,7 +4267,7 @@ namespace WixToolset.Core
4267 IconRef = icon,
4268 IconIndex = iconIndex,
4269 Show = show,
4223 - WorkingDirectory = workingDirectory,
4270 + WorkingDirectory = workingDirectoryId,
4271 DisplayResourceDll = displayResourceDll,
4272 DisplayResourceId = displayResourceId,
4273 DescriptionResourceDll = descriptionResourceDll,
@@ -4309,7 +4356,8 @@ namespace WixToolset.Core
4356 var cost = CompilerConstants.IntegerNotSet;
4357 string description = null;
4358 var flags = 0;
4312 - string helpDirectory = null;
4359 + string helpDirectoryId = null;
4360 + string helpSubdirectory = null;
4361 var language = CompilerConstants.IntegerNotSet;
4362 var majorVersion = CompilerConstants.IntegerNotSet;
4363 var minorVersion = CompilerConstants.IntegerNotSet;
@@ -4346,7 +4394,11 @@ namespace WixToolset.Core
4394 }
4395 break;
4396 case "HelpDirectory":
4349 - helpDirectory = this.Core.CreateDirectoryReferenceFromInlineSyntax(sourceLineNumbers, attrib, null);
4397 + helpDirectoryId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
4398 + this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, helpDirectoryId);
4399 + break;
4400 + case "HelpSubdirectory":
4401 + helpSubdirectory = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, allowRelative: true);
4402 break;
4403 case "Hidden":
4404 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
@@ -4394,6 +4446,8 @@ namespace WixToolset.Core
4446 language = CompilerConstants.IllegalInteger;
4447 }
4448
4449 + helpDirectoryId = this.HandleSubdirectory(sourceLineNumbers, node, helpDirectoryId, helpSubdirectory, "HelpDirectory", "HelpSubdirectory");
4450 +
4451 // build up the typelib version string for the registry if the major or minor version was specified
4452 string registryVersion = null;
4453 if (CompilerConstants.IntegerNotSet != majorVersion || CompilerConstants.IntegerNotSet != minorVersion)
@@ -4488,7 +4542,7 @@ namespace WixToolset.Core
4542 Language = language,
4543 ComponentRef = componentId,
4544 Description = description,
4491 - DirectoryRef = helpDirectory,
4545 + DirectoryRef = helpDirectoryId,
4546 FeatureRef = Guid.Empty.ToString("B")
4547 });
4548
@@ -4534,10 +4588,10 @@ namespace WixToolset.Core
4588 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion]\FLAGS, (Default) = [TypeLibFlags]
4589 this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}\FLAGS", id, registryVersion), null, flags.ToString(CultureInfo.InvariantCulture.NumberFormat), componentId);
4590
4537 - if (null != helpDirectory)
4591 + if (null != helpDirectoryId)
4592 {
4593 // HKCR\TypeLib\[ID]\[MajorVersion].[MinorVersion]\HELPDIR, (Default) = [HelpDirectory]
4540 - this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}\HELPDIR", id, registryVersion), null, String.Concat("[", helpDirectory, "]"), componentId);
4594 + this.Core.CreateRegistryRow(sourceLineNumbers, RegistryRootType.ClassesRoot, String.Format(CultureInfo.InvariantCulture, @"TypeLib\{0}\{1}\HELPDIR", id, registryVersion), null, String.Concat("[", helpDirectoryId, "]"), componentId);
4595 }
4596 }
4597 }
src/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
+23 -103
@@ -18,8 +18,6 @@ namespace WixToolset.Core.ExtensibilityServices
18
19 internal class ParseHelper : IParseHelper
20 {
21 - private static readonly char[] InlineDirectorySeparators = new char[] { ':', '\\', '/' };
22 -
21 public ParseHelper(IServiceProvider serviceProvider)
22 {
23 this.ServiceProvider = serviceProvider;
@@ -56,12 +54,9 @@ namespace WixToolset.Core.ExtensibilityServices
54
55 public Identifier CreateDirectorySymbol(IntermediateSection section, SourceLineNumber sourceLineNumbers, Identifier id, string parentId, string name, string shortName = null, string sourceName = null, string shortSourceName = null)
56 {
59 - // For anonymous directories, create the identifier. If this identifier already exists in the
60 - // active section, bail so we don't add duplicate anonymous directory symbols (which are legal
61 - // but bloat the intermediate and ultimately make the linker do "busy work").
57 if (null == id)
58 {
64 - id = this.CreateIdentifier("dir", parentId, name, shortName, sourceName, shortSourceName);
59 + id = this.CreateIdentifier("d", parentId, name, shortName, sourceName, shortSourceName);
60 }
61
62 var symbol = section.AddSymbol(new DirectorySymbol(sourceLineNumbers, id)
@@ -78,28 +73,37 @@ namespace WixToolset.Core.ExtensibilityServices
73
74 public string CreateDirectoryReferenceFromInlineSyntax(IntermediateSection section, SourceLineNumber sourceLineNumbers, XAttribute attribute, string parentId, string inlineSyntax, IDictionary<string, string> sectionCachedInlinedDirectoryIds)
75 {
81 - if (String.IsNullOrEmpty(inlineSyntax))
76 + if (String.IsNullOrEmpty(parentId))
77 {
83 - inlineSyntax = attribute.Value;
78 + throw new ArgumentNullException(nameof(parentId));
79 }
80
86 - // If no separator is found, the string is a simple reference.
87 - var separatorFound = inlineSyntax.IndexOfAny(InlineDirectorySeparators);
88 - if (separatorFound == -1)
81 + if (String.IsNullOrEmpty(inlineSyntax))
82 {
90 - this.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Directory, inlineSyntax);
91 - return inlineSyntax;
83 + inlineSyntax = this.GetAttributeLongFilename(sourceLineNumbers, attribute, false, true);
84 }
85
94 - // If a parent id was provided and the inline syntax does not start with a directory reference, prepend the parent id.
95 - if (!String.IsNullOrEmpty(parentId) && inlineSyntax[separatorFound] != ':')
86 + if (String.IsNullOrEmpty(inlineSyntax))
87 {
97 - inlineSyntax = String.Concat(parentId, ":", inlineSyntax);
88 + return parentId;
89 }
90
100 - inlineSyntax = inlineSyntax.TrimEnd('\\', '/');
91 + inlineSyntax = inlineSyntax.Trim('\\', '/');
92 +
93 + var cacheKey = String.Concat(parentId, ":", inlineSyntax);
94 +
95 + if (!sectionCachedInlinedDirectoryIds.TryGetValue(cacheKey, out var id))
96 + {
97 + var identifier = this.CreateDirectorySymbol(section, sourceLineNumbers, id: null, parentId, inlineSyntax);
98 +
99 + id = identifier.Id;
100 + }
101 + else
102 + {
103 + this.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Directory, id);
104 + }
105
102 - return this.ParseInlineSyntax(section, sourceLineNumbers, attribute, inlineSyntax, sectionCachedInlinedDirectoryIds);
106 + return id; //this.ParseInlineSyntax(section, sourceLineNumbers, attribute, inlineSyntax, sectionCachedInlinedDirectoryIds);
107 }
108
109 public string CreateGuid(Guid namespaceGuid, string value)
@@ -444,7 +448,7 @@ namespace WixToolset.Core.ExtensibilityServices
448
449 var value = this.GetAttributeValue(sourceLineNumbers, attribute);
450
447 - if (0 < value.Length)
451 + if (!String.IsNullOrEmpty(value))
452 {
453 if (!this.IsValidLongFilename(value, allowWildcards, allowRelative) && !this.IsValidLocIdentifier(value))
454 {
@@ -840,90 +844,6 @@ namespace WixToolset.Core.ExtensibilityServices
844 this.Creator = this.ServiceProvider.GetService<ISymbolDefinitionCreator>();
845 }
846
843 - private string ParseInlineSyntax(IntermediateSection section, SourceLineNumber sourceLineNumbers, XAttribute attribute, string inlineSyntax, IDictionary<string, string> sectionCachedInlinedDirectoryIds)
844 - {
845 - if (!sectionCachedInlinedDirectoryIds.TryGetValue(inlineSyntax, out var id))
846 - {
847 - string parentId;
848 - int nameIndex;
849 -
850 - var separatorIndex = inlineSyntax.LastIndexOfAny(InlineDirectorySeparators);
851 - if (separatorIndex == -1)
852 - {
853 - nameIndex = 0;
854 - parentId = "TARGETDIR";
855 - }
856 - else if (inlineSyntax[separatorIndex] == '\\' || inlineSyntax[separatorIndex] == '/')
857 - {
858 - nameIndex = separatorIndex + 1;
859 -
860 - if (separatorIndex == 0)
861 - {
862 - parentId = "TARGETDIR";
863 - }
864 - else if (inlineSyntax[separatorIndex - 1] == ':')
865 - {
866 - parentId = this.ParseParentReference(section, sourceLineNumbers, attribute, inlineSyntax, separatorIndex - 1);
867 - }
868 - else
869 - {
870 - var parentInlineDirectory = inlineSyntax.Substring(0, separatorIndex);
871 - parentId = this.ParseInlineSyntax(section, sourceLineNumbers, attribute, parentInlineDirectory.TrimEnd('\\', '/'), sectionCachedInlinedDirectoryIds);
872 - }
873 - }
874 - else
875 - {
876 - nameIndex = separatorIndex + 1;
877 - parentId = this.ParseParentReference(section, sourceLineNumbers, attribute, inlineSyntax, separatorIndex);
878 - }
879 -
880 - if (nameIndex == inlineSyntax.Length)
881 - {
882 - id = parentId;
883 - }
884 - else
885 - {
886 - var name = nameIndex != -1 ? inlineSyntax.Substring(nameIndex) : null;
887 -
888 - if (!this.IsValidLongFilename(name, false, false))
889 - {
890 - this.Messaging.Write(ErrorMessages.IllegalLongFilename(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, attribute.Value, name));
891 - return null;
892 - }
893 -
894 - var identifier = this.CreateDirectorySymbol(section, sourceLineNumbers, null, parentId, name);
895 -
896 - id = identifier.Id;
897 - }
898 -
899 - sectionCachedInlinedDirectoryIds.Add(inlineSyntax, id);
900 - }
901 -
902 - return id;
903 - }
904 -
905 - private string ParseParentReference(IntermediateSection section, SourceLineNumber sourceLineNumbers, XAttribute attribute, string reference, int colonIndex)
906 - {
907 - if (colonIndex == 0)
908 - {
909 - this.Messaging.Write(ErrorMessages.IllegalIdentifier(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, attribute.Value, String.Empty));
910 - return null;
911 - }
912 - else
913 - {
914 - var parentId = reference.Substring(0, colonIndex);
915 -
916 - if (!Common.IsIdentifier(parentId))
917 - {
918 - this.Messaging.Write(ErrorMessages.IllegalIdentifier(sourceLineNumbers, attribute.Parent.Name.LocalName, attribute.Name.LocalName, attribute.Value, parentId));
919 - return null;
920 - }
921 -
922 - this.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Directory, parentId);
923 - return parentId;
924 - }
925 - }
926 -
847 private static bool TryFindExtension(IEnumerable<ICompilerExtension> extensions, XNamespace ns, out ICompilerExtension extension)
848 {
849 extension = null;
src/WixToolset.Core/Linker.cs
-1
@@ -587,7 +587,6 @@ namespace WixToolset.Core
587 {
588 var removeSymbols = new List<IntermediateSymbol>();
589
590 - // Count down because we'll sometimes remove items from the list.
590 foreach (var symbol in section.Symbols)
591 {
592 // Only process the "grouping parents" such as FeatureGroup, ComponentGroup, Feature,
src/test/WixToolsetTest.CoreIntegration/DirectoryFixture.cs
+19 -16
@@ -7,6 +7,7 @@ namespace WixToolsetTest.CoreIntegration
7 using WixBuildTools.TestSupport;
8 using WixToolset.Core.TestPackage;
9 using WixToolset.Data;
10 + using WixToolset.Data.WindowsInstaller;
11 using Xunit;
12
13 public class DirectoryFixture
@@ -40,11 +41,11 @@ namespace WixToolsetTest.CoreIntegration
41 var dirSymbols = section.Symbols.OfType<WixToolset.Data.Symbols.DirectorySymbol>().ToList();
42 Assert.Equal(new[]
43 {
43 - "INSTALLFOLDER",
44 - "ProgramFiles6432Folder",
45 - "ProgramFilesFolder",
46 - "TARGETDIR"
47 - }, dirSymbols.Select(d => d.Id.Id).ToArray());
44 + "INSTALLFOLDER:ProgramFiles6432Folder:MsiPackage",
45 + "ProgramFiles6432Folder:ProgramFilesFolder:.",
46 + "ProgramFilesFolder:TARGETDIR:PFiles",
47 + "TARGETDIR::SourceDir"
48 + }, dirSymbols.OrderBy(d => d.Id.Id).Select(d => d.Id.Id + ":" + d.ParentDirectoryRef + ":" + d.Name).ToArray());
49 }
50 }
51
@@ -78,11 +79,11 @@ namespace WixToolsetTest.CoreIntegration
79 var dirSymbols = section.Symbols.OfType<WixToolset.Data.Symbols.DirectorySymbol>().ToList();
80 Assert.Equal(new[]
81 {
81 - "INSTALLFOLDER",
82 - "ProgramFiles6432Folder",
83 - "ProgramFiles64Folder",
84 - "TARGETDIR"
85 - }, dirSymbols.Select(d => d.Id.Id).ToArray());
82 + "INSTALLFOLDER:ProgramFiles6432Folder:MsiPackage",
83 + "ProgramFiles6432Folder:ProgramFiles64Folder:.",
84 + "ProgramFiles64Folder:TARGETDIR:PFiles64",
85 + "TARGETDIR::SourceDir"
86 + }, dirSymbols.OrderBy(d => d.Id.Id).Select(d => d.Id.Id + ":" + d.ParentDirectoryRef + ":" + d.Name).ToArray());
87 }
88 }
89
@@ -116,12 +117,14 @@ namespace WixToolsetTest.CoreIntegration
117 var dirSymbols = section.Symbols.OfType<WixToolset.Data.Symbols.DirectorySymbol>().ToList();
118 Assert.Equal(new[]
119 {
119 - "dirZsSsu81KcG46xXTwc4mTSZO5Zx4",
120 - "INSTALLFOLDER",
121 - "ProgramFiles6432Folder",
122 - "ProgramFiles64Folder",
123 - "TARGETDIR"
124 - }, dirSymbols.Select(d => d.Id.Id).ToArray());
120 + "dZsSsu81KcG46xXTwc4mTSZO5Zx4:INSTALLFOLDER:dupe",
121 + "INSTALLFOLDER:ProgramFiles6432Folder:MsiPackage",
122 + "ProgramFiles6432Folder:ProgramFiles64Folder:.",
123 + "ProgramFiles64Folder:TARGETDIR:PFiles64",
124 + "TARGETDIR::SourceDir"
125 + }, dirSymbols.OrderBy(d => d.Id.Id).Select(d => d.Id.Id + ":" + d.ParentDirectoryRef + ":" + d.Name).ToArray());
126 + }
127 + }
128 }
129 }
130 }
src/test/WixToolsetTest.CoreIntegration/ExtensionFixture.cs
+1 -1
@@ -53,7 +53,7 @@ namespace WixToolsetTest.CoreIntegration
53
54 Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\extest.msi")));
55 Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\extest.wixpdb")));
56 - Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\MsiPackage\example.txt")));
56 + Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\PFiles\MsiPackage\example.txt")));
57
58 var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"bin\extest.wixpdb"));
59 var section = intermediate.Sections.Single();
src/test/WixToolsetTest.CoreIntegration/LanguageFixture.cs
+19
@@ -8,6 +8,7 @@ namespace WixToolsetTest.CoreIntegration
8 using WixToolset.Core.TestPackage;
9 using WixToolset.Data;
10 using WixToolset.Data.Symbols;
11 + using WixToolset.Data.WindowsInstaller;
12 using Xunit;
13
14 public class LanguageFixture
@@ -36,6 +37,14 @@ namespace WixToolsetTest.CoreIntegration
37 var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"bin\test.wixpdb"));
38 var section = intermediate.Sections.Single();
39
40 + var directorySymbols = section.Symbols.OfType<DirectorySymbol>();
41 + Assert.Equal(new[]
42 + {
43 + "INSTALLFOLDER:Example Corporation\\MsiPackage",
44 + "ProgramFilesFolder:PFiles",
45 + "TARGETDIR:SourceDir"
46 + }, directorySymbols.OrderBy(s => s.Id.Id).Select(s => s.Id.Id + ":" + s.Name).ToArray());
47 +
48 var propertySymbol = section.Symbols.OfType<PropertySymbol>().Single(p => p.Id.Id == "ProductLanguage");
49 Assert.Equal("0", propertySymbol.Value);
50
@@ -44,6 +53,16 @@ namespace WixToolsetTest.CoreIntegration
53
54 var summaryCodepage = section.Symbols.OfType<SummaryInformationSymbol>().Single(s => s.PropertyId == SummaryInformationType.Codepage);
55 Assert.Equal("1252", summaryCodepage.Value);
56 +
57 + var data = WindowsInstallerData.Load(Path.Combine(baseFolder, @"bin\test.wixpdb"));
58 + var directoryRows = data.Tables["Directory"].Rows;
59 + Assert.Equal(new[]
60 + {
61 + "d4EceYatXTyy8HXPt5B6DT9Rj.wE:u7-b4gch|Example Corporation",
62 + "INSTALLFOLDER:oekcr5lq|MsiPackage",
63 + "ProgramFilesFolder:PFiles",
64 + "TARGETDIR:SourceDir"
65 + }, directoryRows.Select(r => r.FieldAsString(0) + ":" + r.FieldAsString(2)).ToArray());
66 }
67 }
68
src/test/WixToolsetTest.CoreIntegration/LinkerFixture.cs
+1 -1
@@ -68,7 +68,7 @@ namespace WixToolsetTest.CoreIntegration
68
69 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.msi")));
70 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb")));
71 - Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\MsiPackage\test.txt")));
71 + Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\PFiles\MsiPackage\test.txt")));
72
73 var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"bin\test.wixpdb"));
74 var section = intermediate.Sections.Single();
src/test/WixToolsetTest.CoreIntegration/MsiFixture.cs
+6 -6
@@ -40,7 +40,7 @@ namespace WixToolsetTest.CoreIntegration
40
41 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.msi")));
42 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb")));
43 - Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\MsiPackage\test.txt")));
43 + Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\PFiles\MsiPackage\test.txt")));
44
45 var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"bin\test.wixpdb"));
46
@@ -240,7 +240,7 @@ namespace WixToolsetTest.CoreIntegration
240
241 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.msi")));
242 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb")));
243 - Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\MsiPackage\test.txt")));
243 + Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\PFiles\MsiPackage\test.txt")));
244
245 var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"bin\test.wixpdb"));
246 var section = intermediate.Sections.Single();
@@ -351,7 +351,7 @@ namespace WixToolsetTest.CoreIntegration
351 var pdbPath = Path.Combine(intermediateFolder, @"bin\test.wixpdb");
352 Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\test.msi")));
353 Assert.True(File.Exists(pdbPath));
354 - Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\MsiPackage\test.txt")));
354 + Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\PFiles\MsiPackage\test.txt")));
355
356 var intermediate = Intermediate.Load(pdbPath);
357 var section = intermediate.Sections.Single();
@@ -527,7 +527,7 @@ namespace WixToolsetTest.CoreIntegration
527
528 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.msi")));
529 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb")));
530 - Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\MsiPackage\test.txt")));
530 + Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\PFiles\MsiPackage\test.txt")));
531
532 var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"bin\test.wixpdb"));
533 var section = intermediate.Sections.Single();
@@ -563,7 +563,7 @@ namespace WixToolsetTest.CoreIntegration
563
564 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.msi")));
565 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb")));
566 - Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\AssemblyMsiPackage\candle.exe")));
566 + Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\PFiles\AssemblyMsiPackage\candle.exe")));
567
568 var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"bin\test.wixpdb"));
569 var section = intermediate.Sections.Single();
@@ -721,7 +721,7 @@ namespace WixToolsetTest.CoreIntegration
721
722 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.msi")));
723 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb")));
724 - Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\MsiPackage\Foo.exe")));
724 + Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\PFiles\MsiPackage\Foo.exe")));
725
726 var intermediate = Intermediate.Load(Path.Combine(baseFolder, @"bin\test.wixpdb"));
727 var section = intermediate.Sections.Single();
src/test/WixToolsetTest.CoreIntegration/TestData/CopyFile/CopyFile.wxs
+3 -1
@@ -10,6 +10,8 @@
10 </Fragment>
11
12 <Fragment>
13 - <Directory Id="OtherFolder" Name="INSTALLFOLDER:\other" />
13 + <DirectoryRef Id="INSTALLFOLDER">
14 + <Directory Id="OtherFolder" Name="other" />
15 + </DirectoryRef>
16 </Fragment>
17 </Wix>
src/test/WixToolsetTest.CoreIntegration/TestData/DuplicateDir/DuplicateDir.wxs
+2 -2
@@ -8,7 +8,7 @@
8 </Fragment>
9
10 <Fragment>
11 - <ComponentGroup Id="GroupA" Directory="INSTALLFOLDER:\dupe">
11 + <ComponentGroup Id="GroupA" Directory="INSTALLFOLDER" Subdirectory="dupe">
12 <Component>
13 <File Name="a.txt" Source="test.txt" />
14 </Component>
@@ -16,7 +16,7 @@
16 </Fragment>
17
18 <Fragment>
19 - <ComponentGroup Id="GroupB" Directory="INSTALLFOLDER:\dupe">
19 + <ComponentGroup Id="GroupB" Directory="INSTALLFOLDER" Subdirectory="dupe">
20 <Component>
21 <File Name="b.txt" Source="test.txt" />
22 </Component>
src/test/WixToolsetTest.CoreIntegration/TestData/Language/Package.wxs
+3 -1
@@ -11,6 +11,8 @@
11 </Package>
12
13 <Fragment>
14 - <Directory Id="INSTALLFOLDER" Name="ProgramFilesFolder:\MsiPackage" />
14 + <DirectoryRef Id="ProgramFilesFolder">
15 + <Directory Id="INSTALLFOLDER" Name="MsiPackage" />
16 + </DirectoryRef>
17 </Fragment>
18 </Wix>
src/test/WixToolsetTest.CoreIntegration/TestData/Media/MultiMedia.wxs
+4 -4
@@ -8,19 +8,19 @@
8 <Media Id="2" Cabinet="cab2.cab" />
9
10 <Feature Id="ProductFeature" Title="MsiPackageTitle">
11 - <Component Directory="ProgramFilesFolder:\~MultiMedia" DiskId="1">
11 + <Component Directory="ProgramFilesFolder" Subdirectory="~MultiMedia" DiskId="1">
12 <File Source="a1.txt" />
13 </Component>
14
15 - <Component Directory="ProgramFilesFolder:\~MultiMedia" DiskId="1">
15 + <Component Directory="ProgramFilesFolder" Subdirectory="~MultiMedia" DiskId="1">
16 <File Source="a2.txt" />
17 </Component>
18
19 - <Component Directory="ProgramFilesFolder:\~MultiMedia" DiskId="2">
19 + <Component Directory="ProgramFilesFolder" Subdirectory="~MultiMedia" DiskId="2">
20 <File Source="b2.txt" />
21 </Component>
22
23 - <Component Directory="ProgramFilesFolder:\~MultiMedia" DiskId="2">
23 + <Component Directory="ProgramFilesFolder" Subdirectory="~MultiMedia" DiskId="2">
24 <File Source="b1.txt" />
25 </Component>
26 </Feature>
src/test/WixToolsetTest.CoreIntegration/TestData/PatchNoFileChanges/Package.wxs
+3 -1
@@ -4,7 +4,9 @@
4 <MajorUpgrade DowngradeErrorMessage="Newer version already installed." />
5 <MediaTemplate EmbedCab="yes" />
6
7 - <Directory Id="INSTALLFOLDER" Name="ProgramFilesFolder:\~Test App" />
7 + <DirectoryRef Id="ProgramFilesFolder">
8 + <Directory Id="INSTALLFOLDER" Name="~Test App" />
9 + </DirectoryRef>
10
11 <Feature Id="Main">
12 <ComponentGroupRef Id="Components" />
src/test/WixToolsetTest.CoreIntegration/TestData/ProductWithComponentGroupRef/Product.wxs
+4 -2
@@ -1,4 +1,4 @@
1 -<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
1 +<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
2 <Package Name="MsiPackage" Codepage="1252" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="12E4699F-E774-4D05-8A01-5BDD41BBA127" Compressed="no" Scope="perMachine" ProductCode="83f9c623-26fe-42ab-951e-170022117f54">
3
4 <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
@@ -9,6 +9,8 @@
9 </Package>
10
11 <Fragment>
12 - <Directory Id="INSTALLFOLDER" Name="ProgramFiles6432Folder:\MsiPackage" />
12 + <DirectoryRef Id="ProgramFiles6432Folder">
13 + <Directory Id="INSTALLFOLDER" Name="MsiPackage" />
14 + </DirectoryRef>
15 </Fragment>
16 </Wix>
src/test/WixToolsetTest.CoreIntegration/TestData/SameFileFolders/TestComponents.wxs
+4 -4
@@ -1,14 +1,14 @@
1 <?xml version="1.0" encoding="utf-8"?>
2 <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Fragment>
4 - <ComponentGroup Id="ProductComponents">
5 - <Component Directory="INSTALLFOLDER:\a">
4 + <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
5 + <Component Subdirectory="a">
6 <File Source="a\test.txt" />
7 </Component>
8 - <Component Directory="INSTALLFOLDER:\b">
8 + <Component Subdirectory="b">
9 <File Source="b\test.txt" />
10 </Component>
11 - <Component Directory="INSTALLFOLDER:\c">
11 + <Component Subdirectory="c">
12 <File Source="c\test.txt" />
13 </Component>
14 </ComponentGroup>
src/test/WixToolsetTest.CoreIntegration/TestData/UsingProvides/Package.wxs
+3 -1
@@ -9,6 +9,8 @@
9 </Package>
10
11 <Fragment>
12 - <Directory Id="INSTALLFOLDER" Name="ProgramFilesFolder:\MsiPackage" />
12 + <DirectoryRef Id="ProgramFilesFolder">
13 + <Directory Id="INSTALLFOLDER" Name="MsiPackage" />
14 + </DirectoryRef>
15 </Fragment>
16 </Wix>