From e7b14a8e836de4e36601786bcd4b2cf70a46a599 Mon Sep 17 00:00:00 2001 From: Nir Bar Date: Tue, 5 Dec 2023 10:04:14 +0200 Subject: [PATCH] ExePackage/@DetectVersionVariable: Support providing a version number in a variable to test against the package's version. --- README.md | 3 +- .../Symbols/WixBundleExePackageSymbol.cs | 17 ++ src/burn/engine/exeengine.cpp | 90 ++++++++++ src/burn/engine/package.h | 4 + .../Bundles/CreateBurnManifestCommand.cs | 10 ++ .../PerformBundleBackendValidationCommand.cs | 7 + src/wix/WixToolset.Core/Compiler_Bundle.cs | 53 +++++- .../ExePackageFixture.cs | 164 ++++++++++++++++++ .../ExePackage/ArpEntryAndDetectVersion.wxs | 13 ++ .../ExePackage/DetectVersionVariable.wxs | 11 ++ ...etectVersionVariableAndDetectCondition.wxs | 11 ++ ...etectVersionVariableWithIlegalVariable.wxs | 11 ++ .../InvalidDetectVersionVariableVersion.wxs | 11 ++ 13 files changed, 396 insertions(+), 9 deletions(-) create mode 100644 src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/ArpEntryAndDetectVersion.wxs create mode 100644 src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/DetectVersionVariable.wxs create mode 100644 src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/DetectVersionVariableAndDetectCondition.wxs create mode 100644 src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/DetectVersionVariableWithIlegalVariable.wxs create mode 100644 src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/InvalidDetectVersionVariableVersion.wxs diff --git a/README.md b/README.md index 60c9a1430..bc324ada4 100644 --- a/README.md +++ b/README.md @@ -17,4 +17,5 @@ This repository contains the PanelSwWix4: A custom WiX Toolset codebase - [6298](https://github.com/wixtoolset/issues/issues/6298): Extract detached containers with "wix burn extract" - [6252](https://github.com/wixtoolset/issues/issues/6252): Automatically add -norestart flag for any burn ExePackage, BundlePackage, and related bundles - [7552](https://github.com/wixtoolset/issues/issues/7552): Add burn command line argument to log to console: /clog or /conlog -- [7877](https://github.com/wixtoolset/issues/issues/7877): ArpEntry reads QuietUninstallString or UninstallString, and uses UninstallArguments for the uninstall command line +- [7877](https://github.com/wixtoolset/issues/issues/7877): ArpEntry reads QuietUninstallString or UninstallString, and uses UninstallArguments for the uninstall command line +- ExePackage/@DetectVersionVariable: Support using one of the XxxSearch elements to provide a version number in a variable to test against the package's version. diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleExePackageSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleExePackageSymbol.cs index 741467164..85e96d950 100644 --- a/src/api/wix/WixToolset.Data/Symbols/WixBundleExePackageSymbol.cs +++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleExePackageSymbol.cs @@ -19,6 +19,8 @@ public static partial class SymbolDefinitions new IntermediateFieldDefinition(nameof(WixBundleExePackageSymbolFields.DetectionType), IntermediateFieldType.Number), new IntermediateFieldDefinition(nameof(WixBundleExePackageSymbolFields.ArpId), IntermediateFieldType.String), new IntermediateFieldDefinition(nameof(WixBundleExePackageSymbolFields.ArpDisplayVersion), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(WixBundleExePackageSymbolFields.DetectVersionVariable), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(WixBundleExePackageSymbolFields.Version), IntermediateFieldType.String), }, typeof(WixBundleExePackageSymbol)); } @@ -39,6 +41,8 @@ public enum WixBundleExePackageSymbolFields DetectionType, ArpId, ArpDisplayVersion, + DetectVersionVariable, + Version, } /// @@ -49,6 +53,7 @@ public enum WixBundleExePackageDetectionType None, Condition, Arp, + VersionVariable, } [Flags] @@ -160,5 +165,17 @@ public bool ArpWin64 public bool Repairable => this.RepairCommand != null; public bool Uninstallable => this.UninstallCommand != null; + + public string DetectVersionVariable + { + get => (string)this.Fields[(int)WixBundleExePackageSymbolFields.DetectVersionVariable]; + set => this.Set((int)WixBundleExePackageSymbolFields.DetectVersionVariable, value); + } + + public string Version + { + get => (string)this.Fields[(int)WixBundleExePackageSymbolFields.Version]; + set => this.Set((int)WixBundleExePackageSymbolFields.Version, value); + } } } diff --git a/src/burn/engine/exeengine.cpp b/src/burn/engine/exeengine.cpp index d42a5b863..5d3fcc759 100644 --- a/src/burn/engine/exeengine.cpp +++ b/src/burn/engine/exeengine.cpp @@ -7,6 +7,11 @@ static HRESULT DetectArpEntry( __out BOOTSTRAPPER_PACKAGE_STATE* pPackageState, __out_opt LPWSTR* psczQuietUninstallString ); +static HRESULT DetectByVersionVariable( + __in BURN_VARIABLES* pVariables, + __in const BURN_PACKAGE* pPackage, + __out BOOTSTRAPPER_PACKAGE_STATE* pPackageState + ); // function definitions @@ -33,6 +38,10 @@ extern "C" HRESULT ExeEngineParsePackageFromXml( { pPackage->Exe.detectionType = BURN_EXE_DETECTION_TYPE_ARP; } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"version", -1)) + { + pPackage->Exe.detectionType = BURN_EXE_DETECTION_TYPE_VERSION; + } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"none", -1)) { pPackage->Exe.detectionType = BURN_EXE_DETECTION_TYPE_NONE; @@ -87,6 +96,30 @@ extern "C" HRESULT ExeEngineParsePackageFromXml( pPackage->Exe.fUninstallable = TRUE; } + else if (BURN_EXE_DETECTION_TYPE_VERSION == pPackage->Exe.detectionType) + { + // @DetectVersionVariable + hr = XmlGetAttributeEx(pixnExePackage, L"DetectVersionVariable", &pPackage->Exe.sczDetectVersionVariable); + ExitOnRequiredXmlQueryFailure(hr, "Failed to get @DetectVersionVariable."); + + // @PackageVersion + hr = XmlGetAttributeEx(pixnExePackage, L"PackageVersion", &scz); + ExitOnRequiredXmlQueryFailure(hr, "Failed to get @PackageVersion."); + + hr = VerParseVersion(scz, 0, FALSE, &pPackage->Exe.pExePackageVersion); + ExitOnFailure(hr, "Failed to parse @PackageVersion: %ls", scz); + + if (pPackage->Exe.pExePackageVersion->fInvalid) + { + LogId(REPORT_WARNING, MSG_MANIFEST_INVALID_VERSION, scz); + } + + // @UninstallArguments + hr = XmlGetAttributeEx(pixnExePackage, L"UninstallArguments", &pPackage->Exe.sczUninstallArguments); + ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @UninstallArguments."); + + pPackage->Exe.fUninstallable = TRUE; + } // @InstallArguments hr = XmlGetAttributeEx(pixnExePackage, L"InstallArguments", &pPackage->Exe.sczInstallArguments); @@ -151,7 +184,9 @@ extern "C" void ExeEnginePackageUninitialize( ReleaseStr(pPackage->Exe.sczRepairArguments); ReleaseStr(pPackage->Exe.sczUninstallArguments); ReleaseStr(pPackage->Exe.sczArpKeyPath); + ReleaseStr(pPackage->Exe.sczDetectVersionVariable); ReleaseVerutilVersion(pPackage->Exe.pArpDisplayVersion); + ReleaseVerutilVersion(pPackage->Exe.pExePackageVersion); ReleaseMem(pPackage->Exe.rgExitCodes); // free command-line arguments @@ -208,6 +243,11 @@ extern "C" HRESULT ExeEngineDetectPackage( hr = DetectArpEntry(pPackage, &pPackage->currentState, NULL); ExitOnFailure(hr, "Failed to detect EXE package by ArpEntry."); + break; + case BURN_EXE_DETECTION_TYPE_VERSION: + hr = DetectByVersionVariable(pVariables, pPackage, &pPackage->currentState); + ExitOnFailure(hr, "Failed to detect EXE package by version variable."); + break; default: ExitWithRootFailure(hr, E_INVALIDARG, "Unknown EXE package detection type: %d.", pPackage->Exe.detectionType); @@ -1073,6 +1113,56 @@ extern "C" HRESULT ExeEngineHandleExitCode( return hr; } +static HRESULT DetectByVersionVariable( + __in BURN_VARIABLES* pVariables, + __in const BURN_PACKAGE* pPackage, + __out BOOTSTRAPPER_PACKAGE_STATE* pPackageState + ) +{ + HRESULT hr = S_OK; + VERUTIL_VERSION* pDetectedVersion = NULL; + int nCompareResult = 0; + + *pPackageState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT; + + ExitOnNull((pPackage->Exe.sczDetectVersionVariable && *pPackage->Exe.sczDetectVersionVariable), hr, E_INVALIDSTATE, "DetectVersionVariable is null."); + ExitOnNull(pPackage->Exe.pExePackageVersion, hr, E_INVALIDSTATE, "ExeVersion is null."); + + hr = VariableGetVersion(pVariables, pPackage->Exe.sczDetectVersionVariable, &pDetectedVersion); + if (hr == E_NOTFOUND) + { + hr = S_OK; + ExitFunction(); + } + ExitOnFailure(hr, "Failed to parse detected version variable."); + + if (pDetectedVersion->fInvalid) + { + LogId(REPORT_WARNING, MSG_DETECTED_EXE_PACKAGE_INVALID_VERSION, pPackage->Exe.sczDetectVersionVariable, pDetectedVersion->sczVersion); + } + + hr = VerCompareParsedVersions(pPackage->Exe.pExePackageVersion, pDetectedVersion, &nCompareResult); + ExitOnFailure(hr, "Failed to compare versions."); + + if (nCompareResult < 0) + { + *pPackageState = BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE; + } + else if (nCompareResult > 0) + { + *pPackageState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT; + } + else + { + *pPackageState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT; + } + +LExit: + ReleaseVerutilVersion(pDetectedVersion); + + return hr; +} + static HRESULT DetectArpEntry( __in const BURN_PACKAGE* pPackage, __out BOOTSTRAPPER_PACKAGE_STATE* pPackageState, diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h index 306eed1e2..3a17e1f0f 100644 --- a/src/burn/engine/package.h +++ b/src/burn/engine/package.h @@ -28,6 +28,7 @@ enum BURN_EXE_DETECTION_TYPE BURN_EXE_DETECTION_TYPE_NONE, BURN_EXE_DETECTION_TYPE_CONDITION, BURN_EXE_DETECTION_TYPE_ARP, + BURN_EXE_DETECTION_TYPE_VERSION, }; enum BURN_EXE_EXIT_CODE_TYPE @@ -372,6 +373,9 @@ typedef struct _BURN_PACKAGE LPWSTR sczArpKeyPath; VERUTIL_VERSION* pArpDisplayVersion; + LPWSTR sczDetectVersionVariable; + VERUTIL_VERSION* pExePackageVersion; + LPWSTR sczDetectCondition; LPWSTR sczInstallArguments; LPWSTR sczRepairArguments; diff --git a/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs index 3cb7c35f0..e81b6e797 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs @@ -452,6 +452,16 @@ public void Execute() writer.WriteAttributeString("ArpWin64", "yes"); } + if (!String.IsNullOrEmpty(exePackage.UninstallCommand)) + { + writer.WriteAttributeString("UninstallArguments", exePackage.UninstallCommand); + } + break; + case WixBundleExePackageDetectionType.VersionVariable: + writer.WriteAttributeString("DetectionType", "version"); + writer.WriteAttributeString("DetectVersionVariable", exePackage.DetectVersionVariable); + writer.WriteAttributeString("PackageVersion", exePackage.Version); + if (!String.IsNullOrEmpty(exePackage.UninstallCommand)) { writer.WriteAttributeString("UninstallArguments", exePackage.UninstallCommand); diff --git a/src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs index 01df9f325..a44507b22 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs @@ -120,6 +120,13 @@ private void ValidateExePackage(WixBundleExePackageSymbol symbol, WixBundlePacka this.Messaging.Write(WarningMessages.InvalidWixVersion(symbol.SourceLineNumbers, symbol.ArpDisplayVersion, "ArpEntry", "Version")); } } + else if (symbol.DetectionType == WixBundleExePackageDetectionType.VersionVariable) + { + if (!this.BackendHelper.IsValidWixVersion(symbol.Version)) + { + this.Messaging.Write(WarningMessages.InvalidWixVersion(symbol.SourceLineNumbers, symbol.Version, "ExePackage", "Version")); + } + } } } diff --git a/src/wix/WixToolset.Core/Compiler_Bundle.cs b/src/wix/WixToolset.Core/Compiler_Bundle.cs index cd5a4445b..9ec03ce56 100644 --- a/src/wix/WixToolset.Core/Compiler_Bundle.cs +++ b/src/wix/WixToolset.Core/Compiler_Bundle.cs @@ -2127,6 +2127,8 @@ private string ParseChainPackage(XElement node, WixBundlePackageType packageType string uninstallArguments = null; var perMachine = YesNoDefaultType.NotSet; string detectCondition = null; + string detectVersionVariable = null; + string version = null; string protocol = null; long? installSize = null; var enableFeatureSelection = YesNoType.NotSet; @@ -2135,7 +2137,7 @@ private string ParseChainPackage(XElement node, WixBundlePackageType packageType var bundle = YesNoType.NotSet; var slipstream = YesNoType.NotSet; var hasPayloadInfo = false; - WixBundleExePackageDetectionType? exeDetectionType = WixBundleExePackageDetectionType.None; + WixBundleExePackageDetectionType exeDetectionType = WixBundleExePackageDetectionType.None; string arpId = null; string arpDisplayVersion = null; var arpWin64 = YesNoType.NotSet; @@ -2255,6 +2257,26 @@ private string ParseChainPackage(XElement node, WixBundlePackageType packageType case "DetectCondition": detectCondition = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); allowed = (packageType == WixBundlePackageType.Exe || packageType == WixBundlePackageType.Msu); + + if (exeDetectionType != WixBundleExePackageDetectionType.None) + { + this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "DetectVersionVariable")); + } + exeDetectionType = WixBundleExePackageDetectionType.Condition; + break; + case "DetectVersionVariable": + detectVersionVariable = this.Core.GetAttributeBundleVariableNameValue(sourceLineNumbers, attrib); + allowed = (packageType == WixBundlePackageType.Exe); + + if (exeDetectionType != WixBundleExePackageDetectionType.None) + { + this.Core.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "DetectCondition")); + } + exeDetectionType = WixBundleExePackageDetectionType.VersionVariable; + break; + case "Version": + version = this.Core.GetAttributeValue(sourceLineNumbers, attrib); + allowed = (packageType == WixBundlePackageType.Exe); break; case "Protocol": protocol = this.Core.GetAttributeValue(sourceLineNumbers, attrib); @@ -2332,9 +2354,9 @@ private string ParseChainPackage(XElement node, WixBundlePackageType packageType allowed = packageType == WixBundlePackageType.Exe; if (allowed) { - if (exeDetectionType.Value != WixBundleExePackageDetectionType.None) + if (exeDetectionType != WixBundleExePackageDetectionType.None) { - throw new WixException($"Unexpected WixBundleExePackageDetectionType: {exeDetectionType}"); + this.Core.Write(ErrorMessages.UnexpectedElementWithAttribute(sourceLineNumbers, node.Name.LocalName, child.Name.LocalName, (exeDetectionType == WixBundleExePackageDetectionType.VersionVariable) ? "DetectVersionVariable" : "DetectCondition")); } exeDetectionType = WixBundleExePackageDetectionType.Arp; @@ -2403,7 +2425,7 @@ private string ParseChainPackage(XElement node, WixBundlePackageType packageType } } - if (packageType == WixBundlePackageType.Exe && exeDetectionType.Value == WixBundleExePackageDetectionType.None && (detectCondition != null || uninstallArguments != null)) + if (packageType == WixBundlePackageType.Exe && exeDetectionType == WixBundleExePackageDetectionType.None && (detectCondition != null || uninstallArguments != null)) { exeDetectionType = WixBundleExePackageDetectionType.Condition; } @@ -2438,11 +2460,24 @@ private string ParseChainPackage(XElement node, WixBundlePackageType packageType perMachine = YesNoDefaultType.Default; } + if (version != null && exeDetectionType != WixBundleExePackageDetectionType.VersionVariable) + { + this.Core.Write(ErrorMessages.IllegalAttributeWithoutOtherAttributes(sourceLineNumbers, node.Name.LocalName, "Version", "DetectVersionVariable")); + } + if (exeDetectionType == WixBundleExePackageDetectionType.Arp) { - if (!String.IsNullOrEmpty(detectCondition)) + // Missing attributes are reported when parsing the element. + } + else if (exeDetectionType == WixBundleExePackageDetectionType.VersionVariable) + { + if (String.IsNullOrEmpty(detectVersionVariable)) + { + this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "DetectVersionVariable")); + } + if (String.IsNullOrEmpty(version)) { - this.Core.Write(ErrorMessages.UnexpectedElementWithAttribute(sourceLineNumbers, node.Name.LocalName, "ArpEntry", "DetectCondition")); + version = $"!(bind.packageVersion.{id.Id})"; } } else if (exeDetectionType == WixBundleExePackageDetectionType.Condition) @@ -2631,9 +2666,11 @@ private string ParseChainPackage(XElement node, WixBundlePackageType packageType RepairCommand = repairArguments, UninstallCommand = uninstallArguments, ExeProtocol = protocol, - DetectionType = exeDetectionType.Value, + DetectionType = exeDetectionType, ArpId = arpId, ArpDisplayVersion = arpDisplayVersion, + DetectVersionVariable = detectVersionVariable, + Version = version, }); break; @@ -3406,7 +3443,7 @@ private void CreateRollbackBoundary(SourceLineNumber sourceLineNumbers, Identifi { this.Core.AddSymbol(new WixChainItemSymbol(sourceLineNumbers, id)); - var rollbackBoundary = this.Core.AddSymbol(new WixBundleRollbackBoundarySymbol(sourceLineNumbers, id) + this.Core.AddSymbol(new WixBundleRollbackBoundarySymbol(sourceLineNumbers, id) { Vital = vital == YesNoType.Yes, }); diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/ExePackageFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/ExePackageFixture.cs index b8f1af4d3..7c63dd424 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/ExePackageFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/ExePackageFixture.cs @@ -560,5 +560,169 @@ public void CannotBuildBundleWithExePackageWithoutSourceOrHashOrCertificate() }, result.Messages.Select(m => m.ToString()).ToArray()); } } + + [Fact] + public void CanBuildWithDetectVersionVariable() + { + var folder = TestData.Get(@"TestData"); + + using (var fs = new DisposableFileSystem()) + { + var baseFolder = fs.GetFolder(); + var intermediateFolder = Path.Combine(baseFolder, "obj"); + var binFolder = Path.Combine(baseFolder, "bin"); + var bundlePath = Path.Combine(binFolder, "test.exe"); + var baFolderPath = Path.Combine(baseFolder, "ba"); + var extractFolderPath = Path.Combine(baseFolder, "extract"); + + var result = WixRunner.Execute(new[] + { + "build", + Path.Combine(folder, "ExePackage", "DetectVersionVariable.wxs"), + Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"), + "-bindpath", Path.Combine(folder, "SimpleBundle", "data"), + "-bindpath", Path.Combine(folder, ".Data"), + "-intermediateFolder", intermediateFolder, + "-o", bundlePath, + }); + + result.AssertSuccess(); + + Assert.True(File.Exists(bundlePath)); + + var extractResult = BundleExtractor.ExtractBAContainer(null, bundlePath, baFolderPath, extractFolderPath); + extractResult.AssertSuccess(); + + var exePackages = extractResult.GetManifestTestXmlLines("/burn:BurnManifest/burn:Chain/burn:ExePackage"); + WixAssert.CompareLineByLine(new string[] + { + "" + + "" + + "", + }, exePackages); + } + } + + [Fact] + public void WarningWhenInvalidDetectVersionVariableVersion() + { + var folder = TestData.Get(@"TestData"); + + using (var fs = new DisposableFileSystem()) + { + var baseFolder = fs.GetFolder(); + var intermediateFolder = Path.Combine(baseFolder, "obj"); + var binFolder = Path.Combine(baseFolder, "bin"); + var bundlePath = Path.Combine(binFolder, "test.exe"); + var baFolderPath = Path.Combine(baseFolder, "ba"); + var extractFolderPath = Path.Combine(baseFolder, "extract"); + + var result = WixRunner.Execute(false, new[] + { + "build", + Path.Combine(folder, "ExePackage", "InvalidDetectVersionVariableVersion.wxs"), + Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"), + "-bindpath", Path.Combine(folder, "SimpleBundle", "data"), + "-bindpath", Path.Combine(folder, ".Data"), + "-intermediateFolder", intermediateFolder, + "-o", bundlePath, + }); + + WixAssert.CompareLineByLine(new[] + { + "Invalid WixVersion '1.0.0.abc' in ExePackage/@'Version'. Comparisons may yield unexpected results." + }, result.Messages.Select(m => m.ToString()).ToArray()); + result.AssertSuccess(); + + Assert.True(File.Exists(bundlePath)); + + var extractResult = BundleExtractor.ExtractBAContainer(null, bundlePath, baFolderPath, extractFolderPath); + extractResult.AssertSuccess(); + + var ignoreAttributes = new Dictionary> + { + { "ExePackage", new List { "CacheId", "Size" } }, + }; + var exePackages = extractResult.GetManifestTestXmlLines("/burn:BurnManifest/burn:Chain/burn:ExePackage", ignoreAttributes); + WixAssert.CompareLineByLine(new string[] + { + "" + + "" + + "", + }, exePackages); + } + } + + [Fact] + public void ErrorWhenDetectVersionVariableWithArpEntry() + { + var folder = TestData.Get(@"TestData", "ExePackage"); + + using (var fs = new DisposableFileSystem()) + { + var baseFolder = fs.GetFolder(); + + var result = WixRunner.Execute(new[] + { + "build", + Path.Combine(folder, "ArpEntryAndDetectVersion.wxs"), + "-o", Path.Combine(baseFolder, "test.wixlib") + }); + + WixAssert.CompareLineByLine(new[] + { + "The ExePackage element cannot have a child element 'ArpEntry' when attribute 'DetectVersionVariable' is set.", + }, result.Messages.Select(m => m.ToString()).ToArray()); + Assert.Equal(372, result.ExitCode); + } + } + + [Fact] + public void ErrorWhenDetectVersionVariableWithDetectCondition() + { + var folder = TestData.Get(@"TestData", "ExePackage"); + + using (var fs = new DisposableFileSystem()) + { + var baseFolder = fs.GetFolder(); + + var result = WixRunner.Execute(new[] + { + "build", + Path.Combine(folder, "DetectVersionVariableAndDetectCondition.wxs"), + "-o", Path.Combine(baseFolder, "test.wixlib") + }); + + WixAssert.CompareLineByLine(new[] + { + "The ExePackage/@DetectVersionVariable attribute cannot be specified when attribute DetectCondition is present.", + }, result.Messages.Select(m => m.ToString()).ToArray()); + Assert.Equal(35, result.ExitCode); + } + } + + [Fact] + public void ErrorWhenDetectVersionVariableWithIlegalVariable() + { + var folder = TestData.Get(@"TestData", "ExePackage"); + + using (var fs = new DisposableFileSystem()) + { + var baseFolder = fs.GetFolder(); + + var result = WixRunner.Execute(new[] + { + "build", + Path.Combine(folder, "DetectVersionVariableWithIlegalVariable.wxs"), + "-o", Path.Combine(baseFolder, "test.wixlib") + }); + + WixAssert.CompareLineByLine(new[] + { + "The ExePackage/@DetectVersionVariable attribute's value, '*not*a*variable', is not a legal bundle variable name. Identifiers may contain ASCII characters A-Z, a-z, digits, or underscores (_). Every identifier must begin with either a letter or an underscore.", + }, result.Messages.Select(m => m.ToString()).ToArray()); + Assert.Equal(6603, result.ExitCode); + } + } } } diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/ArpEntryAndDetectVersion.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/ArpEntryAndDetectVersion.wxs new file mode 100644 index 000000000..79075bb6d --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/ArpEntryAndDetectVersion.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/DetectVersionVariable.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/DetectVersionVariable.wxs new file mode 100644 index 000000000..ff7bcaf64 --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/DetectVersionVariable.wxs @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/DetectVersionVariableAndDetectCondition.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/DetectVersionVariableAndDetectCondition.wxs new file mode 100644 index 000000000..856218dd1 --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/DetectVersionVariableAndDetectCondition.wxs @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/DetectVersionVariableWithIlegalVariable.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/DetectVersionVariableWithIlegalVariable.wxs new file mode 100644 index 000000000..26853ca65 --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/DetectVersionVariableWithIlegalVariable.wxs @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/InvalidDetectVersionVariableVersion.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/InvalidDetectVersionVariableVersion.wxs new file mode 100644 index 000000000..8ebe90fbd --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/InvalidDetectVersionVariableVersion.wxs @@ -0,0 +1,11 @@ + + + + + + + +