aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNir Bar <nir.bar@panel-sw.co.il>2023-11-20 18:00:03 +0200
committerBob Arnson <github@bobs.org>2023-12-24 17:30:44 -0500
commit6f4fda58d9303c889024e20ee39b1374ed0f02e1 (patch)
treeb940085ebd2bc0dd97bbebe6eb77bce3b5a73f90
parentf02ef4acf9649badaa3ab78d2499ca5014fa2234 (diff)
downloadwix-6f4fda58d9303c889024e20ee39b1374ed0f02e1.tar.gz
wix-6f4fda58d9303c889024e20ee39b1374ed0f02e1.tar.bz2
wix-6f4fda58d9303c889024e20ee39b1374ed0f02e1.zip
ArpEntry reads QuietUninstallString or UninstallString, and uses UninstallArguments for the uninstall command line
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundleExePackageSymbol.cs17
-rw-r--r--src/burn/engine/exeengine.cpp26
-rw-r--r--src/burn/engine/package.h1
-rw-r--r--src/test/burn/TestData/ExePackageTests/PerMachineArpEntryWithUninstallStringExePackage/PerMachineArpEntryWithUninstallStringExePackage.wixproj19
-rw-r--r--src/test/burn/TestData/ExePackageTests/PerMachineArpEntryWithUninstallStringExePackage/PerMachineArpEntryWithUninstallStringExePackage.wxs18
-rw-r--r--src/test/burn/WixToolsetTest.BurnE2E/ExePackageTests.cs22
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs10
-rw-r--r--src/wix/WixToolset.Core/Compiler_Bundle.cs51
8 files changed, 135 insertions, 29 deletions
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleExePackageSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleExePackageSymbol.cs
index 74146716..0fcc6dd1 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundleExePackageSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleExePackageSymbol.cs
@@ -57,6 +57,7 @@ namespace WixToolset.Data.Symbols
57 None = 0, 57 None = 0,
58 Bundle = 1, 58 Bundle = 1,
59 ArpWin64 = 2, 59 ArpWin64 = 2,
60 ArpUseUninstallString = 4,
60 } 61 }
61 62
62 public class WixBundleExePackageSymbol : IntermediateSymbol 63 public class WixBundleExePackageSymbol : IntermediateSymbol
@@ -157,6 +158,22 @@ namespace WixToolset.Data.Symbols
157 } 158 }
158 } 159 }
159 160
161 public bool ArpUseUninstallString
162 {
163 get { return this.Attributes.HasFlag(WixBundleExePackageAttributes.ArpUseUninstallString); }
164 set
165 {
166 if (value)
167 {
168 this.Attributes |= WixBundleExePackageAttributes.ArpUseUninstallString;
169 }
170 else
171 {
172 this.Attributes &= ~WixBundleExePackageAttributes.ArpUseUninstallString;
173 }
174 }
175 }
176
160 public bool Repairable => this.RepairCommand != null; 177 public bool Repairable => this.RepairCommand != null;
161 178
162 public bool Uninstallable => this.UninstallCommand != null; 179 public bool Uninstallable => this.UninstallCommand != null;
diff --git a/src/burn/engine/exeengine.cpp b/src/burn/engine/exeengine.cpp
index 6d326a5a..c0bab254 100644
--- a/src/burn/engine/exeengine.cpp
+++ b/src/burn/engine/exeengine.cpp
@@ -81,6 +81,14 @@ extern "C" HRESULT ExeEngineParsePackageFromXml(
81 hr = XmlGetYesNoAttribute(pixnExePackage, L"ArpWin64", &pPackage->Exe.fArpWin64); 81 hr = XmlGetYesNoAttribute(pixnExePackage, L"ArpWin64", &pPackage->Exe.fArpWin64);
82 ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @ArpWin64."); 82 ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @ArpWin64.");
83 83
84 // @ArpUseUninstallString
85 hr = XmlGetYesNoAttribute(pixnExePackage, L"ArpUseUninstallString", &pPackage->Exe.fArpUseUninstallString);
86 ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @ArpWin64.");
87
88 // @UninstallArguments
89 hr = XmlGetAttributeEx(pixnExePackage, L"UninstallArguments", &pPackage->Exe.sczUninstallArguments);
90 ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @UninstallArguments.");
91
84 pPackage->Exe.fUninstallable = TRUE; 92 pPackage->Exe.fUninstallable = TRUE;
85 } 93 }
86 94
@@ -481,7 +489,7 @@ extern "C" HRESULT ExeEngineExecutePackage(
481 } 489 }
482 else if (BURN_EXE_DETECTION_TYPE_ARP == pPackage->Exe.detectionType && BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pExecuteAction->exePackage.action) 490 else if (BURN_EXE_DETECTION_TYPE_ARP == pPackage->Exe.detectionType && BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pExecuteAction->exePackage.action)
483 { 491 {
484 ExitOnNull(sczArpUninstallString, hr, E_INVALIDARG, "QuietUninstallString is null."); 492 ExitOnNull(sczArpUninstallString, hr, E_INVALIDARG, "%hs is null.", pPackage->Exe.fArpUseUninstallString ? "UninstallString" : "QuietUninstallString");
485 493
486 hr = AppParseCommandLine(sczArpUninstallString, &argcArp, &argvArp); 494 hr = AppParseCommandLine(sczArpUninstallString, &argcArp, &argvArp);
487 ExitOnFailure(hr, "Failed to parse QuietUninstallString: %ls.", sczArpUninstallString); 495 ExitOnFailure(hr, "Failed to parse QuietUninstallString: %ls.", sczArpUninstallString);
@@ -1122,8 +1130,20 @@ static HRESULT DetectArpEntry(
1122 1130
1123 if (psczQuietUninstallString) 1131 if (psczQuietUninstallString)
1124 { 1132 {
1125 hr = RegReadString(hKey, L"QuietUninstallString", psczQuietUninstallString); 1133 LPCWSTR sczUninstallStringName = pPackage->Exe.fArpUseUninstallString ? L"UninstallString" : L"QuietUninstallString";
1126 ExitOnPathFailure(hr, fExists, "Failed to read QuietUninstallString."); 1134
1135 hr = RegReadString(hKey, sczUninstallStringName, psczQuietUninstallString);
1136 ExitOnPathFailure(hr, fExists, "Failed to read %ls.", sczUninstallStringName);
1137
1138 // If the uninstall string is an executable path then ensure it is enclosed in quotes
1139 if (fExists && *psczQuietUninstallString && (L'\"' != **psczQuietUninstallString) && FileExistsEx(*psczQuietUninstallString, nullptr))
1140 {
1141 hr = StrAllocPrefix(psczQuietUninstallString, L"\"", 0);
1142 ExitOnFailure(hr, "Failed to prepend UninstallString with quote.");
1143
1144 hr = StrAllocConcat(psczQuietUninstallString, L"\"", 0);
1145 ExitOnFailure(hr, "Failed to append quote to UninstallString.");
1146 }
1127 } 1147 }
1128 1148
1129LExit: 1149LExit:
diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h
index bdebd5b6..1ea169e6 100644
--- a/src/burn/engine/package.h
+++ b/src/burn/engine/package.h
@@ -362,6 +362,7 @@ typedef struct _BURN_PACKAGE
362 BURN_EXE_DETECTION_TYPE detectionType; 362 BURN_EXE_DETECTION_TYPE detectionType;
363 363
364 BOOL fArpWin64; 364 BOOL fArpWin64;
365 BOOL fArpUseUninstallString;
365 LPWSTR sczArpKeyPath; 366 LPWSTR sczArpKeyPath;
366 VERUTIL_VERSION* pArpDisplayVersion; 367 VERUTIL_VERSION* pArpDisplayVersion;
367 368
diff --git a/src/test/burn/TestData/ExePackageTests/PerMachineArpEntryWithUninstallStringExePackage/PerMachineArpEntryWithUninstallStringExePackage.wixproj b/src/test/burn/TestData/ExePackageTests/PerMachineArpEntryWithUninstallStringExePackage/PerMachineArpEntryWithUninstallStringExePackage.wixproj
new file mode 100644
index 00000000..afdd9e5b
--- /dev/null
+++ b/src/test/burn/TestData/ExePackageTests/PerMachineArpEntryWithUninstallStringExePackage/PerMachineArpEntryWithUninstallStringExePackage.wixproj
@@ -0,0 +1,19 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup>
4 <OutputType>Bundle</OutputType>
5 <InstallerPlatform>x64</InstallerPlatform>
6 <BA>TestBA_x64</BA>
7 <UpgradeCode>{0A3D66F0-21A8-41B5-BE9A-7A9ABDEC3AB5}</UpgradeCode>
8 </PropertyGroup>
9 <ItemGroup>
10 <Compile Include="..\..\Templates\Bundle.wxs" Link="Bundle.wxs" />
11 </ItemGroup>
12 <ItemGroup>
13 <ProjectReference Include="..\..\TestBA\TestBAWixlib_x64\testbawixlib_x64.wixproj" />
14 </ItemGroup>
15 <ItemGroup>
16 <PackageReference Include="WixToolset.Bal.wixext" />
17 <PackageReference Include="WixToolset.NetFx.wixext" />
18 </ItemGroup>
19</Project>
diff --git a/src/test/burn/TestData/ExePackageTests/PerMachineArpEntryWithUninstallStringExePackage/PerMachineArpEntryWithUninstallStringExePackage.wxs b/src/test/burn/TestData/ExePackageTests/PerMachineArpEntryWithUninstallStringExePackage/PerMachineArpEntryWithUninstallStringExePackage.wxs
new file mode 100644
index 00000000..58198257
--- /dev/null
+++ b/src/test/burn/TestData/ExePackageTests/PerMachineArpEntryWithUninstallStringExePackage/PerMachineArpEntryWithUninstallStringExePackage.wxs
@@ -0,0 +1,18 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2
3<?define ArpId = {21E99C0F-E604-439C-97E0-33B9771394BC}?>
4<?define ArpKeyPath = HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(var.ArpId)?>
5<?define ArpVersion = 1.0.0.0?>
6
7<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
8 <Fragment>
9 <PackageGroup Id="BundlePackages">
10 <ExePackage Id="TestExe" PerMachine="yes"
11 InstallArguments="/regw &quot;$(var.ArpKeyPath),DisplayVersion,String,$(var.ArpVersion)&quot; /regw &quot;$(var.ArpKeyPath),UninstallString,String,\&quot;[WixBundleExecutePackageCacheFolder]testexe.exe\&quot; /regd \&quot;$(var.ArpKeyPath)\&quot;&quot;">
12 <ArpEntry Id="$(var.ArpId)" Version="$(var.ArpVersion)" Win64="yes" UseUninstallString="yes" />
13
14 <PayloadGroupRef Id="TestExePayloads_x64" />
15 </ExePackage>
16 </PackageGroup>
17 </Fragment>
18</Wix>
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/ExePackageTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/ExePackageTests.cs
index 42301f30..dc0b6b5a 100644
--- a/src/test/burn/WixToolsetTest.BurnE2E/ExePackageTests.cs
+++ b/src/test/burn/WixToolsetTest.BurnE2E/ExePackageTests.cs
@@ -34,6 +34,28 @@ namespace WixToolsetTest.BurnE2E
34 } 34 }
35 35
36 [RuntimeFact] 36 [RuntimeFact]
37 public void CanInstallAndUninstallPerMachineArpEntryWithUninstallStringExePackage()
38 {
39 var perMachineArpEntryExePackageBundle = this.CreateBundleInstaller(@"PerMachineArpEntryWithUninstallStringExePackage");
40 var arpEntryExePackage = this.CreateArpEntryInstaller(perMachineArpEntryExePackageBundle, "TestExe");
41 var arpId = arpEntryExePackage.ArpId;
42
43 arpEntryExePackage.VerifyRegistered(false);
44
45 var installLogPath = perMachineArpEntryExePackageBundle.Install();
46 perMachineArpEntryExePackageBundle.VerifyRegisteredAndInPackageCache();
47 arpEntryExePackage.VerifyRegistered(true);
48
49 Assert.True(LogVerifier.MessageInLogFile(installLogPath, $"TestExe.exe\" /regw \"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{arpId},DisplayVersion,String,1.0.0.0\" /regw \"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{arpId},UninstallString,String,\\\""));
50
51 var uninstallLogPath = perMachineArpEntryExePackageBundle.Uninstall();
52 perMachineArpEntryExePackageBundle.VerifyUnregisteredAndRemovedFromPackageCache();
53 arpEntryExePackage.VerifyRegistered(false);
54
55 Assert.True(LogVerifier.MessageInLogFile(uninstallLogPath, $"testexe.exe\" /regd HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{arpId}"));
56 }
57
58 [RuntimeFact]
37 public void CanRecacheAndReinstallPerMachineArpEntryExePackageOnUninstallRollback() 59 public void CanRecacheAndReinstallPerMachineArpEntryExePackageOnUninstallRollback()
38 { 60 {
39 var packageTestExe = this.CreatePackageInstaller("PackageTestExe"); 61 var packageTestExe = this.CreatePackageInstaller("PackageTestExe");
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
index ec418bc1..0a11ea3a 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
@@ -436,6 +436,16 @@ namespace WixToolset.Core.Burn.Bundles
436 { 436 {
437 writer.WriteAttributeString("ArpWin64", "yes"); 437 writer.WriteAttributeString("ArpWin64", "yes");
438 } 438 }
439
440 if (exePackage.ArpUseUninstallString)
441 {
442 writer.WriteAttributeString("ArpUseUninstallString", "yes");
443 }
444
445 if (!String.IsNullOrEmpty(exePackage.UninstallCommand))
446 {
447 writer.WriteAttributeString("UninstallArguments", exePackage.UninstallCommand);
448 }
439 break; 449 break;
440 case WixBundleExePackageDetectionType.None: 450 case WixBundleExePackageDetectionType.None:
441 writer.WriteAttributeString("DetectionType", "none"); 451 writer.WriteAttributeString("DetectionType", "none");
diff --git a/src/wix/WixToolset.Core/Compiler_Bundle.cs b/src/wix/WixToolset.Core/Compiler_Bundle.cs
index 89826cf6..7790d50d 100644
--- a/src/wix/WixToolset.Core/Compiler_Bundle.cs
+++ b/src/wix/WixToolset.Core/Compiler_Bundle.cs
@@ -1997,10 +1997,11 @@ namespace WixToolset.Core
1997 var bundle = YesNoType.NotSet; 1997 var bundle = YesNoType.NotSet;
1998 var slipstream = YesNoType.NotSet; 1998 var slipstream = YesNoType.NotSet;
1999 var hasPayloadInfo = false; 1999 var hasPayloadInfo = false;
2000 WixBundleExePackageDetectionType? exeDetectionType = WixBundleExePackageDetectionType.None; 2000 WixBundleExePackageDetectionType exeDetectionType = WixBundleExePackageDetectionType.None;
2001 string arpId = null; 2001 string arpId = null;
2002 string arpDisplayVersion = null; 2002 string arpDisplayVersion = null;
2003 var arpWin64 = YesNoType.NotSet; 2003 var arpWin64 = YesNoType.NotSet;
2004 var arpUseUninstallString = YesNoType.NotSet;
2004 2005
2005 var expectedNetFx4Args = new string[] { "/q", "/norestart" }; 2006 var expectedNetFx4Args = new string[] { "/q", "/norestart" };
2006 2007
@@ -2117,6 +2118,7 @@ namespace WixToolset.Core
2117 case "DetectCondition": 2118 case "DetectCondition":
2118 detectCondition = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); 2119 detectCondition = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty);
2119 allowed = (packageType == WixBundlePackageType.Exe || packageType == WixBundlePackageType.Msu); 2120 allowed = (packageType == WixBundlePackageType.Exe || packageType == WixBundlePackageType.Msu);
2121 exeDetectionType = WixBundleExePackageDetectionType.Condition;
2120 break; 2122 break;
2121 case "Protocol": 2123 case "Protocol":
2122 protocol = this.Core.GetAttributeValue(sourceLineNumbers, attrib); 2124 protocol = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
@@ -2183,11 +2185,6 @@ namespace WixToolset.Core
2183 this.Core.ParseExtensionAttribute(node, attribute, contextValues); 2185 this.Core.ParseExtensionAttribute(node, attribute, contextValues);
2184 } 2186 }
2185 2187
2186 if (packageType == WixBundlePackageType.Exe && (detectCondition != null || uninstallArguments != null))
2187 {
2188 exeDetectionType = WixBundleExePackageDetectionType.Condition;
2189 }
2190
2191 foreach (var child in node.Elements()) 2188 foreach (var child in node.Elements())
2192 { 2189 {
2193 if (CompilerCore.WixNamespace == child.Name.Namespace) 2190 if (CompilerCore.WixNamespace == child.Name.Namespace)
@@ -2199,25 +2196,17 @@ namespace WixToolset.Core
2199 allowed = packageType == WixBundlePackageType.Exe; 2196 allowed = packageType == WixBundlePackageType.Exe;
2200 if (allowed) 2197 if (allowed)
2201 { 2198 {
2202 if (exeDetectionType == WixBundleExePackageDetectionType.Arp) 2199 if (exeDetectionType != WixBundleExePackageDetectionType.None)
2203 { 2200 {
2204 this.Core.Write(ErrorMessages.TooManyChildren(Preprocessor.GetSourceLineNumbers(child), node.Name.LocalName, child.Name.LocalName)); 2201 this.Core.Write(ErrorMessages.UnexpectedElementWithAttribute(sourceLineNumbers, node.Name.LocalName, child.Name.LocalName, "DetectCondition"));
2205 } 2202 }
2206 else if (!exeDetectionType.HasValue || exeDetectionType.Value == WixBundleExePackageDetectionType.Condition) 2203 if (null != uninstallArguments)
2207 { 2204 {
2208 exeDetectionType = null; 2205 this.Core.Write(ErrorMessages.UnexpectedElementWithAttribute(sourceLineNumbers, node.Name.LocalName, child.Name.LocalName, "UninstallArguments"));
2209 }
2210 else
2211 {
2212 if (exeDetectionType.Value != WixBundleExePackageDetectionType.None)
2213 {
2214 throw new WixException($"Unexpected WixBundleExePackageDetectionType: {exeDetectionType}");
2215 }
2216
2217 exeDetectionType = WixBundleExePackageDetectionType.Arp;
2218 } 2206 }
2219 2207
2220 this.ParseExePackageArpEntryElement(child, out arpId, out arpDisplayVersion, out arpWin64); 2208 exeDetectionType = WixBundleExePackageDetectionType.Arp;
2209 this.ParseExePackageArpEntryElement(child, out arpId, out arpDisplayVersion, out arpWin64, out uninstallArguments, out arpUseUninstallString);
2221 } 2210 }
2222 break; 2211 break;
2223 case "SlipstreamMsp": 2212 case "SlipstreamMsp":
@@ -2282,6 +2271,11 @@ namespace WixToolset.Core
2282 } 2271 }
2283 } 2272 }
2284 2273
2274 if (packageType == WixBundlePackageType.Exe && exeDetectionType == WixBundleExePackageDetectionType.None && uninstallArguments != null)
2275 {
2276 exeDetectionType = WixBundleExePackageDetectionType.Condition;
2277 }
2278
2285 if (id.Id == BurnConstants.BundleDefaultBoundaryId) 2279 if (id.Id == BurnConstants.BundleDefaultBoundaryId)
2286 { 2280 {
2287 this.Messaging.Write(CompilerErrors.ReservedValue(sourceLineNumbers, node.Name.LocalName, "Id", id.Id)); 2281 this.Messaging.Write(CompilerErrors.ReservedValue(sourceLineNumbers, node.Name.LocalName, "Id", id.Id));
@@ -2374,10 +2368,6 @@ namespace WixToolset.Core
2374 this.Core.Write(WarningMessages.ExePackageDetectInformationRecommended(sourceLineNumbers)); 2368 this.Core.Write(WarningMessages.ExePackageDetectInformationRecommended(sourceLineNumbers));
2375 } 2369 }
2376 } 2370 }
2377 else
2378 {
2379 this.Core.Write(ErrorMessages.UnexpectedElementWithAttribute(sourceLineNumbers, node.Name.LocalName, "ArpEntry", String.IsNullOrEmpty(detectCondition) ? "UninstallArguments" : "DetectCondition"));
2380 }
2381 2371
2382 if (repairArguments == null && repairCondition != null) 2372 if (repairArguments == null && repairCondition != null)
2383 { 2373 {
@@ -2497,6 +2487,7 @@ namespace WixToolset.Core
2497 WixBundleExePackageAttributes exeAttributes = 0; 2487 WixBundleExePackageAttributes exeAttributes = 0;
2498 exeAttributes |= (YesNoType.Yes == bundle) ? WixBundleExePackageAttributes.Bundle : 0; 2488 exeAttributes |= (YesNoType.Yes == bundle) ? WixBundleExePackageAttributes.Bundle : 0;
2499 exeAttributes |= (YesNoType.Yes == arpWin64) ? WixBundleExePackageAttributes.ArpWin64 : 0; 2489 exeAttributes |= (YesNoType.Yes == arpWin64) ? WixBundleExePackageAttributes.ArpWin64 : 0;
2490 exeAttributes |= (YesNoType.Yes == arpUseUninstallString) ? WixBundleExePackageAttributes.ArpUseUninstallString : 0;
2500 2491
2501 this.Core.AddSymbol(new WixBundleExePackageSymbol(sourceLineNumbers, id) 2492 this.Core.AddSymbol(new WixBundleExePackageSymbol(sourceLineNumbers, id)
2502 { 2493 {
@@ -2506,7 +2497,7 @@ namespace WixToolset.Core
2506 RepairCommand = repairArguments, 2497 RepairCommand = repairArguments,
2507 UninstallCommand = uninstallArguments, 2498 UninstallCommand = uninstallArguments,
2508 ExeProtocol = protocol, 2499 ExeProtocol = protocol,
2509 DetectionType = exeDetectionType.Value, 2500 DetectionType = exeDetectionType,
2510 ArpId = arpId, 2501 ArpId = arpId,
2511 ArpDisplayVersion = arpDisplayVersion, 2502 ArpDisplayVersion = arpDisplayVersion,
2512 }); 2503 });
@@ -2971,12 +2962,14 @@ namespace WixToolset.Core
2971 } 2962 }
2972 } 2963 }
2973 2964
2974 private void ParseExePackageArpEntryElement(XElement node, out string id, out string version, out YesNoType win64) 2965 private void ParseExePackageArpEntryElement(XElement node, out string id, out string version, out YesNoType win64, out string uninstallArguments, out YesNoType arpUseUninstallString)
2975 { 2966 {
2976 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 2967 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
2977 id = null; 2968 id = null;
2978 version = null; 2969 version = null;
2979 win64 = YesNoType.NotSet; 2970 win64 = YesNoType.NotSet;
2971 arpUseUninstallString = YesNoType.NotSet;
2972 uninstallArguments = null;
2980 2973
2981 foreach (var attrib in node.Attributes()) 2974 foreach (var attrib in node.Attributes())
2982 { 2975 {
@@ -2990,6 +2983,12 @@ namespace WixToolset.Core
2990 case "Version": 2983 case "Version":
2991 version = this.Core.GetAttributeValue(sourceLineNumbers, attrib); 2984 version = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2992 break; 2985 break;
2986 case "AdditionalUninstallArguments":
2987 uninstallArguments = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2988 break;
2989 case "UseUninstallString":
2990 arpUseUninstallString = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2991 break;
2993 case "Win64": 2992 case "Win64":
2994 win64 = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); 2993 win64 = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2995 break; 2994 break;