From 36a8f464f6c9b7e553c94b29ee3ca836638eef4d Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Thu, 7 Jul 2022 17:52:15 -0700 Subject: Support bind variables in Package and Bundle versions Closes 6779 --- src/api/wix/WixToolset.Data/ErrorMessages.cs | 7 +- .../Services/IBackendHelper.cs | 19 +++- .../WixToolset.Core.Burn/Bind/BindBundleCommand.cs | 32 ++++-- src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs | 2 +- .../ExtensibilityServices/BurnBackendHelper.cs | 10 ++ .../Bind/BindDatabaseCommand.cs | 31 ++++-- .../CreateWindowsInstallerDataFromIRCommand.cs | 51 +++++++++- .../Bind/ProcessPackageSoftwareTagsCommand.cs | 50 ++++----- .../WindowsInstallerBackendHelper.cs | 10 ++ src/wix/WixToolset.Core/Common.cs | 2 +- src/wix/WixToolset.Core/Compiler.cs | 1 - .../ExtensibilityServices/BackendHelper.cs | 35 +++++++ .../ExtensibilityServices/ParseHelper.cs | 5 +- .../PackageSummaryInformation/TypicalV3.wxs | 2 +- .../WixToolsetTest.Core/ParserHelperFixture.cs | 2 +- .../BundleFixture.cs | 28 +++++- .../BundleBindVariables/BindVarBundleVersion.wxs | 14 +++ .../TestData/Version/Package.wxs | 31 ------ .../Version/PackageWithBindVariableVersion.wxs | 33 ++++++ .../Version/PackageWithReplaceableVersion.wxs | 31 ++++++ .../UpgradeFixture.cs | 2 +- .../VersionFixture.cs | 112 ++++++++++++++++++++- .../WixToolsetTest.CoreIntegration.csproj | 4 - 23 files changed, 411 insertions(+), 103 deletions(-) create mode 100644 src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundleBindVariables/BindVarBundleVersion.wxs delete mode 100644 src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/Package.wxs create mode 100644 src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/PackageWithBindVariableVersion.wxs create mode 100644 src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/PackageWithReplaceableVersion.wxs (limited to 'src') 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 public static Message InvalidProductVersion(SourceLineNumber sourceLineNumbers, string version) { - 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); - } - - public static Message InvalidProductVersion(SourceLineNumber sourceLineNumbers, string version, string packagePath) - { - 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); + 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); } 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 /// The Filename value. /// true to get a source name; false to get a target name /// true to get a long name; false to get a short name - /// The name. + /// The requesed file name. string GetMsiFileName(string value, bool source, bool longName); /// @@ -165,5 +165,22 @@ namespace WixToolset.Extensibility.Services /// Thus the returned array will always be of length 4. /// string[] SplitMsiFileName(string value); + + /// + /// Tries to parse a version from the provided version string. + /// + /// The version to verify and parse. + /// The parsed result if possible, otherwise null. + /// True if the version was able to parsed, otherwise false. + bool TryParseFourPartVersion(string version, out string parsedVersion); + + /// + /// Tries to parse an MSI product version from the provided version string. + /// + /// The version to verify and parse. + /// Indicates whether to return a strict (255.255.65535) product version or any valid product version (255.255.65535.*). + /// The parsed result if possible, otherwise null. + /// True if the version was able to parsed as an product version, otherwise false. + bool TryParseMsiProductVersion(string version, bool strict, out string parsedVersion); } } 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 return; } + // Resolve any delayed fields now that the variable cache is populated with package information. + if (this.DelayedFields.Any()) + { + this.BackendHelper.ResolveDelayedFields(this.DelayedFields, variableCache); + } + + // Now that delayed variables are resolved the bundle version must be valid so ensure + // it is correct. + this.ProcessBundleVersion(bundleSymbol); + // Reindex the payloads now that all the payloads (minus the manifest payloads that will be created later) // are present. payloadSymbols = section.Symbols.OfType().ToDictionary(t => t.Id.Id); @@ -344,12 +354,6 @@ namespace WixToolset.Core.Burn boundaries = command.UsedRollbackBoundaries; } - // Resolve any delayed fields before generating the manifest. - if (this.DelayedFields.Any()) - { - this.BackendHelper.ResolveDelayedFields(this.DelayedFields, variableCache); - } - { var command = new ProcessDependencyProvidersCommand(this.ServiceProvider, section, facades); command.Execute(); @@ -535,6 +539,22 @@ namespace WixToolset.Core.Burn bundleSymbol.UpgradeCode = this.NormalizeBundleRelatedBundleId(bundleSymbol.SourceLineNumbers, bundleSymbol.UpgradeCode, null, null); } + private void ProcessBundleVersion(WixBundleSymbol bundleSymbol) + { + if (WixVersion.TryParse(bundleSymbol.Version, out var wixVersion)) + { + // Trim the prefix from the version if it is there. + if (wixVersion.Prefix.HasValue) + { + bundleSymbol.Version = bundleSymbol.Version.Substring(1); + } + } + else + { + this.Messaging.Write(ErrorMessages.IllegalVersionValue(bundleSymbol.SourceLineNumbers, "Bundle", "Version", bundleSymbol.Version)); + } + } + private string NormalizeBundleRelatedBundleId(SourceLineNumber sourceLineNumber, string relatedBundleId, string elementName, string attributeName) { 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 public static Message InvalidBundleManifest(SourceLineNumber sourceLineNumbers, string bundleExecutable, string reason) { - return Message(sourceLineNumbers, Ids.InvalidBundleManifest, "Unable to harvest bundle executable '{0}'. The manifest was invalid. {1}", bundleExecutable, reason); + return Message(sourceLineNumbers, Ids.InvalidBundleManifest, "Unable to read bundle executable '{0}'. Its manifest is invalid. {1}", bundleExecutable, reason); } 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 return this.backendHelper.SplitMsiFileName(value); } + public bool TryParseFourPartVersion(string version, out string parsedVersion) + { + return this.backendHelper.TryParseFourPartVersion(version, out parsedVersion); + } + + public bool TryParseMsiProductVersion(string version, bool strict, out string parsedVersion) + { + return this.backendHelper.TryParseMsiProductVersion(version, strict, out parsedVersion); + } + public ITrackedFile TrackFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers = null) { 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 tableDefinitions = command.TableDefinitions; } + if (section.Type == SectionType.Product) + { + this.ProcessProductVersion(packageSymbol, section, validate: false); + } + // Calculate codepage var codepage = this.CalculateCodepage(packageSymbol, moduleSymbol, patchSymbol); @@ -298,8 +303,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind command.Execute(); } - // Now that delayed fields are processed, validate the package/module version. - this.VerifyVersion(packageSymbol, moduleSymbol); + // Now that delayed fields are processed, fixup the package version (if needed) and validate it + // which will short circuit duplicate errors later if the ProductVersion is invalid. + if (SectionType.Product == section.Type) + { + this.ProcessProductVersion(packageSymbol, section, validate: true); + } // Process dependency references. if (SectionType.Product == section.Type || SectionType.Module == section.Type) @@ -551,21 +560,21 @@ namespace WixToolset.Core.WindowsInstaller.Bind return result; } - private void VerifyVersion(WixPackageSymbol packageSymbol, WixModuleSymbol moduleSymbol) + private void ProcessProductVersion(WixPackageSymbol packageSymbol, IntermediateSection section, bool validate) { - if (packageSymbol != null) + if (this.WindowsInstallerBackendHelper.TryParseMsiProductVersion(packageSymbol.Version, strict: false, out var version)) { - if (!this.WindowsInstallerBackendHelper.IsValidMsiProductVersion(packageSymbol.Version)) + if (packageSymbol.Version != version) { - this.Messaging.Write(ErrorMessages.InvalidProductVersion(packageSymbol.SourceLineNumbers, packageSymbol.Version)); + packageSymbol.Version = version; + + var productVersionProperty = section.Symbols.OfType().FirstOrDefault(p => p.Id.Id == "ProductVersion"); + productVersionProperty.Value = version; } } - else if (moduleSymbol != null) + else if (validate) { - if (!this.WindowsInstallerBackendHelper.IsValidFourPartVersion(moduleSymbol.Version)) - { - this.Messaging.Write(WindowsInstallerBackendErrors.InvalidModuleVersion(moduleSymbol.SourceLineNumbers, moduleSymbol.Version)); - } + this.Messaging.Write(ErrorMessages.InvalidProductVersion(packageSymbol.SourceLineNumbers, packageSymbol.Version)); } } 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 this.AddWixEnsureTableSymbol((WixEnsureTableSymbol)symbol); break; + case SymbolDefinitionType.WixModule: + this.AddWixModuleSymbol((WixModuleSymbol)symbol); + break; + case SymbolDefinitionType.WixPackage: this.AddWixPackageSymbol((WixPackageSymbol)symbol); break; @@ -1033,14 +1037,14 @@ namespace WixToolset.Core.WindowsInstaller.Bind private void AddUpgradeSymbol(UpgradeSymbol symbol) { - if (!String.IsNullOrEmpty(symbol.VersionMin) && !this.BackendHelper.IsValidMsiProductVersion(symbol.VersionMin)) + if (this.CheckUpgradeVersion(symbol, symbol.VersionMin, out var changedVersion)) { - this.Messaging.Write(ErrorMessages.InvalidProductVersion(symbol.SourceLineNumbers, symbol.VersionMin)); + symbol.VersionMin = changedVersion; } - if (!String.IsNullOrEmpty(symbol.VersionMax) && !this.BackendHelper.IsValidMsiProductVersion(symbol.VersionMax)) + if (this.CheckUpgradeVersion(symbol, symbol.VersionMax, out changedVersion)) { - this.Messaging.Write(ErrorMessages.InvalidProductVersion(symbol.SourceLineNumbers, symbol.VersionMax)); + symbol.VersionMax = changedVersion; } var row = (UpgradeRow)this.CreateRow(symbol, "Upgrade"); @@ -1248,6 +1252,21 @@ namespace WixToolset.Core.WindowsInstaller.Bind } } + private void AddWixModuleSymbol(WixModuleSymbol symbol) + { + if (!String.IsNullOrEmpty(symbol.Version) && this.BackendHelper.TryParseFourPartVersion(symbol.Version, out var version)) + { + var row = this.CreateRow(symbol, "ModuleSignature"); + row[0] = symbol.ModuleId; + row[1] = symbol.Language; + row[2] = version; + } + else + { + this.Messaging.Write(WindowsInstallerBackendErrors.InvalidModuleVersion(symbol.SourceLineNumbers, symbol.Version)); + } + } + private void AddWixPackageSymbol(WixPackageSymbol symbol) { // TODO: Remove the following from the compiler and do it here instead. @@ -1584,6 +1603,30 @@ namespace WixToolset.Core.WindowsInstaller.Bind return this.BackendHelper.CreateRow(this.Section, symbol, this.Data, tableDefinition); } + private bool CheckUpgradeVersion(UpgradeSymbol symbol, string version, out string changedVersion) + { + if (String.IsNullOrEmpty(version)) + { + // Null is allowed. + } + else if (this.BackendHelper.TryParseMsiProductVersion(version, strict: false, out var parsedVersionMin)) + { + // If the strictly parsed value is different, update the symbol. + if (version != parsedVersionMin) + { + changedVersion = parsedVersionMin; + return true; + } + } + else + { + this.Messaging.Write(ErrorMessages.InvalidProductVersion(symbol.SourceLineNumbers, version)); + } + + changedVersion = null; + return false; + } + private string CreateShortName(string longName, bool keepExtension, params string[] args) { 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 { var trackedFiles = new List(); - string productName = null; - string productVersion = null; - string manufacturer = null; - string upgradeCode = null; - var summaryInfo = this.Section.Symbols.OfType().FirstOrDefault(s => s.PropertyId == SummaryInformationType.PackageCode); var packageCode = NormalizeGuid(summaryInfo?.Value); - foreach (var property in this.Section.Symbols.OfType()) - { - switch (property.Id.Id) - { - case "ProductName": - productName = property.Value; - break; - case "ProductVersion": - productVersion = property.Value; - break; - case "Manufacturer": - manufacturer = property.Value; - break; - case "UpgradeCode": - upgradeCode = NormalizeGuid(property.Value); - break; - } - } + var packageSymbol = this.Section.Symbols.OfType().First(); + var upgradeCode = NormalizeGuid(packageSymbol.UpgradeCode); var fileSymbolsById = this.Section.Symbols.OfType().Where(f => f.Id != null).ToDictionary(f => f.Id.Id); @@ -83,7 +62,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind using (var fs = new FileStream(fileSymbol.Source.Path, FileMode.Create)) { - CreateTagFile(fs, uniqueId, productName, productVersion, tagRow.Regid, manufacturer, persistentId); + CreateTagFile(fs, uniqueId, packageSymbol.Name, packageSymbol.Version, tagRow.Regid, packageSymbol.Manufacturer, persistentId); } // Ensure the matching "SoftwareIdentificationTag" row exists and @@ -113,7 +92,28 @@ namespace WixToolset.Core.WindowsInstaller.Bind private static void CreateTagFile(Stream stream, string uniqueId, string name, string version, string regid, string manufacturer, string persistendId) { - var versionScheme = Version.TryParse(version, out _) ? "multipartnumeric" : "alphanumeric"; + var versionScheme = "alphanumeric"; + + if (WixVersion.TryParse(version, out var parsedVersion)) + { + if (parsedVersion.Prefix.HasValue) + { + version = version.Substring(1); + } + + if (Version.TryParse(version, out _)) + { + versionScheme = "multipartnumeric"; + } + else if (!parsedVersion.HasRevision) + { + versionScheme = "semver"; + } + else + { + versionScheme = "multipartnumeric+suffix"; + } + } using (var writer = XmlWriter.Create(stream, new XmlWriterSettings { Indent = true })) { 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 return this.backendHelper.SplitMsiFileName(value); } + public bool TryParseFourPartVersion(string version, out string parsedVersion) + { + return this.backendHelper.TryParseFourPartVersion(version, out parsedVersion); + } + + public bool TryParseMsiProductVersion(string version, bool strict, out string parsedVersion) + { + return this.backendHelper.TryParseMsiProductVersion(version, strict, out parsedVersion); + } + public ITrackedFile TrackFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers = null) { 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 public static bool IsValidMsiProductVersion(string version) { - return Version.TryParse(version, out var ver) && ver.Major < 256 && ver.Minor < 256 && ver.Build < 65536; + 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); } 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 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Message")); } - this.Core.ParseForExtensionElements(node); 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 { return Common.IsValidShortFilename(filename, allowWildcards); } + + public bool TryParseFourPartVersion(string version, out string parsedVersion) + { + if (WixVersion.TryParse(version, out var wixVersion) && wixVersion.HasMajor && wixVersion.Major < 65536 && wixVersion.Minor < 65536 && wixVersion.Patch < 65536 && wixVersion.Revision < 65536) + { + parsedVersion = $"{wixVersion.Major}.{wixVersion.Minor}.{wixVersion.Patch}.{wixVersion.Revision}"; + return true; + } + + parsedVersion = null; + return false; + } + + public bool TryParseMsiProductVersion(string version, bool strict, out string parsedVersion) + { + 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)) + { + parsedVersion = $"{wixVersion.Major}.{wixVersion.Minor}"; + + if (strict || wixVersion.HasPatch) + { + parsedVersion += $".{wixVersion.Patch}"; + } + + if (!strict && wixVersion.HasRevision) + { + parsedVersion += $".{wixVersion.Revision}"; + } + + return true; + } + + parsedVersion = null; + return false; + } } } 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 if (!String.IsNullOrEmpty(value)) { - if (WixVersion.TryParse(value, out var version)) + if (WixVersion.TryParse(value, out var _)) { - // Return the attribute value sans-prefix, if present. - return version.Prefix.HasValue ? value.Substring(1) : value; + return value; } // 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 @@ - \ No newline at end of file + 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 var attribute = CreateAttribute("v1.2.3.4"); var result = helper.GetAttributeVersionValue(null, attribute); - WixAssert.StringEqual("1.2.3.4", result); + WixAssert.StringEqual("v1.2.3.4", result); } 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 using System.Linq; using System.Text; using System.Xml; - using System.Xml.Linq; using Example.Extension; using WixBuildTools.TestSupport; using WixToolset.Core.Burn; @@ -21,6 +20,33 @@ namespace WixToolsetTest.CoreIntegration public class BundleFixture { + [Fact] + public void CanBuildBundleWithBindVariableVersion() + { + var folder = TestData.Get(@"TestData"); + + using (var fs = new DisposableFileSystem()) + { + var baseFolder = fs.GetFolder(); + var intermediateFolder = Path.Combine(baseFolder, "obj"); + var exePath = Path.Combine(baseFolder, @"bin\test.exe"); + + var result = WixRunner.Execute(new[] + { + "build", + Path.Combine(folder, "BundleBindVariables", "BindVarBundleVersion.wxs"), + "-bindpath", Path.Combine(folder, "SimpleBundle", "data"), + "-bindpath", Path.Combine(folder, ".Data"), + "-intermediateFolder", intermediateFolder, + "-o", exePath, + }); + + result.AssertSuccess(); + + Assert.True(File.Exists(exePath)); + } + } + [Fact] public void CanBuildMultiFileBundle() { 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 @@ + + + + + + + + + + + + + + diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/Package.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/Package.wxs deleted file mode 100644 index 1a9e102f..00000000 --- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/Package.wxs +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/PackageWithReplaceableVersion.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/PackageWithReplaceableVersion.wxs new file mode 100644 index 00000000..1a9e102f --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Version/PackageWithReplaceableVersion.wxs @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 .ToArray(); WixAssert.CompareLineByLine(new[] { - "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.", + "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.", }, errorMessages); Assert.Equal(242, result.ExitCode); } 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 @@ -12,6 +12,101 @@ namespace WixToolsetTest.CoreIntegration public class VersionFixture { + [Fact] + public void CanBuildMsiWithPrefixedVersion() + { + var folder = TestData.Get(@"TestData"); + + using (var fs = new DisposableFileSystem()) + { + var baseFolder = fs.GetFolder(); + var intermediateFolder = Path.Combine(baseFolder, "obj"); + var msiPath = Path.Combine(baseFolder, "bin", "test1.msi"); + + var result = WixRunner.Execute(new[] + { + "build", + Path.Combine(folder, "Version", "PackageWithReplaceableVersion.wxs"), + "-bindpath", Path.Combine(folder, "SingleFile", "data"), + "-intermediateFolder", intermediateFolder, + "-d", "Version=v4.3.2.1", + "-o", msiPath + }); + + result.AssertSuccess(); + + var productVersion = GetProductVersionFromMsi(msiPath); + Assert.Equal("4.3.2.1", productVersion); + } + } + + [Fact] + public void CanBuildMsiWithPrefixedVersionBindVariable() + { + var folder = TestData.Get(@"TestData"); + + using (var fs = new DisposableFileSystem()) + { + var baseFolder = fs.GetFolder(); + var intermediateFolder = Path.Combine(baseFolder, "obj"); + var msiPath = Path.Combine(baseFolder, "bin", "test1.msi"); + + var result = WixRunner.Execute(new[] + { + "build", + Path.Combine(folder, "Version", "PackageWithBindVariableVersion.wxs"), + "-bindpath", Path.Combine(folder, "SingleFile", "data"), + "-intermediateFolder", intermediateFolder, + "-o", msiPath + }); + + result.AssertSuccess(); + + var productVersion = GetProductVersionFromMsi(msiPath); + Assert.Equal("9.8.7.6", productVersion); + + var directoryTable = Query.QueryDatabase(msiPath, new[] { "Directory" }).OrderBy(s => s).ToArray(); + WixAssert.CompareLineByLine(new[] + { + "Directory:DesktopFolder\tTARGETDIR\tDesktop", + "Directory:INSTALLFOLDER\tDesktopFolder\tpja2bznq|MsiPackage v9.8.7.6 and 9.8.7.6", + "Directory:TARGETDIR\t\tSourceDir" + }, directoryTable); + } + } + + [Fact] + public void CannotBuildMsiWithExtendedVersion() + { + var folder = TestData.Get(@"TestData"); + + using (var fs = new DisposableFileSystem()) + { + var baseFolder = fs.GetFolder(); + var intermediateFolder = Path.Combine(baseFolder, "obj"); + var msiPath = Path.Combine(baseFolder, "bin", "test1.msi"); + + var result = WixRunner.Execute(new[] + { + "build", + Path.Combine(folder, "Version", "PackageWithReplaceableVersion.wxs"), + "-bindpath", Path.Combine(folder, "SingleFile", "data"), + "-intermediateFolder", intermediateFolder, + "-d", "Version=v4.3.2-preview.1", + "-o", msiPath + }); + + var errorMessages = result.Messages.Where(m => m.Level == MessageLevel.Error) + .Select(m => m.ToString()) + .ToArray(); + WixAssert.CompareLineByLine(new[] + { + "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.", + }, errorMessages); + Assert.Equal(242, result.ExitCode); + } + } + [Fact] public void CannotBuildMsiWithInvalidMajorVersion() { @@ -26,7 +121,7 @@ namespace WixToolsetTest.CoreIntegration var result = WixRunner.Execute(new[] { "build", - Path.Combine(folder, "Version", "Package.wxs"), + Path.Combine(folder, "Version", "PackageWithReplaceableVersion.wxs"), "-bindpath", Path.Combine(folder, "SingleFile", "data"), "-intermediateFolder", intermediateFolder, "-d", "Version=257.0.0", @@ -38,7 +133,7 @@ namespace WixToolsetTest.CoreIntegration .ToArray(); WixAssert.CompareLineByLine(new[] { - "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.", + "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.", }, errorMessages); Assert.Equal(242, result.ExitCode); } @@ -60,7 +155,7 @@ namespace WixToolsetTest.CoreIntegration var result = WixRunner.Execute(new[] { "build", - Path.Combine(folder, "Version", "Package.wxs"), + Path.Combine(folder, "Version", "PackageWithReplaceableVersion.wxs"), "-bindpath", Path.Combine(folder, "SingleFile", "data"), "-intermediateFolder", intermediateFolder, "-d", "Version=255.255.65535", @@ -82,8 +177,7 @@ namespace WixToolsetTest.CoreIntegration result3.AssertSuccess(); - var propertyTable = Query.QueryDatabase(msiPath, new[] { "Property" }).Select(r => r.Split('\t')).ToDictionary(r => r[0].Substring("Property:".Length), r => r[1]); - Assert.True(propertyTable.TryGetValue("ProductVersion", out var productVersion)); + var productVersion = GetProductVersionFromMsi(msiPath); WixAssert.StringEqual("255.255.65535", productVersion); 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 WixAssert.StringEqual("2022.3.9-preview.0-build.5+0987654321abcdef1234567890", bundleVersion.Value); } } + + private static string GetProductVersionFromMsi(string msiPath) + { + var propertyTable = Query.QueryDatabase(msiPath, new[] { "Property" }).Select(r => r.Split('\t')).ToDictionary(r => r[0].Substring("Property:".Length), r => r[1]); + Assert.True(propertyTable.TryGetValue("ProductVersion", out var productVersion)); + + return productVersion; + } } } 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 @@ -14,10 +14,6 @@ - - - - -- cgit v1.2.3-55-g6feb