aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2022-03-01 20:10:52 -0800
committerRob Mensching <rob@firegiant.com>2022-03-01 20:49:18 -0800
commit89c476396d7ad6ab7c596300ec082dd9c38b9121 (patch)
tree3f132caeadccc8cb7369eca2bf700991847eadcd
parentbefcd209d62a25020f46a688002b259c59e4dc3b (diff)
downloadwix-89c476396d7ad6ab7c596300ec082dd9c38b9121.tar.gz
wix-89c476396d7ad6ab7c596300ec082dd9c38b9121.tar.bz2
wix-89c476396d7ad6ab7c596300ec082dd9c38b9121.zip
Improve error reporting wrt ExePackage and MsuPackage attributes
For example, DetectCondition is required when RepairArguments or UninstallArguments present and always recommended. Also, non-permanent ExePackages need UninstallArguments. The code was refactored to make it easier to reason over the different requirements for different package types.
-rw-r--r--src/ext/Bal/test/examples/EarliestCoreBundleFDD/FrameworkDependentBundle.wxs2
-rw-r--r--src/ext/Bal/test/examples/EarliestCoreBundleSCD/SelfContainedBundle.wxs2
-rw-r--r--src/ext/Bal/test/examples/EarliestCoreBundleTrimmedSCD/TrimmedSelfContainedBundle.wxs2
-rw-r--r--src/ext/Bal/test/examples/FullFramework2Bundle/Bundle.wxs2
-rw-r--r--src/ext/Bal/test/examples/FullFramework4Bundle/Bundle.wxs2
-rw-r--r--src/ext/Bal/test/examples/LatestCoreBundleFDD/FrameworkDependentBundle.wxs2
-rw-r--r--src/ext/Bal/test/examples/LatestCoreBundleSCD/SelfContainedBundle.wxs2
-rw-r--r--src/ext/Bal/test/examples/LatestCoreBundleTrimmedSCD/TrimmedSelfContainedBundle.wxs2
-rw-r--r--src/ext/Bal/test/examples/WPFCoreBundleFDD/FrameworkDependentBundle.wxs2
-rw-r--r--src/test/burn/TestData/DependencyTests/BundleE/BundleE.wxs2
-rw-r--r--src/wix/WixToolset.Core/Compiler_Bundle.cs106
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/ExePackageFixture.cs6
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/PayloadFixture.cs2
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/DuplicateCacheIds.wxs4
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/DuplicatePayloadNames.wxs8
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/UnscheduledPackage.wxs6
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/UnscheduledRollbackBoundary.wxs4
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/Dependency/ExePackageProvidesBundle.wxs2
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/MsuPackage/Bundle.wxs2
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/Payload/DownloadUrlPlaceholdersBundle.wxs2
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/Payload/SharedBAAndPackagePayloadBundle.wxs2
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/SingleExeBundle/SingleExePackageGroup.wxs2
22 files changed, 112 insertions, 54 deletions
diff --git a/src/ext/Bal/test/examples/EarliestCoreBundleFDD/FrameworkDependentBundle.wxs b/src/ext/Bal/test/examples/EarliestCoreBundleFDD/FrameworkDependentBundle.wxs
index ce4d8db7..116d5223 100644
--- a/src/ext/Bal/test/examples/EarliestCoreBundleFDD/FrameworkDependentBundle.wxs
+++ b/src/ext/Bal/test/examples/EarliestCoreBundleFDD/FrameworkDependentBundle.wxs
@@ -9,7 +9,7 @@
9 <bal:WixDotNetCoreBootstrapperApplicationHost /> 9 <bal:WixDotNetCoreBootstrapperApplicationHost />
10 </BootstrapperApplication> 10 </BootstrapperApplication>
11 <Chain> 11 <Chain>
12 <ExePackage DetectCondition="none" SourceFile="..\.data\notanexe.exe" bal:PrereqPackage="yes" /> 12 <ExePackage DetectCondition="none" UninstallArguments="-foo" SourceFile="..\.data\notanexe.exe" bal:PrereqPackage="yes" />
13 </Chain> 13 </Chain>
14 </Bundle> 14 </Bundle>
15</Wix> 15</Wix>
diff --git a/src/ext/Bal/test/examples/EarliestCoreBundleSCD/SelfContainedBundle.wxs b/src/ext/Bal/test/examples/EarliestCoreBundleSCD/SelfContainedBundle.wxs
index 3ff2a196..d888d3d9 100644
--- a/src/ext/Bal/test/examples/EarliestCoreBundleSCD/SelfContainedBundle.wxs
+++ b/src/ext/Bal/test/examples/EarliestCoreBundleSCD/SelfContainedBundle.wxs
@@ -5,7 +5,7 @@
5 <PayloadGroupRef Id="publish.Example.EarliestCoreMBA.scd" /> 5 <PayloadGroupRef Id="publish.Example.EarliestCoreMBA.scd" />
6 </BootstrapperApplication> 6 </BootstrapperApplication>
7 <Chain> 7 <Chain>
8 <ExePackage DetectCondition="none" SourceFile="..\.data\notanexe.exe" PerMachine="yes" /> 8 <ExePackage DetectCondition="none" UninstallArguments="-foo" SourceFile="..\.data\notanexe.exe" PerMachine="yes" />
9 </Chain> 9 </Chain>
10 </Bundle> 10 </Bundle>
11</Wix> 11</Wix>
diff --git a/src/ext/Bal/test/examples/EarliestCoreBundleTrimmedSCD/TrimmedSelfContainedBundle.wxs b/src/ext/Bal/test/examples/EarliestCoreBundleTrimmedSCD/TrimmedSelfContainedBundle.wxs
index b0f7a831..5f1aa557 100644
--- a/src/ext/Bal/test/examples/EarliestCoreBundleTrimmedSCD/TrimmedSelfContainedBundle.wxs
+++ b/src/ext/Bal/test/examples/EarliestCoreBundleTrimmedSCD/TrimmedSelfContainedBundle.wxs
@@ -5,7 +5,7 @@
5 <PayloadGroupRef Id="publish.Example.EarliestCoreMBA.trimmedscd" /> 5 <PayloadGroupRef Id="publish.Example.EarliestCoreMBA.trimmedscd" />
6 </BootstrapperApplication> 6 </BootstrapperApplication>
7 <Chain> 7 <Chain>
8 <ExePackage DetectCondition="none" SourceFile="..\.data\notanexe.exe" PerMachine="yes" /> 8 <ExePackage DetectCondition="none" UninstallArguments="-foo" SourceFile="..\.data\notanexe.exe" PerMachine="yes" />
9 </Chain> 9 </Chain>
10 </Bundle> 10 </Bundle>
11</Wix> 11</Wix>
diff --git a/src/ext/Bal/test/examples/FullFramework2Bundle/Bundle.wxs b/src/ext/Bal/test/examples/FullFramework2Bundle/Bundle.wxs
index f3a2b182..cdb15bb0 100644
--- a/src/ext/Bal/test/examples/FullFramework2Bundle/Bundle.wxs
+++ b/src/ext/Bal/test/examples/FullFramework2Bundle/Bundle.wxs
@@ -8,7 +8,7 @@
8 <bal:WixManagedBootstrapperApplicationHost /> 8 <bal:WixManagedBootstrapperApplicationHost />
9 </BootstrapperApplication> 9 </BootstrapperApplication>
10 <Chain> 10 <Chain>
11 <ExePackage DetectCondition="none" SourceFile="..\.data\notanexe.exe" bal:PrereqPackage="yes" /> 11 <ExePackage DetectCondition="none" UninstallArguments="-foo" SourceFile="..\.data\notanexe.exe" bal:PrereqPackage="yes" />
12 </Chain> 12 </Chain>
13 </Bundle> 13 </Bundle>
14</Wix> 14</Wix>
diff --git a/src/ext/Bal/test/examples/FullFramework4Bundle/Bundle.wxs b/src/ext/Bal/test/examples/FullFramework4Bundle/Bundle.wxs
index 31f1eb9b..3602f969 100644
--- a/src/ext/Bal/test/examples/FullFramework4Bundle/Bundle.wxs
+++ b/src/ext/Bal/test/examples/FullFramework4Bundle/Bundle.wxs
@@ -8,7 +8,7 @@
8 <bal:WixManagedBootstrapperApplicationHost /> 8 <bal:WixManagedBootstrapperApplicationHost />
9 </BootstrapperApplication> 9 </BootstrapperApplication>
10 <Chain> 10 <Chain>
11 <ExePackage DetectCondition="none" SourceFile="..\.data\notanexe.exe" bal:PrereqPackage="yes" /> 11 <ExePackage DetectCondition="none" UninstallArguments="-foo" SourceFile="..\.data\notanexe.exe" bal:PrereqPackage="yes" />
12 </Chain> 12 </Chain>
13 </Bundle> 13 </Bundle>
14</Wix> 14</Wix>
diff --git a/src/ext/Bal/test/examples/LatestCoreBundleFDD/FrameworkDependentBundle.wxs b/src/ext/Bal/test/examples/LatestCoreBundleFDD/FrameworkDependentBundle.wxs
index 78ac8220..b29363dd 100644
--- a/src/ext/Bal/test/examples/LatestCoreBundleFDD/FrameworkDependentBundle.wxs
+++ b/src/ext/Bal/test/examples/LatestCoreBundleFDD/FrameworkDependentBundle.wxs
@@ -9,7 +9,7 @@
9 <bal:WixDotNetCoreBootstrapperApplicationHost /> 9 <bal:WixDotNetCoreBootstrapperApplicationHost />
10 </BootstrapperApplication> 10 </BootstrapperApplication>
11 <Chain> 11 <Chain>
12 <ExePackage DetectCondition="none" SourceFile="..\.data\notanexe.exe" bal:PrereqPackage="yes" /> 12 <ExePackage DetectCondition="none" UninstallArguments="-foo" SourceFile="..\.data\notanexe.exe" bal:PrereqPackage="yes" />
13 </Chain> 13 </Chain>
14 </Bundle> 14 </Bundle>
15</Wix> 15</Wix>
diff --git a/src/ext/Bal/test/examples/LatestCoreBundleSCD/SelfContainedBundle.wxs b/src/ext/Bal/test/examples/LatestCoreBundleSCD/SelfContainedBundle.wxs
index a708d0ad..56edc986 100644
--- a/src/ext/Bal/test/examples/LatestCoreBundleSCD/SelfContainedBundle.wxs
+++ b/src/ext/Bal/test/examples/LatestCoreBundleSCD/SelfContainedBundle.wxs
@@ -5,7 +5,7 @@
5 <PayloadGroupRef Id="publish.Example.LatestCoreMBA.scd" /> 5 <PayloadGroupRef Id="publish.Example.LatestCoreMBA.scd" />
6 </BootstrapperApplication> 6 </BootstrapperApplication>
7 <Chain> 7 <Chain>
8 <ExePackage DetectCondition="none" SourceFile="..\.data\notanexe.exe" PerMachine="yes" /> 8 <ExePackage DetectCondition="none" UninstallArguments="-foo" SourceFile="..\.data\notanexe.exe" PerMachine="yes" />
9 </Chain> 9 </Chain>
10 </Bundle> 10 </Bundle>
11</Wix> 11</Wix>
diff --git a/src/ext/Bal/test/examples/LatestCoreBundleTrimmedSCD/TrimmedSelfContainedBundle.wxs b/src/ext/Bal/test/examples/LatestCoreBundleTrimmedSCD/TrimmedSelfContainedBundle.wxs
index f862d396..7ac9c34a 100644
--- a/src/ext/Bal/test/examples/LatestCoreBundleTrimmedSCD/TrimmedSelfContainedBundle.wxs
+++ b/src/ext/Bal/test/examples/LatestCoreBundleTrimmedSCD/TrimmedSelfContainedBundle.wxs
@@ -5,7 +5,7 @@
5 <PayloadGroupRef Id="publish.Example.LatestCoreMBA.trimmedscd" /> 5 <PayloadGroupRef Id="publish.Example.LatestCoreMBA.trimmedscd" />
6 </BootstrapperApplication> 6 </BootstrapperApplication>
7 <Chain> 7 <Chain>
8 <ExePackage DetectCondition="none" SourceFile="..\.data\notanexe.exe" PerMachine="yes" /> 8 <ExePackage DetectCondition="none" UninstallArguments="-foo" SourceFile="..\.data\notanexe.exe" PerMachine="yes" />
9 </Chain> 9 </Chain>
10 </Bundle> 10 </Bundle>
11</Wix> 11</Wix>
diff --git a/src/ext/Bal/test/examples/WPFCoreBundleFDD/FrameworkDependentBundle.wxs b/src/ext/Bal/test/examples/WPFCoreBundleFDD/FrameworkDependentBundle.wxs
index 8d9f5ca4..5f054ca4 100644
--- a/src/ext/Bal/test/examples/WPFCoreBundleFDD/FrameworkDependentBundle.wxs
+++ b/src/ext/Bal/test/examples/WPFCoreBundleFDD/FrameworkDependentBundle.wxs
@@ -9,7 +9,7 @@
9 <bal:WixDotNetCoreBootstrapperApplicationHost /> 9 <bal:WixDotNetCoreBootstrapperApplicationHost />
10 </BootstrapperApplication> 10 </BootstrapperApplication>
11 <Chain> 11 <Chain>
12 <ExePackage DetectCondition="none" SourceFile="..\.data\notanexe.exe" bal:PrereqPackage="yes" /> 12 <ExePackage DetectCondition="none" UninstallArguments="-foo" SourceFile="..\.data\notanexe.exe" bal:PrereqPackage="yes" />
13 </Chain> 13 </Chain>
14 </Bundle> 14 </Bundle>
15</Wix> 15</Wix>
diff --git a/src/test/burn/TestData/DependencyTests/BundleE/BundleE.wxs b/src/test/burn/TestData/DependencyTests/BundleE/BundleE.wxs
index 03b3538b..a2372241 100644
--- a/src/test/burn/TestData/DependencyTests/BundleE/BundleE.wxs
+++ b/src/test/burn/TestData/DependencyTests/BundleE/BundleE.wxs
@@ -9,7 +9,7 @@
9 <PackageGroup Id="BundlePackages"> 9 <PackageGroup Id="BundlePackages">
10 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" /> 10 <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv1.TargetPath)" />
11 <MsiPackage Id="PackageC" SourceFile="$(var.PackageC.TargetPath)" Vital="no" /> 11 <MsiPackage Id="PackageC" SourceFile="$(var.PackageC.TargetPath)" Vital="no" />
12 <ExePackage Id="ExeA" Cache="remove" Vital="no" PerMachine="yes" InstallArguments="/ec 1603" 12 <ExePackage Id="ExeA" Cache="remove" Vital="no" PerMachine="yes" InstallArguments="/ec 1603" UninstallArguments=""
13 DetectCondition="ExeA_Version AND ExeA_Version &gt;= v$(var.Version)"> 13 DetectCondition="ExeA_Version AND ExeA_Version &gt;= v$(var.Version)">
14 <Provides Key="$(var.TestGroupName)_ExeA,v1.0" Version="$(var.Version)" /> 14 <Provides Key="$(var.TestGroupName)_ExeA,v1.0" Version="$(var.Version)" />
15 <PayloadGroupRef Id="TestExePayloads" /> 15 <PayloadGroupRef Id="TestExePayloads" />
diff --git a/src/wix/WixToolset.Core/Compiler_Bundle.cs b/src/wix/WixToolset.Core/Compiler_Bundle.cs
index 3fde990e..dd263484 100644
--- a/src/wix/WixToolset.Core/Compiler_Bundle.cs
+++ b/src/wix/WixToolset.Core/Compiler_Bundle.cs
@@ -6,7 +6,6 @@ namespace WixToolset.Core
6 using System.Collections.Generic; 6 using System.Collections.Generic;
7 using System.Diagnostics; 7 using System.Diagnostics;
8 using System.Globalization; 8 using System.Globalization;
9 using System.IO;
10 using System.Linq; 9 using System.Linq;
11 using System.Xml.Linq; 10 using System.Xml.Linq;
12 using WixToolset.Data; 11 using WixToolset.Data;
@@ -2099,7 +2098,7 @@ namespace WixToolset.Core
2099 allowed = (packageType == WixBundlePackageType.Exe); 2098 allowed = (packageType == WixBundlePackageType.Exe);
2100 break; 2099 break;
2101 case "UninstallArguments": 2100 case "UninstallArguments":
2102 uninstallArguments = this.Core.GetAttributeValue(sourceLineNumbers, attrib); 2101 uninstallArguments = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
2103 allowed = (packageType == WixBundlePackageType.Exe); 2102 allowed = (packageType == WixBundlePackageType.Exe);
2104 break; 2103 break;
2105 case "PerMachine": 2104 case "PerMachine":
@@ -2187,49 +2186,104 @@ namespace WixToolset.Core
2187 rollbackPathVariable = String.Concat("WixBundleRollbackLog_", id.Id); 2186 rollbackPathVariable = String.Concat("WixBundleRollbackLog_", id.Id);
2188 } 2187 }
2189 2188
2190 if (!String.IsNullOrEmpty(protocol) && !protocol.Equals("burn", StringComparison.Ordinal) && !protocol.Equals("netfx4", StringComparison.Ordinal) && !protocol.Equals("none", StringComparison.Ordinal)) 2189 if (packageType == WixBundlePackageType.Exe)
2191 { 2190 {
2192 this.Core.Write(ErrorMessages.IllegalAttributeValueWithLegalList(sourceLineNumbers, node.Name.LocalName, "Protocol", protocol, "none, burn, netfx4")); 2191 // Set default scope for EXEs and MSPs if not already set.
2193 } 2192 if (perMachine == YesNoDefaultType.NotSet)
2193 {
2194 perMachine = YesNoDefaultType.Default;
2195 }
2194 2196
2195 if (!String.IsNullOrEmpty(protocol) && protocol.Equals("netfx4", StringComparison.Ordinal)) 2197 if (permanent == YesNoType.No)
2196 {
2197 foreach (var expectedArgument in expectedNetFx4Args)
2198 { 2198 {
2199 if (null == installArguments || -1 == installArguments.IndexOf(expectedArgument, StringComparison.OrdinalIgnoreCase)) 2199 if (uninstallArguments == null)
2200 { 2200 {
2201 this.Core.Write(WarningMessages.AttributeShouldContain(sourceLineNumbers, node.Name.LocalName, "InstallArguments", installArguments, expectedArgument, "Protocol", "netfx4")); 2201 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "UninstallArguments", "Permanent", "no"));
2202 } 2202 }
2203 }
2204 else if (permanent == YesNoType.NotSet)
2205 {
2206 if (uninstallArguments == null)
2207 {
2208 this.Core.Write(ErrorMessages.ExpectedAttributeWithoutOtherAttribute(sourceLineNumbers, node.Name.LocalName, "UninstallArguments", "Permanent"));
2209 }
2210 }
2203 2211
2204 if (!String.IsNullOrEmpty(repairArguments) && -1 == repairArguments.IndexOf(expectedArgument, StringComparison.OrdinalIgnoreCase)) 2212 // Detect condition is recommended or required for Exe packages (depending on whether repair or uninstall arguments were provided).
2213 if (String.IsNullOrEmpty(detectCondition))
2214 {
2215 if (repairArguments != null)
2205 { 2216 {
2206 this.Core.Write(WarningMessages.AttributeShouldContain(sourceLineNumbers, node.Name.LocalName, "RepairArguments", repairArguments, expectedArgument, "Protocol", "netfx4")); 2217 this.Core.Write(ErrorMessages.ExpectedAttributeWithValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DetectCondition", "RepairArguments"));
2207 } 2218 }
2219 else if (uninstallArguments != null)
2220 {
2221 this.Core.Write(ErrorMessages.ExpectedAttributeWithValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DetectCondition", "UninstallArguments"));
2222 }
2223 else
2224 {
2225 this.Core.Write(WarningMessages.DetectConditionRecommended(sourceLineNumbers, node.Name.LocalName));
2226 }
2227 }
2228
2229 // Validate the protocol if provided.
2230 if (!String.IsNullOrEmpty(protocol))
2231 {
2232 if (protocol.Equals("netfx4", StringComparison.Ordinal))
2233 {
2234 foreach (var expectedArgument in expectedNetFx4Args)
2235 {
2236 if (null == installArguments || -1 == installArguments.IndexOf(expectedArgument, StringComparison.OrdinalIgnoreCase))
2237 {
2238 this.Core.Write(WarningMessages.AttributeShouldContain(sourceLineNumbers, node.Name.LocalName, "InstallArguments", installArguments, expectedArgument, "Protocol", "netfx4"));
2239 }
2208 2240
2209 if (!String.IsNullOrEmpty(uninstallArguments) && -1 == uninstallArguments.IndexOf(expectedArgument, StringComparison.OrdinalIgnoreCase)) 2241 if (!String.IsNullOrEmpty(repairArguments) && -1 == repairArguments.IndexOf(expectedArgument, StringComparison.OrdinalIgnoreCase))
2242 {
2243 this.Core.Write(WarningMessages.AttributeShouldContain(sourceLineNumbers, node.Name.LocalName, "RepairArguments", repairArguments, expectedArgument, "Protocol", "netfx4"));
2244 }
2245
2246 if (!String.IsNullOrEmpty(uninstallArguments) && -1 == uninstallArguments.IndexOf(expectedArgument, StringComparison.OrdinalIgnoreCase))
2247 {
2248 this.Core.Write(WarningMessages.AttributeShouldContain(sourceLineNumbers, node.Name.LocalName, "UninstallArguments", uninstallArguments, expectedArgument, "Protocol", "netfx4"));
2249 }
2250 }
2251 }
2252 else if (!protocol.Equals("burn", StringComparison.Ordinal) && !protocol.Equals("none", StringComparison.Ordinal))
2210 { 2253 {
2211 this.Core.Write(WarningMessages.AttributeShouldContain(sourceLineNumbers, node.Name.LocalName, "UninstallArguments", uninstallArguments, expectedArgument, "Protocol", "netfx4")); 2254 this.Core.Write(ErrorMessages.IllegalAttributeValueWithLegalList(sourceLineNumbers, node.Name.LocalName, "Protocol", protocol, "none, burn, netfx4"));
2212 } 2255 }
2213 } 2256 }
2214 } 2257 }
2215 2258 else if (packageType == WixBundlePackageType.Msp)
2216 // Only set default scope for EXEs and MSPs if not already set.
2217 if ((WixBundlePackageType.Exe == packageType || WixBundlePackageType.Msp == packageType) && YesNoDefaultType.NotSet == perMachine)
2218 { 2259 {
2219 perMachine = YesNoDefaultType.Default; 2260 // Set default scope for EXEs and MSPs if not already set.
2261 if (perMachine == YesNoDefaultType.NotSet)
2262 {
2263 perMachine = YesNoDefaultType.Default;
2264 }
2220 } 2265 }
2221 2266 else if (packageType == WixBundlePackageType.Msu)
2222 // Detect condition is recommended or required for Exe and Msu packages
2223 // (depending on whether uninstall arguments were provided).
2224 if ((packageType == WixBundlePackageType.Exe || packageType == WixBundlePackageType.Msu) && String.IsNullOrEmpty(detectCondition))
2225 { 2267 {
2226 if (String.IsNullOrEmpty(uninstallArguments)) 2268 if (permanent == YesNoType.No)
2227 { 2269 {
2228 this.Core.Write(WarningMessages.DetectConditionRecommended(sourceLineNumbers, node.Name.LocalName)); 2270 if (String.IsNullOrEmpty(msuKB))
2271 {
2272 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "KB", "Permanent", "no"));
2273 }
2229 } 2274 }
2230 else 2275 else if (permanent == YesNoType.NotSet)
2276 {
2277 if (String.IsNullOrEmpty(msuKB))
2278 {
2279 this.Core.Write(ErrorMessages.ExpectedAttributeWithoutOtherAttribute(sourceLineNumbers, node.Name.LocalName, "KB", "Permanent"));
2280 }
2281 }
2282
2283 // Detect condition is recommended for Msu packages.
2284 if (String.IsNullOrEmpty(detectCondition))
2231 { 2285 {
2232 this.Core.Write(ErrorMessages.ExpectedAttributeWithValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "DetectCondition", "UninstallArguments")); 2286 this.Core.Write(WarningMessages.DetectConditionRecommended(sourceLineNumbers, node.Name.LocalName));
2233 } 2287 }
2234 } 2288 }
2235 2289
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/ExePackageFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/ExePackageFixture.cs
index e2306dcd..15885b94 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/ExePackageFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/ExePackageFixture.cs
@@ -3,6 +3,7 @@
3namespace WixToolsetTest.CoreIntegration 3namespace WixToolsetTest.CoreIntegration
4{ 4{
5 using System.IO; 5 using System.IO;
6 using System.Linq;
6 using WixBuildTools.TestSupport; 7 using WixBuildTools.TestSupport;
7 using WixToolset.Core.TestPackage; 8 using WixToolset.Core.TestPackage;
8 using Xunit; 9 using Xunit;
@@ -25,6 +26,11 @@ namespace WixToolsetTest.CoreIntegration
25 "-o", Path.Combine(baseFolder, "test.wixlib") 26 "-o", Path.Combine(baseFolder, "test.wixlib")
26 }); 27 });
27 28
29 WixAssert.CompareLineByLine(new[]
30 {
31 "The ExePackage element's UninstallArguments attribute was not found; it is required without attribute Permanent present.",
32 "The ExePackage/@DetectCondition attribute is recommended so the package is only installed when absent."
33 }, result.Messages.Select(m => m.ToString()).ToArray());
28 Assert.Equal(1153, result.ExitCode); 34 Assert.Equal(1153, result.ExitCode);
29 } 35 }
30 } 36 }
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/PayloadFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/PayloadFixture.cs
index bda642cb..5b663d93 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/PayloadFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/PayloadFixture.cs
@@ -2,13 +2,11 @@
2 2
3namespace WixToolsetTest.CoreIntegration 3namespace WixToolsetTest.CoreIntegration
4{ 4{
5 using System;
6 using System.Collections.Generic; 5 using System.Collections.Generic;
7 using System.IO; 6 using System.IO;
8 using System.Linq; 7 using System.Linq;
9 using System.Xml; 8 using System.Xml;
10 using WixBuildTools.TestSupport; 9 using WixBuildTools.TestSupport;
11 using WixToolset.Core;
12 using WixToolset.Core.TestPackage; 10 using WixToolset.Core.TestPackage;
13 using WixToolset.Data; 11 using WixToolset.Data;
14 using WixToolset.Data.Symbols; 12 using WixToolset.Data.Symbols;
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/DuplicateCacheIds.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/DuplicateCacheIds.wxs
index 0c350042..f404d2ee 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/DuplicateCacheIds.wxs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/DuplicateCacheIds.wxs
@@ -2,8 +2,8 @@
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> 2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Fragment> 3 <Fragment>
4 <PackageGroup Id="BundlePackages"> 4 <PackageGroup Id="BundlePackages">
5 <ExePackage Id="Manual1" SourceFile="burn.exe" Name="manual1\burn.exe" DetectCondition="test" CacheId="!(wix.WixVariable1)" /> 5 <ExePackage Id="Manual1" SourceFile="burn.exe" Name="manual1\burn.exe" DetectCondition="test" UninstallArguments="-u" CacheId="!(wix.WixVariable1)" />
6 <ExePackage Id="Manual2" SourceFile="burn.exe" Name="manual2\burn.exe" DetectCondition="test" CacheId="!(wix.WixVariable2)" /> 6 <ExePackage Id="Manual2" SourceFile="burn.exe" Name="manual2\burn.exe" DetectCondition="test" UninstallArguments="-u" CacheId="!(wix.WixVariable2)" />
7 </PackageGroup> 7 </PackageGroup>
8 8
9 <WixVariable Id="WixVariable1" Value="CollidingCacheId" /> 9 <WixVariable Id="WixVariable1" Value="CollidingCacheId" />
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/DuplicatePayloadNames.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/DuplicatePayloadNames.wxs
index 4fe7e097..002aa18b 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/DuplicatePayloadNames.wxs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/DuplicatePayloadNames.wxs
@@ -2,12 +2,12 @@
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> 2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Fragment> 3 <Fragment>
4 <PackageGroup Id="BundlePackages"> 4 <PackageGroup Id="BundlePackages">
5 <ExePackage Id="Auto1" SourceFile="burn.exe" CacheId="Auto1" DetectCondition="none" /> 5 <ExePackage Id="Auto1" SourceFile="burn.exe" CacheId="Auto1" DetectCondition="none" UninstallArguments="-u" />
6 <ExePackage Id="Auto2" SourceFile="burn.exe" CacheId="Auto2" DetectCondition="none" /> 6 <ExePackage Id="Auto2" SourceFile="burn.exe" CacheId="Auto2" DetectCondition="none" UninstallArguments="-u" />
7 <ExePackage Id="DuplicateCacheIds.wxs" SourceFile="$(sys.SOURCEFILEDIR)DuplicateCacheIds.wxs" Compressed="no" DetectCondition="none" Name="PayloadCollision"> 7 <ExePackage Id="DuplicateCacheIds.wxs" SourceFile="$(sys.SOURCEFILEDIR)DuplicateCacheIds.wxs" Compressed="no" DetectCondition="none" UninstallArguments="-u" Name="PayloadCollision">
8 <Payload SourceFile="$(sys.SOURCEFILEDIR)BundleVariable.wxs" Compressed="no" Name="ContainerCollision" /> 8 <Payload SourceFile="$(sys.SOURCEFILEDIR)BundleVariable.wxs" Compressed="no" Name="ContainerCollision" />
9 </ExePackage> 9 </ExePackage>
10 <ExePackage Id="HiddenPersistedBundleVariable.wxs" SourceFile="$(sys.SOURCEFILEDIR)HiddenPersistedBundleVariable.wxs" Compressed="no" DetectCondition="none" Name="PayloadCollision" /> 10 <ExePackage Id="HiddenPersistedBundleVariable.wxs" SourceFile="$(sys.SOURCEFILEDIR)HiddenPersistedBundleVariable.wxs" Compressed="no" DetectCondition="none" UninstallArguments="-u" Name="PayloadCollision" />
11 <PackageGroupRef Id="MsiPackages" /> 11 <PackageGroupRef Id="MsiPackages" />
12 </PackageGroup> 12 </PackageGroup>
13 13
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/UnscheduledPackage.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/UnscheduledPackage.wxs
index fc53c4a2..5172fed0 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/UnscheduledPackage.wxs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/UnscheduledPackage.wxs
@@ -2,15 +2,15 @@
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> 2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Fragment> 3 <Fragment>
4 <PackageGroup Id="BundlePackages"> 4 <PackageGroup Id="BundlePackages">
5 <ExePackage Id="Auto1" SourceFile="burn.exe" CacheId="Auto1" DetectCondition="none" /> 5 <ExePackage Id="Auto1" SourceFile="burn.exe" CacheId="Auto1" DetectCondition="none" UninstallArguments="-u" />
6 <ExePackage Id="Auto2" SourceFile="burn.exe" CacheId="Auto2" DetectCondition="none" /> 6 <ExePackage Id="Auto2" SourceFile="burn.exe" CacheId="Auto2" DetectCondition="none" UninstallArguments="-u" />
7 </PackageGroup> 7 </PackageGroup>
8 <SetVariableRef Id="Dummy" /> 8 <SetVariableRef Id="Dummy" />
9 </Fragment> 9 </Fragment>
10 <Fragment> 10 <Fragment>
11 <SetVariable Id="Dummy" Variable="Dummy" /> 11 <SetVariable Id="Dummy" Variable="Dummy" />
12 <PackageGroup Id="Unscheduled"> 12 <PackageGroup Id="Unscheduled">
13 <ExePackage Id="Unscheduled1" SourceFile="burn.exe" CacheId="Unscheduled1" DetectCondition="none" /> 13 <ExePackage Id="Unscheduled1" SourceFile="burn.exe" CacheId="Unscheduled1" DetectCondition="none" UninstallArguments="-u" />
14 </PackageGroup> 14 </PackageGroup>
15 </Fragment> 15 </Fragment>
16</Wix> 16</Wix>
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/UnscheduledRollbackBoundary.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/UnscheduledRollbackBoundary.wxs
index 6cf8528e..de67d001 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/UnscheduledRollbackBoundary.wxs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BadInput/UnscheduledRollbackBoundary.wxs
@@ -2,8 +2,8 @@
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> 2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Fragment> 3 <Fragment>
4 <PackageGroup Id="BundlePackages"> 4 <PackageGroup Id="BundlePackages">
5 <ExePackage Id="Auto1" SourceFile="burn.exe" CacheId="Auto1" DetectCondition="none" /> 5 <ExePackage Id="Auto1" SourceFile="burn.exe" CacheId="Auto1" DetectCondition="none" UninstallArguments="-u" />
6 <ExePackage Id="Auto2" SourceFile="burn.exe" CacheId="Auto2" DetectCondition="none" /> 6 <ExePackage Id="Auto2" SourceFile="burn.exe" CacheId="Auto2" DetectCondition="none" UninstallArguments="-u" />
7 </PackageGroup> 7 </PackageGroup>
8 <SetVariableRef Id="Dummy" /> 8 <SetVariableRef Id="Dummy" />
9 </Fragment> 9 </Fragment>
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Dependency/ExePackageProvidesBundle.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Dependency/ExePackageProvidesBundle.wxs
index 4d188d3a..2f7d41c7 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Dependency/ExePackageProvidesBundle.wxs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Dependency/ExePackageProvidesBundle.wxs
@@ -2,7 +2,7 @@
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> 2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Fragment> 3 <Fragment>
4 <PackageGroup Id="BundlePackages"> 4 <PackageGroup Id="BundlePackages">
5 <ExePackage DetectCondition="DetectedSomething" SourceFile="burn.exe"> 5 <ExePackage DetectCondition="DetectedSomething" UninstallArguments="-u" SourceFile="burn.exe">
6 <Provides Key="DependencyTests_ExeA,v1.0" Version="1.0.0.0" /> 6 <Provides Key="DependencyTests_ExeA,v1.0" Version="1.0.0.0" />
7 </ExePackage> 7 </ExePackage>
8 </PackageGroup> 8 </PackageGroup>
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/MsuPackage/Bundle.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/MsuPackage/Bundle.wxs
index dbca3393..48222546 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/MsuPackage/Bundle.wxs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/MsuPackage/Bundle.wxs
@@ -5,7 +5,7 @@
5 </BootstrapperApplication> 5 </BootstrapperApplication>
6 6
7 <Chain> 7 <Chain>
8 <MsuPackage DetectCondition="DetectedTheMsu" SourceFile="test.msu" /> 8 <MsuPackage DetectCondition="DetectedTheMsu" KB="xyz" SourceFile="test.msu" />
9 </Chain> 9 </Chain>
10 </Bundle> 10 </Bundle>
11</Wix> 11</Wix>
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Payload/DownloadUrlPlaceholdersBundle.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Payload/DownloadUrlPlaceholdersBundle.wxs
index f8f38ea6..f077c418 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Payload/DownloadUrlPlaceholdersBundle.wxs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Payload/DownloadUrlPlaceholdersBundle.wxs
@@ -14,7 +14,7 @@
14 </Bundle> 14 </Bundle>
15 <Fragment> 15 <Fragment>
16 <PackageGroup Id="ContainerPackages"> 16 <PackageGroup Id="ContainerPackages">
17 <ExePackage SourceFile="burn.exe" DetectCondition="none" Compressed="no" /> 17 <ExePackage SourceFile="burn.exe" DetectCondition="none" UninstallArguments="-u" Compressed="no" />
18 </PackageGroup> 18 </PackageGroup>
19 </Fragment> 19 </Fragment>
20 <Fragment> 20 <Fragment>
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Payload/SharedBAAndPackagePayloadBundle.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Payload/SharedBAAndPackagePayloadBundle.wxs
index 5263cbd4..5bfa2972 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Payload/SharedBAAndPackagePayloadBundle.wxs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/Payload/SharedBAAndPackagePayloadBundle.wxs
@@ -2,7 +2,7 @@
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> 2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Fragment> 3 <Fragment>
4 <PackageGroup Id="BundlePackages"> 4 <PackageGroup Id="BundlePackages">
5 <ExePackage SourceFile="burn.exe" DetectCondition="none"> 5 <ExePackage SourceFile="burn.exe" DetectCondition="none" UninstallArguments="-u">
6 <PayloadGroupRef Id="Shared" /> 6 <PayloadGroupRef Id="Shared" />
7 </ExePackage> 7 </ExePackage>
8 </PackageGroup> 8 </PackageGroup>
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/SingleExeBundle/SingleExePackageGroup.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/SingleExeBundle/SingleExePackageGroup.wxs
index cad1f049..ce0db542 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/SingleExeBundle/SingleExePackageGroup.wxs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/SingleExeBundle/SingleExePackageGroup.wxs
@@ -2,7 +2,7 @@
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> 2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Fragment> 3 <Fragment>
4 <PackageGroup Id="BundlePackages"> 4 <PackageGroup Id="BundlePackages">
5 <ExePackage DetectCondition="DetectedSomething" SourceFile="burn.exe" /> 5 <ExePackage DetectCondition="DetectedSomething" UninstallArguments="-uninstall" SourceFile="burn.exe" />
6 </PackageGroup> 6 </PackageGroup>
7 </Fragment> 7 </Fragment>
8</Wix> 8</Wix>