aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2022-07-07 17:52:15 -0700
committerRob Mensching <rob@firegiant.com>2022-07-10 21:42:26 -0700
commit36a8f464f6c9b7e553c94b29ee3ca836638eef4d (patch)
tree701d5c00b29e566da0fe434c695e7cc9efde62f3
parent69b10dec18ed9c3ac115db5a207b506807862e2b (diff)
downloadwix-36a8f464f6c9b7e553c94b29ee3ca836638eef4d.tar.gz
wix-36a8f464f6c9b7e553c94b29ee3ca836638eef4d.tar.bz2
wix-36a8f464f6c9b7e553c94b29ee3ca836638eef4d.zip
Support bind variables in Package and Bundle versions
Closes 6779
-rw-r--r--src/api/wix/WixToolset.Data/ErrorMessages.cs7
-rw-r--r--src/api/wix/WixToolset.Extensibility/Services/IBackendHelper.cs19
-rw-r--r--src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs32
-rw-r--r--src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs2
-rw-r--r--src/wix/WixToolset.Core.Burn/ExtensibilityServices/BurnBackendHelper.cs10
-rw-r--r--src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs31
-rw-r--r--src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs51
-rw-r--r--src/wix/WixToolset.Core.WindowsInstaller/Bind/ProcessPackageSoftwareTagsCommand.cs50
-rw-r--r--src/wix/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerBackendHelper.cs10
-rw-r--r--src/wix/WixToolset.Core/Common.cs2
-rw-r--r--src/wix/WixToolset.Core/Compiler.cs1
-rw-r--r--src/wix/WixToolset.Core/ExtensibilityServices/BackendHelper.cs35
-rw-r--r--src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs5
-rw-r--r--src/wix/test/WixToolsetTest.Converters/TestData/PackageSummaryInformation/TypicalV3.wxs2
-rw-r--r--src/wix/test/WixToolsetTest.Core/ParserHelperFixture.cs2
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/BundleFixture.cs28
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleBindVariables/BindVarBundleVersion.wxs14
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/PackageWithBindVariableVersion.wxs33
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/PackageWithReplaceableVersion.wxs (renamed from src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/Package.wxs)0
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/UpgradeFixture.cs2
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/VersionFixture.cs112
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj4
22 files changed, 380 insertions, 72 deletions
diff --git a/src/api/wix/WixToolset.Data/ErrorMessages.cs b/src/api/wix/WixToolset.Data/ErrorMessages.cs
index be222e6d..c28812f7 100644
--- a/src/api/wix/WixToolset.Data/ErrorMessages.cs
+++ b/src/api/wix/WixToolset.Data/ErrorMessages.cs
@@ -1326,12 +1326,7 @@ namespace WixToolset.Data
1326 1326
1327 public static Message InvalidProductVersion(SourceLineNumber sourceLineNumbers, string version) 1327 public static Message InvalidProductVersion(SourceLineNumber sourceLineNumbers, string version)
1328 { 1328 {
1329 return Message(sourceLineNumbers, Ids.InvalidProductVersion, "Invalid product version '{0}'. Product version must have a major version less than 256, a minor version less than 256, and a build version less than 65536.", version); 1329 return Message(sourceLineNumbers, Ids.InvalidProductVersion, "Invalid product version '{0}'. MSI product versions must have a major version less than 256, a minor version less than 256, and a build version less than 65536. The revision value is ignored but version labels and metadata are not allowed.", version);
1330 }
1331
1332 public static Message InvalidProductVersion(SourceLineNumber sourceLineNumbers, string version, string packagePath)
1333 {
1334 return Message(sourceLineNumbers, Ids.InvalidProductVersion, "Invalid product version '{0}' in package '{1}'. When included in a bundle, all product version fields in an MSI package must be less than 65536.", version, packagePath);
1335 } 1330 }
1336 1331
1337 public static Message InvalidRemoveComponent(SourceLineNumber sourceLineNumbers, string component, string feature, string transformPath) 1332 public static Message InvalidRemoveComponent(SourceLineNumber sourceLineNumbers, string component, string feature, string transformPath)
diff --git a/src/api/wix/WixToolset.Extensibility/Services/IBackendHelper.cs b/src/api/wix/WixToolset.Extensibility/Services/IBackendHelper.cs
index 1c92303e..eff42b99 100644
--- a/src/api/wix/WixToolset.Extensibility/Services/IBackendHelper.cs
+++ b/src/api/wix/WixToolset.Extensibility/Services/IBackendHelper.cs
@@ -93,7 +93,7 @@ namespace WixToolset.Extensibility.Services
93 /// <param name="value">The Filename value.</param> 93 /// <param name="value">The Filename value.</param>
94 /// <param name="source">true to get a source name; false to get a target name</param> 94 /// <param name="source">true to get a source name; false to get a target name</param>
95 /// <param name="longName">true to get a long name; false to get a short name</param> 95 /// <param name="longName">true to get a long name; false to get a short name</param>
96 /// <returns>The name.</returns> 96 /// <returns>The requesed file name.</returns>
97 string GetMsiFileName(string value, bool source, bool longName); 97 string GetMsiFileName(string value, bool source, bool longName);
98 98
99 /// <summary> 99 /// <summary>
@@ -165,5 +165,22 @@ namespace WixToolset.Extensibility.Services
165 /// Thus the returned array will always be of length 4. 165 /// Thus the returned array will always be of length 4.
166 /// </remarks> 166 /// </remarks>
167 string[] SplitMsiFileName(string value); 167 string[] SplitMsiFileName(string value);
168
169 /// <summary>
170 /// Tries to parse a version from the provided version string.
171 /// </summary>
172 /// <param name="version">The version to verify and parse.</param>
173 /// <param name="parsedVersion">The parsed result if possible, otherwise null.</param>
174 /// <returns>True if the version was able to parsed, otherwise false.</returns>
175 bool TryParseFourPartVersion(string version, out string parsedVersion);
176
177 /// <summary>
178 /// Tries to parse an MSI product version from the provided version string.
179 /// </summary>
180 /// <param name="version">The version to verify and parse.</param>
181 /// <param name="strict">Indicates whether to return a strict (255.255.65535) product version or any valid product version (255.255.65535.*).</param>
182 /// <param name="parsedVersion">The parsed result if possible, otherwise null.</param>
183 /// <returns>True if the version was able to parsed as an product version, otherwise false.</returns>
184 bool TryParseMsiProductVersion(string version, bool strict, out string parsedVersion);
168 } 185 }
169} 186}
diff --git a/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
index 82547487..a961ef0f 100644
--- a/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
@@ -227,6 +227,16 @@ namespace WixToolset.Core.Burn
227 return; 227 return;
228 } 228 }
229 229
230 // Resolve any delayed fields now that the variable cache is populated with package information.
231 if (this.DelayedFields.Any())
232 {
233 this.BackendHelper.ResolveDelayedFields(this.DelayedFields, variableCache);
234 }
235
236 // Now that delayed variables are resolved the bundle version must be valid so ensure
237 // it is correct.
238 this.ProcessBundleVersion(bundleSymbol);
239
230 // Reindex the payloads now that all the payloads (minus the manifest payloads that will be created later) 240 // Reindex the payloads now that all the payloads (minus the manifest payloads that will be created later)
231 // are present. 241 // are present.
232 payloadSymbols = section.Symbols.OfType<WixBundlePayloadSymbol>().ToDictionary(t => t.Id.Id); 242 payloadSymbols = section.Symbols.OfType<WixBundlePayloadSymbol>().ToDictionary(t => t.Id.Id);
@@ -344,12 +354,6 @@ namespace WixToolset.Core.Burn
344 boundaries = command.UsedRollbackBoundaries; 354 boundaries = command.UsedRollbackBoundaries;
345 } 355 }
346 356
347 // Resolve any delayed fields before generating the manifest.
348 if (this.DelayedFields.Any())
349 {
350 this.BackendHelper.ResolveDelayedFields(this.DelayedFields, variableCache);
351 }
352
353 { 357 {
354 var command = new ProcessDependencyProvidersCommand(this.ServiceProvider, section, facades); 358 var command = new ProcessDependencyProvidersCommand(this.ServiceProvider, section, facades);
355 command.Execute(); 359 command.Execute();
@@ -535,6 +539,22 @@ namespace WixToolset.Core.Burn
535 bundleSymbol.UpgradeCode = this.NormalizeBundleRelatedBundleId(bundleSymbol.SourceLineNumbers, bundleSymbol.UpgradeCode, null, null); 539 bundleSymbol.UpgradeCode = this.NormalizeBundleRelatedBundleId(bundleSymbol.SourceLineNumbers, bundleSymbol.UpgradeCode, null, null);
536 } 540 }
537 541
542 private void ProcessBundleVersion(WixBundleSymbol bundleSymbol)
543 {
544 if (WixVersion.TryParse(bundleSymbol.Version, out var wixVersion))
545 {
546 // Trim the prefix from the version if it is there.
547 if (wixVersion.Prefix.HasValue)
548 {
549 bundleSymbol.Version = bundleSymbol.Version.Substring(1);
550 }
551 }
552 else
553 {
554 this.Messaging.Write(ErrorMessages.IllegalVersionValue(bundleSymbol.SourceLineNumbers, "Bundle", "Version", bundleSymbol.Version));
555 }
556 }
557
538 private string NormalizeBundleRelatedBundleId(SourceLineNumber sourceLineNumber, string relatedBundleId, string elementName, string attributeName) 558 private string NormalizeBundleRelatedBundleId(SourceLineNumber sourceLineNumber, string relatedBundleId, string elementName, string attributeName)
539 { 559 {
540 if (Guid.TryParse(relatedBundleId, out var guid)) 560 if (Guid.TryParse(relatedBundleId, out var guid))
diff --git a/src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs b/src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs
index 0cfd849b..04290667 100644
--- a/src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs
+++ b/src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs
@@ -92,7 +92,7 @@ namespace WixToolset.Core.Burn
92 92
93 public static Message InvalidBundleManifest(SourceLineNumber sourceLineNumbers, string bundleExecutable, string reason) 93 public static Message InvalidBundleManifest(SourceLineNumber sourceLineNumbers, string bundleExecutable, string reason)
94 { 94 {
95 return Message(sourceLineNumbers, Ids.InvalidBundleManifest, "Unable to harvest bundle executable '{0}'. The manifest was invalid. {1}", bundleExecutable, reason); 95 return Message(sourceLineNumbers, Ids.InvalidBundleManifest, "Unable to read bundle executable '{0}'. Its manifest is invalid. {1}", bundleExecutable, reason);
96 } 96 }
97 97
98 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args) 98 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args)
diff --git a/src/wix/WixToolset.Core.Burn/ExtensibilityServices/BurnBackendHelper.cs b/src/wix/WixToolset.Core.Burn/ExtensibilityServices/BurnBackendHelper.cs
index 909c9b60..52f01f58 100644
--- a/src/wix/WixToolset.Core.Burn/ExtensibilityServices/BurnBackendHelper.cs
+++ b/src/wix/WixToolset.Core.Burn/ExtensibilityServices/BurnBackendHelper.cs
@@ -134,6 +134,16 @@ namespace WixToolset.Core.Burn.ExtensibilityServices
134 return this.backendHelper.SplitMsiFileName(value); 134 return this.backendHelper.SplitMsiFileName(value);
135 } 135 }
136 136
137 public bool TryParseFourPartVersion(string version, out string parsedVersion)
138 {
139 return this.backendHelper.TryParseFourPartVersion(version, out parsedVersion);
140 }
141
142 public bool TryParseMsiProductVersion(string version, bool strict, out string parsedVersion)
143 {
144 return this.backendHelper.TryParseMsiProductVersion(version, strict, out parsedVersion);
145 }
146
137 public ITrackedFile TrackFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers = null) 147 public ITrackedFile TrackFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers = null)
138 { 148 {
139 return this.backendHelper.TrackFile(path, type, sourceLineNumbers); 149 return this.backendHelper.TrackFile(path, type, sourceLineNumbers);
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
index 5b5221fa..0e26bf6f 100644
--- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
+++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
@@ -127,6 +127,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind
127 tableDefinitions = command.TableDefinitions; 127 tableDefinitions = command.TableDefinitions;
128 } 128 }
129 129
130 if (section.Type == SectionType.Product)
131 {
132 this.ProcessProductVersion(packageSymbol, section, validate: false);
133 }
134
130 // Calculate codepage 135 // Calculate codepage
131 var codepage = this.CalculateCodepage(packageSymbol, moduleSymbol, patchSymbol); 136 var codepage = this.CalculateCodepage(packageSymbol, moduleSymbol, patchSymbol);
132 137
@@ -298,8 +303,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind
298 command.Execute(); 303 command.Execute();
299 } 304 }
300 305
301 // Now that delayed fields are processed, validate the package/module version. 306 // Now that delayed fields are processed, fixup the package version (if needed) and validate it
302 this.VerifyVersion(packageSymbol, moduleSymbol); 307 // which will short circuit duplicate errors later if the ProductVersion is invalid.
308 if (SectionType.Product == section.Type)
309 {
310 this.ProcessProductVersion(packageSymbol, section, validate: true);
311 }
303 312
304 // Process dependency references. 313 // Process dependency references.
305 if (SectionType.Product == section.Type || SectionType.Module == section.Type) 314 if (SectionType.Product == section.Type || SectionType.Module == section.Type)
@@ -551,21 +560,21 @@ namespace WixToolset.Core.WindowsInstaller.Bind
551 return result; 560 return result;
552 } 561 }
553 562
554 private void VerifyVersion(WixPackageSymbol packageSymbol, WixModuleSymbol moduleSymbol) 563 private void ProcessProductVersion(WixPackageSymbol packageSymbol, IntermediateSection section, bool validate)
555 { 564 {
556 if (packageSymbol != null) 565 if (this.WindowsInstallerBackendHelper.TryParseMsiProductVersion(packageSymbol.Version, strict: false, out var version))
557 { 566 {
558 if (!this.WindowsInstallerBackendHelper.IsValidMsiProductVersion(packageSymbol.Version)) 567 if (packageSymbol.Version != version)
559 { 568 {
560 this.Messaging.Write(ErrorMessages.InvalidProductVersion(packageSymbol.SourceLineNumbers, packageSymbol.Version)); 569 packageSymbol.Version = version;
570
571 var productVersionProperty = section.Symbols.OfType<PropertySymbol>().FirstOrDefault(p => p.Id.Id == "ProductVersion");
572 productVersionProperty.Value = version;
561 } 573 }
562 } 574 }
563 else if (moduleSymbol != null) 575 else if (validate)
564 { 576 {
565 if (!this.WindowsInstallerBackendHelper.IsValidFourPartVersion(moduleSymbol.Version)) 577 this.Messaging.Write(ErrorMessages.InvalidProductVersion(packageSymbol.SourceLineNumbers, packageSymbol.Version));
566 {
567 this.Messaging.Write(WindowsInstallerBackendErrors.InvalidModuleVersion(moduleSymbol.SourceLineNumbers, moduleSymbol.Version));
568 }
569 } 578 }
570 } 579 }
571 580
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs
index e5966920..60317cd9 100644
--- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs
+++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateWindowsInstallerDataFromIRCommand.cs
@@ -224,6 +224,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind
224 this.AddWixEnsureTableSymbol((WixEnsureTableSymbol)symbol); 224 this.AddWixEnsureTableSymbol((WixEnsureTableSymbol)symbol);
225 break; 225 break;
226 226
227 case SymbolDefinitionType.WixModule:
228 this.AddWixModuleSymbol((WixModuleSymbol)symbol);
229 break;
230
227 case SymbolDefinitionType.WixPackage: 231 case SymbolDefinitionType.WixPackage:
228 this.AddWixPackageSymbol((WixPackageSymbol)symbol); 232 this.AddWixPackageSymbol((WixPackageSymbol)symbol);
229 break; 233 break;
@@ -1033,14 +1037,14 @@ namespace WixToolset.Core.WindowsInstaller.Bind
1033 1037
1034 private void AddUpgradeSymbol(UpgradeSymbol symbol) 1038 private void AddUpgradeSymbol(UpgradeSymbol symbol)
1035 { 1039 {
1036 if (!String.IsNullOrEmpty(symbol.VersionMin) && !this.BackendHelper.IsValidMsiProductVersion(symbol.VersionMin)) 1040 if (this.CheckUpgradeVersion(symbol, symbol.VersionMin, out var changedVersion))
1037 { 1041 {
1038 this.Messaging.Write(ErrorMessages.InvalidProductVersion(symbol.SourceLineNumbers, symbol.VersionMin)); 1042 symbol.VersionMin = changedVersion;
1039 } 1043 }
1040 1044
1041 if (!String.IsNullOrEmpty(symbol.VersionMax) && !this.BackendHelper.IsValidMsiProductVersion(symbol.VersionMax)) 1045 if (this.CheckUpgradeVersion(symbol, symbol.VersionMax, out changedVersion))
1042 { 1046 {
1043 this.Messaging.Write(ErrorMessages.InvalidProductVersion(symbol.SourceLineNumbers, symbol.VersionMax)); 1047 symbol.VersionMax = changedVersion;
1044 } 1048 }
1045 1049
1046 var row = (UpgradeRow)this.CreateRow(symbol, "Upgrade"); 1050 var row = (UpgradeRow)this.CreateRow(symbol, "Upgrade");
@@ -1248,6 +1252,21 @@ namespace WixToolset.Core.WindowsInstaller.Bind
1248 } 1252 }
1249 } 1253 }
1250 1254
1255 private void AddWixModuleSymbol(WixModuleSymbol symbol)
1256 {
1257 if (!String.IsNullOrEmpty(symbol.Version) && this.BackendHelper.TryParseFourPartVersion(symbol.Version, out var version))
1258 {
1259 var row = this.CreateRow(symbol, "ModuleSignature");
1260 row[0] = symbol.ModuleId;
1261 row[1] = symbol.Language;
1262 row[2] = version;
1263 }
1264 else
1265 {
1266 this.Messaging.Write(WindowsInstallerBackendErrors.InvalidModuleVersion(symbol.SourceLineNumbers, symbol.Version));
1267 }
1268 }
1269
1251 private void AddWixPackageSymbol(WixPackageSymbol symbol) 1270 private void AddWixPackageSymbol(WixPackageSymbol symbol)
1252 { 1271 {
1253 // TODO: Remove the following from the compiler and do it here instead. 1272 // TODO: Remove the following from the compiler and do it here instead.
@@ -1584,6 +1603,30 @@ namespace WixToolset.Core.WindowsInstaller.Bind
1584 return this.BackendHelper.CreateRow(this.Section, symbol, this.Data, tableDefinition); 1603 return this.BackendHelper.CreateRow(this.Section, symbol, this.Data, tableDefinition);
1585 } 1604 }
1586 1605
1606 private bool CheckUpgradeVersion(UpgradeSymbol symbol, string version, out string changedVersion)
1607 {
1608 if (String.IsNullOrEmpty(version))
1609 {
1610 // Null is allowed.
1611 }
1612 else if (this.BackendHelper.TryParseMsiProductVersion(version, strict: false, out var parsedVersionMin))
1613 {
1614 // If the strictly parsed value is different, update the symbol.
1615 if (version != parsedVersionMin)
1616 {
1617 changedVersion = parsedVersionMin;
1618 return true;
1619 }
1620 }
1621 else
1622 {
1623 this.Messaging.Write(ErrorMessages.InvalidProductVersion(symbol.SourceLineNumbers, version));
1624 }
1625
1626 changedVersion = null;
1627 return false;
1628 }
1629
1587 private string CreateShortName(string longName, bool keepExtension, params string[] args) 1630 private string CreateShortName(string longName, bool keepExtension, params string[] args)
1588 { 1631 {
1589 longName = longName.ToLowerInvariant(); 1632 longName = longName.ToLowerInvariant();
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/ProcessPackageSoftwareTagsCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/ProcessPackageSoftwareTagsCommand.cs
index 41dfbcf1..67815fcf 100644
--- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/ProcessPackageSoftwareTagsCommand.cs
+++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/ProcessPackageSoftwareTagsCommand.cs
@@ -36,32 +36,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind
36 { 36 {
37 var trackedFiles = new List<ITrackedFile>(); 37 var trackedFiles = new List<ITrackedFile>();
38 38
39 string productName = null;
40 string productVersion = null;
41 string manufacturer = null;
42 string upgradeCode = null;
43
44 var summaryInfo = this.Section.Symbols.OfType<SummaryInformationSymbol>().FirstOrDefault(s => s.PropertyId == SummaryInformationType.PackageCode); 39 var summaryInfo = this.Section.Symbols.OfType<SummaryInformationSymbol>().FirstOrDefault(s => s.PropertyId == SummaryInformationType.PackageCode);
45 var packageCode = NormalizeGuid(summaryInfo?.Value); 40 var packageCode = NormalizeGuid(summaryInfo?.Value);
46 41
47 foreach (var property in this.Section.Symbols.OfType<PropertySymbol>()) 42 var packageSymbol = this.Section.Symbols.OfType<WixPackageSymbol>().First();
48 { 43 var upgradeCode = NormalizeGuid(packageSymbol.UpgradeCode);
49 switch (property.Id.Id)
50 {
51 case "ProductName":
52 productName = property.Value;
53 break;
54 case "ProductVersion":
55 productVersion = property.Value;
56 break;
57 case "Manufacturer":
58 manufacturer = property.Value;
59 break;
60 case "UpgradeCode":
61 upgradeCode = NormalizeGuid(property.Value);
62 break;
63 }
64 }
65 44
66 var fileSymbolsById = this.Section.Symbols.OfType<FileSymbol>().Where(f => f.Id != null).ToDictionary(f => f.Id.Id); 45 var fileSymbolsById = this.Section.Symbols.OfType<FileSymbol>().Where(f => f.Id != null).ToDictionary(f => f.Id.Id);
67 46
@@ -83,7 +62,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
83 62
84 using (var fs = new FileStream(fileSymbol.Source.Path, FileMode.Create)) 63 using (var fs = new FileStream(fileSymbol.Source.Path, FileMode.Create))
85 { 64 {
86 CreateTagFile(fs, uniqueId, productName, productVersion, tagRow.Regid, manufacturer, persistentId); 65 CreateTagFile(fs, uniqueId, packageSymbol.Name, packageSymbol.Version, tagRow.Regid, packageSymbol.Manufacturer, persistentId);
87 } 66 }
88 67
89 // Ensure the matching "SoftwareIdentificationTag" row exists and 68 // Ensure the matching "SoftwareIdentificationTag" row exists and
@@ -113,7 +92,28 @@ namespace WixToolset.Core.WindowsInstaller.Bind
113 92
114 private static void CreateTagFile(Stream stream, string uniqueId, string name, string version, string regid, string manufacturer, string persistendId) 93 private static void CreateTagFile(Stream stream, string uniqueId, string name, string version, string regid, string manufacturer, string persistendId)
115 { 94 {
116 var versionScheme = Version.TryParse(version, out _) ? "multipartnumeric" : "alphanumeric"; 95 var versionScheme = "alphanumeric";
96
97 if (WixVersion.TryParse(version, out var parsedVersion))
98 {
99 if (parsedVersion.Prefix.HasValue)
100 {
101 version = version.Substring(1);
102 }
103
104 if (Version.TryParse(version, out _))
105 {
106 versionScheme = "multipartnumeric";
107 }
108 else if (!parsedVersion.HasRevision)
109 {
110 versionScheme = "semver";
111 }
112 else
113 {
114 versionScheme = "multipartnumeric+suffix";
115 }
116 }
117 117
118 using (var writer = XmlWriter.Create(stream, new XmlWriterSettings { Indent = true })) 118 using (var writer = XmlWriter.Create(stream, new XmlWriterSettings { Indent = true }))
119 { 119 {
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerBackendHelper.cs b/src/wix/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerBackendHelper.cs
index 30e167f5..ad738321 100644
--- a/src/wix/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerBackendHelper.cs
+++ b/src/wix/WixToolset.Core.WindowsInstaller/ExtensibilityServices/WindowsInstallerBackendHelper.cs
@@ -123,6 +123,16 @@ namespace WixToolset.Core.WindowsInstaller.ExtensibilityServices
123 return this.backendHelper.SplitMsiFileName(value); 123 return this.backendHelper.SplitMsiFileName(value);
124 } 124 }
125 125
126 public bool TryParseFourPartVersion(string version, out string parsedVersion)
127 {
128 return this.backendHelper.TryParseFourPartVersion(version, out parsedVersion);
129 }
130
131 public bool TryParseMsiProductVersion(string version, bool strict, out string parsedVersion)
132 {
133 return this.backendHelper.TryParseMsiProductVersion(version, strict, out parsedVersion);
134 }
135
126 public ITrackedFile TrackFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers = null) 136 public ITrackedFile TrackFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers = null)
127 { 137 {
128 return this.backendHelper.TrackFile(path, type, sourceLineNumbers); 138 return this.backendHelper.TrackFile(path, type, sourceLineNumbers);
diff --git a/src/wix/WixToolset.Core/Common.cs b/src/wix/WixToolset.Core/Common.cs
index 486c05c7..89cfe515 100644
--- a/src/wix/WixToolset.Core/Common.cs
+++ b/src/wix/WixToolset.Core/Common.cs
@@ -134,7 +134,7 @@ namespace WixToolset.Core
134 134
135 public static bool IsValidMsiProductVersion(string version) 135 public static bool IsValidMsiProductVersion(string version)
136 { 136 {
137 return Version.TryParse(version, out var ver) && ver.Major < 256 && ver.Minor < 256 && ver.Build < 65536; 137 return WixVersion.TryParse(version, out var wixVersion) && wixVersion.HasMajor && wixVersion.Major < 256 && wixVersion.Minor < 256 && wixVersion.Patch < 65536 && wixVersion.Labels == null && String.IsNullOrEmpty(wixVersion.Metadata);
138 } 138 }
139 139
140 public static bool IsValidLongFilename(string filename, bool allowWildcards, bool allowRelative) 140 public static bool IsValidLongFilename(string filename, bool allowWildcards, bool allowRelative)
diff --git a/src/wix/WixToolset.Core/Compiler.cs b/src/wix/WixToolset.Core/Compiler.cs
index 82faa9bb..7361f501 100644
--- a/src/wix/WixToolset.Core/Compiler.cs
+++ b/src/wix/WixToolset.Core/Compiler.cs
@@ -5910,7 +5910,6 @@ namespace WixToolset.Core
5910 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Message")); 5910 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Message"));
5911 } 5911 }
5912 5912
5913
5914 this.Core.ParseForExtensionElements(node); 5913 this.Core.ParseForExtensionElements(node);
5915 5914
5916 if (!this.Core.EncounteredError) 5915 if (!this.Core.EncounteredError)
diff --git a/src/wix/WixToolset.Core/ExtensibilityServices/BackendHelper.cs b/src/wix/WixToolset.Core/ExtensibilityServices/BackendHelper.cs
index f3e526a9..20a47637 100644
--- a/src/wix/WixToolset.Core/ExtensibilityServices/BackendHelper.cs
+++ b/src/wix/WixToolset.Core/ExtensibilityServices/BackendHelper.cs
@@ -119,5 +119,40 @@ namespace WixToolset.Core.ExtensibilityServices
119 { 119 {
120 return Common.IsValidShortFilename(filename, allowWildcards); 120 return Common.IsValidShortFilename(filename, allowWildcards);
121 } 121 }
122
123 public bool TryParseFourPartVersion(string version, out string parsedVersion)
124 {
125 if (WixVersion.TryParse(version, out var wixVersion) && wixVersion.HasMajor && wixVersion.Major < 65536 && wixVersion.Minor < 65536 && wixVersion.Patch < 65536 && wixVersion.Revision < 65536)
126 {
127 parsedVersion = $"{wixVersion.Major}.{wixVersion.Minor}.{wixVersion.Patch}.{wixVersion.Revision}";
128 return true;
129 }
130
131 parsedVersion = null;
132 return false;
133 }
134
135 public bool TryParseMsiProductVersion(string version, bool strict, out string parsedVersion)
136 {
137 if (WixVersion.TryParse(version, out var wixVersion) && wixVersion.HasMajor && wixVersion.Major < 256 && wixVersion.Minor < 256 && wixVersion.Patch < 65536 && wixVersion.Labels == null && String.IsNullOrEmpty(wixVersion.Metadata))
138 {
139 parsedVersion = $"{wixVersion.Major}.{wixVersion.Minor}";
140
141 if (strict || wixVersion.HasPatch)
142 {
143 parsedVersion += $".{wixVersion.Patch}";
144 }
145
146 if (!strict && wixVersion.HasRevision)
147 {
148 parsedVersion += $".{wixVersion.Revision}";
149 }
150
151 return true;
152 }
153
154 parsedVersion = null;
155 return false;
156 }
122 } 157 }
123} 158}
diff --git a/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs b/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
index 4c6702b8..a885e7af 100644
--- a/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
+++ b/src/wix/WixToolset.Core/ExtensibilityServices/ParseHelper.cs
@@ -552,10 +552,9 @@ namespace WixToolset.Core.ExtensibilityServices
552 552
553 if (!String.IsNullOrEmpty(value)) 553 if (!String.IsNullOrEmpty(value))
554 { 554 {
555 if (WixVersion.TryParse(value, out var version)) 555 if (WixVersion.TryParse(value, out var _))
556 { 556 {
557 // Return the attribute value sans-prefix, if present. 557 return value;
558 return version.Prefix.HasValue ? value.Substring(1) : value;
559 } 558 }
560 559
561 // Allow versions to contain binder variables. 560 // Allow versions to contain binder variables.
diff --git a/src/wix/test/WixToolsetTest.Converters/TestData/PackageSummaryInformation/TypicalV3.wxs b/src/wix/test/WixToolsetTest.Converters/TestData/PackageSummaryInformation/TypicalV3.wxs
index 8c5027b4..ea74d63d 100644
--- a/src/wix/test/WixToolsetTest.Converters/TestData/PackageSummaryInformation/TypicalV3.wxs
+++ b/src/wix/test/WixToolsetTest.Converters/TestData/PackageSummaryInformation/TypicalV3.wxs
@@ -34,4 +34,4 @@
34 </Component> 34 </Component>
35 </ComponentGroup> 35 </ComponentGroup>
36 </Product> 36 </Product>
37</Wix> \ No newline at end of file 37</Wix>
diff --git a/src/wix/test/WixToolsetTest.Core/ParserHelperFixture.cs b/src/wix/test/WixToolsetTest.Core/ParserHelperFixture.cs
index 336e6e21..64ae19e4 100644
--- a/src/wix/test/WixToolsetTest.Core/ParserHelperFixture.cs
+++ b/src/wix/test/WixToolsetTest.Core/ParserHelperFixture.cs
@@ -78,7 +78,7 @@ namespace WixToolsetTest.Core
78 var attribute = CreateAttribute("v1.2.3.4"); 78 var attribute = CreateAttribute("v1.2.3.4");
79 var result = helper.GetAttributeVersionValue(null, attribute); 79 var result = helper.GetAttributeVersionValue(null, attribute);
80 80
81 WixAssert.StringEqual("1.2.3.4", result); 81 WixAssert.StringEqual("v1.2.3.4", result);
82 } 82 }
83 83
84 84
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/BundleFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/BundleFixture.cs
index a281ad0f..132e93e6 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/BundleFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/BundleFixture.cs
@@ -8,7 +8,6 @@ namespace WixToolsetTest.CoreIntegration
8 using System.Linq; 8 using System.Linq;
9 using System.Text; 9 using System.Text;
10 using System.Xml; 10 using System.Xml;
11 using System.Xml.Linq;
12 using Example.Extension; 11 using Example.Extension;
13 using WixBuildTools.TestSupport; 12 using WixBuildTools.TestSupport;
14 using WixToolset.Core.Burn; 13 using WixToolset.Core.Burn;
@@ -22,6 +21,33 @@ namespace WixToolsetTest.CoreIntegration
22 public class BundleFixture 21 public class BundleFixture
23 { 22 {
24 [Fact] 23 [Fact]
24 public void CanBuildBundleWithBindVariableVersion()
25 {
26 var folder = TestData.Get(@"TestData");
27
28 using (var fs = new DisposableFileSystem())
29 {
30 var baseFolder = fs.GetFolder();
31 var intermediateFolder = Path.Combine(baseFolder, "obj");
32 var exePath = Path.Combine(baseFolder, @"bin\test.exe");
33
34 var result = WixRunner.Execute(new[]
35 {
36 "build",
37 Path.Combine(folder, "BundleBindVariables", "BindVarBundleVersion.wxs"),
38 "-bindpath", Path.Combine(folder, "SimpleBundle", "data"),
39 "-bindpath", Path.Combine(folder, ".Data"),
40 "-intermediateFolder", intermediateFolder,
41 "-o", exePath,
42 });
43
44 result.AssertSuccess();
45
46 Assert.True(File.Exists(exePath));
47 }
48 }
49
50 [Fact]
25 public void CanBuildMultiFileBundle() 51 public void CanBuildMultiFileBundle()
26 { 52 {
27 var folder = TestData.Get(@"TestData\SimpleBundle"); 53 var folder = TestData.Get(@"TestData\SimpleBundle");
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleBindVariables/BindVarBundleVersion.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleBindVariables/BindVarBundleVersion.wxs
new file mode 100644
index 00000000..b8703b61
--- /dev/null
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleBindVariables/BindVarBundleVersion.wxs
@@ -0,0 +1,14 @@
1<?xml version="1.0" encoding="utf-8"?>
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Bundle Name="BindVarBundleVersion" Version="!(wix.BundleVersion)" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a">
4 <BootstrapperApplication Id="fakeba">
5 <BootstrapperApplicationDll SourceFile="fakeba.dll" />
6 </BootstrapperApplication>
7
8 <Chain>
9 <MsiPackage SourceFile="test.msi" />
10 </Chain>
11
12 <WixVariable Id="BundleVersion" Value="v8.7.6.5" />
13 </Bundle>
14</Wix>
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/PackageWithBindVariableVersion.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/PackageWithBindVariableVersion.wxs
new file mode 100644
index 00000000..43f1c259
--- /dev/null
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/PackageWithBindVariableVersion.wxs
@@ -0,0 +1,33 @@
1<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
2 <Package Version="!(wix.Version)"
3 Name="MsiPackage"
4 Manufacturer="Example Corporation"
5 UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a"
6 Scope="perUser">
7 <MajorUpgrade DowngradeErrorMessage="Downgrade not allowed" />
8 <MediaTemplate EmbedCab="true" />
9
10 <Feature Id="ProductFeature" Title="Feature title">
11 <ComponentGroupRef Id="ProductComponents" />
12 </Feature>
13
14 <WixVariable Id="Version" Value="v9.8.7.6" />
15 </Package>
16
17 <Fragment>
18 <StandardDirectory Id="DesktopFolder">
19 <Directory Id="INSTALLFOLDER" Name="MsiPackage !(wix.Version) and !(bind.property.ProductVersion)" />
20 </StandardDirectory>
21 </Fragment>
22
23 <Fragment>
24 <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
25 <Component>
26 <File Source="test.txt" />
27 </Component>
28 <Component Id="Shared.dll" Shared="yes">
29 <File Name="Shared.dll" Source="test.txt" />
30 </Component>
31 </ComponentGroup>
32 </Fragment>
33</Wix>
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/Package.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/PackageWithReplaceableVersion.wxs
index 1a9e102f..1a9e102f 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/Package.wxs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/PackageWithReplaceableVersion.wxs
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/UpgradeFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/UpgradeFixture.cs
index 5a4c2aae..a9c9fb13 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/UpgradeFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/UpgradeFixture.cs
@@ -39,7 +39,7 @@ namespace WixToolsetTest.CoreIntegration
39 .ToArray(); 39 .ToArray();
40 WixAssert.CompareLineByLine(new[] 40 WixAssert.CompareLineByLine(new[]
41 { 41 {
42 "Invalid product version '1.256.0'. Product version must have a major version less than 256, a minor version less than 256, and a build version less than 65536.", 42 "Invalid product version '1.256.0'. MSI product versions must have a major version less than 256, a minor version less than 256, and a build version less than 65536. The revision value is ignored but version labels and metadata are not allowed.",
43 }, errorMessages); 43 }, errorMessages);
44 Assert.Equal(242, result.ExitCode); 44 Assert.Equal(242, result.ExitCode);
45 } 45 }
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/VersionFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/VersionFixture.cs
index 2a325aa4..f17a92e0 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/VersionFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/VersionFixture.cs
@@ -13,6 +13,101 @@ namespace WixToolsetTest.CoreIntegration
13 public class VersionFixture 13 public class VersionFixture
14 { 14 {
15 [Fact] 15 [Fact]
16 public void CanBuildMsiWithPrefixedVersion()
17 {
18 var folder = TestData.Get(@"TestData");
19
20 using (var fs = new DisposableFileSystem())
21 {
22 var baseFolder = fs.GetFolder();
23 var intermediateFolder = Path.Combine(baseFolder, "obj");
24 var msiPath = Path.Combine(baseFolder, "bin", "test1.msi");
25
26 var result = WixRunner.Execute(new[]
27 {
28 "build",
29 Path.Combine(folder, "Version", "PackageWithReplaceableVersion.wxs"),
30 "-bindpath", Path.Combine(folder, "SingleFile", "data"),
31 "-intermediateFolder", intermediateFolder,
32 "-d", "Version=v4.3.2.1",
33 "-o", msiPath
34 });
35
36 result.AssertSuccess();
37
38 var productVersion = GetProductVersionFromMsi(msiPath);
39 Assert.Equal("4.3.2.1", productVersion);
40 }
41 }
42
43 [Fact]
44 public void CanBuildMsiWithPrefixedVersionBindVariable()
45 {
46 var folder = TestData.Get(@"TestData");
47
48 using (var fs = new DisposableFileSystem())
49 {
50 var baseFolder = fs.GetFolder();
51 var intermediateFolder = Path.Combine(baseFolder, "obj");
52 var msiPath = Path.Combine(baseFolder, "bin", "test1.msi");
53
54 var result = WixRunner.Execute(new[]
55 {
56 "build",
57 Path.Combine(folder, "Version", "PackageWithBindVariableVersion.wxs"),
58 "-bindpath", Path.Combine(folder, "SingleFile", "data"),
59 "-intermediateFolder", intermediateFolder,
60 "-o", msiPath
61 });
62
63 result.AssertSuccess();
64
65 var productVersion = GetProductVersionFromMsi(msiPath);
66 Assert.Equal("9.8.7.6", productVersion);
67
68 var directoryTable = Query.QueryDatabase(msiPath, new[] { "Directory" }).OrderBy(s => s).ToArray();
69 WixAssert.CompareLineByLine(new[]
70 {
71 "Directory:DesktopFolder\tTARGETDIR\tDesktop",
72 "Directory:INSTALLFOLDER\tDesktopFolder\tpja2bznq|MsiPackage v9.8.7.6 and 9.8.7.6",
73 "Directory:TARGETDIR\t\tSourceDir"
74 }, directoryTable);
75 }
76 }
77
78 [Fact]
79 public void CannotBuildMsiWithExtendedVersion()
80 {
81 var folder = TestData.Get(@"TestData");
82
83 using (var fs = new DisposableFileSystem())
84 {
85 var baseFolder = fs.GetFolder();
86 var intermediateFolder = Path.Combine(baseFolder, "obj");
87 var msiPath = Path.Combine(baseFolder, "bin", "test1.msi");
88
89 var result = WixRunner.Execute(new[]
90 {
91 "build",
92 Path.Combine(folder, "Version", "PackageWithReplaceableVersion.wxs"),
93 "-bindpath", Path.Combine(folder, "SingleFile", "data"),
94 "-intermediateFolder", intermediateFolder,
95 "-d", "Version=v4.3.2-preview.1",
96 "-o", msiPath
97 });
98
99 var errorMessages = result.Messages.Where(m => m.Level == MessageLevel.Error)
100 .Select(m => m.ToString())
101 .ToArray();
102 WixAssert.CompareLineByLine(new[]
103 {
104 "Invalid product version 'v4.3.2-preview.1'. MSI product versions must have a major version less than 256, a minor version less than 256, and a build version less than 65536. The revision value is ignored but version labels and metadata are not allowed.",
105 }, errorMessages);
106 Assert.Equal(242, result.ExitCode);
107 }
108 }
109
110 [Fact]
16 public void CannotBuildMsiWithInvalidMajorVersion() 111 public void CannotBuildMsiWithInvalidMajorVersion()
17 { 112 {
18 var folder = TestData.Get(@"TestData"); 113 var folder = TestData.Get(@"TestData");
@@ -26,7 +121,7 @@ namespace WixToolsetTest.CoreIntegration
26 var result = WixRunner.Execute(new[] 121 var result = WixRunner.Execute(new[]
27 { 122 {
28 "build", 123 "build",
29 Path.Combine(folder, "Version", "Package.wxs"), 124 Path.Combine(folder, "Version", "PackageWithReplaceableVersion.wxs"),
30 "-bindpath", Path.Combine(folder, "SingleFile", "data"), 125 "-bindpath", Path.Combine(folder, "SingleFile", "data"),
31 "-intermediateFolder", intermediateFolder, 126 "-intermediateFolder", intermediateFolder,
32 "-d", "Version=257.0.0", 127 "-d", "Version=257.0.0",
@@ -38,7 +133,7 @@ namespace WixToolsetTest.CoreIntegration
38 .ToArray(); 133 .ToArray();
39 WixAssert.CompareLineByLine(new[] 134 WixAssert.CompareLineByLine(new[]
40 { 135 {
41 "Invalid product version '257.0.0'. Product version must have a major version less than 256, a minor version less than 256, and a build version less than 65536.", 136 "Invalid product version '257.0.0'. MSI product versions must have a major version less than 256, a minor version less than 256, and a build version less than 65536. The revision value is ignored but version labels and metadata are not allowed.",
42 }, errorMessages); 137 }, errorMessages);
43 Assert.Equal(242, result.ExitCode); 138 Assert.Equal(242, result.ExitCode);
44 } 139 }
@@ -60,7 +155,7 @@ namespace WixToolsetTest.CoreIntegration
60 var result = WixRunner.Execute(new[] 155 var result = WixRunner.Execute(new[]
61 { 156 {
62 "build", 157 "build",
63 Path.Combine(folder, "Version", "Package.wxs"), 158 Path.Combine(folder, "Version", "PackageWithReplaceableVersion.wxs"),
64 "-bindpath", Path.Combine(folder, "SingleFile", "data"), 159 "-bindpath", Path.Combine(folder, "SingleFile", "data"),
65 "-intermediateFolder", intermediateFolder, 160 "-intermediateFolder", intermediateFolder,
66 "-d", "Version=255.255.65535", 161 "-d", "Version=255.255.65535",
@@ -82,8 +177,7 @@ namespace WixToolsetTest.CoreIntegration
82 177
83 result3.AssertSuccess(); 178 result3.AssertSuccess();
84 179
85 var propertyTable = Query.QueryDatabase(msiPath, new[] { "Property" }).Select(r => r.Split('\t')).ToDictionary(r => r[0].Substring("Property:".Length), r => r[1]); 180 var productVersion = GetProductVersionFromMsi(msiPath);
86 Assert.True(propertyTable.TryGetValue("ProductVersion", out var productVersion));
87 WixAssert.StringEqual("255.255.65535", productVersion); 181 WixAssert.StringEqual("255.255.65535", productVersion);
88 182
89 var extractResult = BundleExtractor.ExtractAllContainers(null, bundlePath, Path.Combine(baseFolder, "ba"), Path.Combine(baseFolder, "attached"), Path.Combine(baseFolder, "extract")); 183 var extractResult = BundleExtractor.ExtractAllContainers(null, bundlePath, Path.Combine(baseFolder, "ba"), Path.Combine(baseFolder, "attached"), Path.Combine(baseFolder, "extract"));
@@ -95,5 +189,13 @@ namespace WixToolsetTest.CoreIntegration
95 WixAssert.StringEqual("2022.3.9-preview.0-build.5+0987654321abcdef1234567890", bundleVersion.Value); 189 WixAssert.StringEqual("2022.3.9-preview.0-build.5+0987654321abcdef1234567890", bundleVersion.Value);
96 } 190 }
97 } 191 }
192
193 private static string GetProductVersionFromMsi(string msiPath)
194 {
195 var propertyTable = Query.QueryDatabase(msiPath, new[] { "Property" }).Select(r => r.Split('\t')).ToDictionary(r => r[0].Substring("Property:".Length), r => r[1]);
196 Assert.True(propertyTable.TryGetValue("ProductVersion", out var productVersion));
197
198 return productVersion;
199 }
98 } 200 }
99} 201}
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj b/src/wix/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj
index 211db06a..996858d1 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/WixToolsetTest.CoreIntegration.csproj
@@ -15,10 +15,6 @@
15 </ItemGroup> 15 </ItemGroup>
16 16
17 <ItemGroup> 17 <ItemGroup>
18 <None Remove="TestData\BundleWithInvalid\BundleWithInvalidLocVariableNames.wxs" />
19 </ItemGroup>
20
21 <ItemGroup>
22 <ProjectReference Include="..\..\WixToolset.Core\WixToolset.Core.csproj" /> 18 <ProjectReference Include="..\..\WixToolset.Core\WixToolset.Core.csproj" />
23 <ProjectReference Include="..\..\WixToolset.Core.Burn\WixToolset.Core.Burn.csproj" /> 19 <ProjectReference Include="..\..\WixToolset.Core.Burn\WixToolset.Core.Burn.csproj" />
24 <ProjectReference Include="..\..\WixToolset.Core.WindowsInstaller\WixToolset.Core.WindowsInstaller.csproj" /> 20 <ProjectReference Include="..\..\WixToolset.Core.WindowsInstaller\WixToolset.Core.WindowsInstaller.csproj" />