Warn about unsuffixed custom action ids.
Fixes https://github.com/wixtoolset/issues/issues/7018.
Bob Arnson committed
Nov 16, 2022 at 20:27 UTC
13292da793c9e0792d3ecd86974304b8b2a51d7a
2 files changed
+110
-1
src/wix/WixToolset.Converters/WixConverter.cs
+78
-1
@@ -78,6 +78,7 @@ namespace WixToolset.Converters
78
private static readonly XName BundleCustomDataElementName = WixNamespace + "BundleCustomData";
79
private static readonly XName BundleCustomDataRefElementName = WixNamespace + "BundleCustomDataRef";
80
private static readonly XName BundleElementElementName = WixNamespace + "BundleElement";
81
+ private static readonly XName CustomElementName = WixNamespace + "Custom";
82
private static readonly XName CustomTableElementName = WixNamespace + "CustomTable";
83
private static readonly XName CustomTableRefElementName = WixNamespace + "CustomTableRef";
84
private static readonly XName CatalogElementName = WixNamespace + "Catalog";
@@ -97,7 +98,6 @@ namespace WixToolset.Converters
98
private static readonly XName FileElementName = WixNamespace + "File";
99
private static readonly XName FragmentElementName = WixNamespace + "Fragment";
100
private static readonly XName FirewallRemoteAddressElementName = WixFirewallNamespace + "RemoteAddress";
100
- private static readonly XName GetCapabilitiesElementName = WixFirewallNamespace + "GetCapabilities";
101
private static readonly XName LaunchElementName = WixNamespace + "Launch";
102
private static readonly XName LevelElementName = WixNamespace + "Level";
103
private static readonly XName ExePackageElementName = WixNamespace + "ExePackage";
@@ -196,6 +196,65 @@ namespace WixToolset.Converters
196
{ "http://schemas.microsoft.com/wix/2006/WixUnit", "http://wixtoolset.org/schemas/v4/wixunit" },
197
};
198
199
+ private static readonly Dictionary<string, string> CustomActionIdsWithPlatformSuffix = new Dictionary<string, string>()
200
+ {
201
+ { "ConfigureComPlusUninstall", "Wix4ConfigureComPlusUninstall_<PlatformSuffix>" },
202
+ { "ConfigureComPlusInstall", "Wix4ConfigureComPlusInstall_<PlatformSuffix>" },
203
+ { "WixDependencyRequire", "Wix4DependencyRequire_<PlatformSuffix>" },
204
+ { "WixDependencyCheck", "Wix4DependencyCheck_<PlatformSuffix>" },
205
+ { "WixQueryDirectXCaps", "Wix4QueryDirectXCaps_<PlatformSuffix>" },
206
+ { "WixSchedFirewallExceptionsUninstall", "Wix4SchedFirewallExceptionsUninstall_<PlatformSuffix>" },
207
+ { "WixSchedFirewallExceptionsInstall", "Wix4SchedFirewallExceptionsInstall_<PlatformSuffix>" },
208
+ { "WixSchedHttpUrlReservationsUninstall", "Wix4SchedHttpUrlReservationsUninstall_<PlatformSuffix>" },
209
+ { "WixSchedHttpUrlReservationsInstall", "Wix4SchedHttpUrlReservationsInstall_<PlatformSuffix>" },
210
+ { "ConfigureIIs", "Wix4ConfigureIIs_<PlatformSuffix>" },
211
+ { "UninstallCertificates", "Wix4UninstallCertificates_<PlatformSuffix>" },
212
+ { "InstallCertificates", "Wix4_<PlatformSuffix>" },
213
+ { "MessageQueuingUninstall", "Wix4MessageQueuingUninstall_<PlatformSuffix>" },
214
+ { "MessageQueuingInstall", "Wix4_MessageQueuingInstall<PlatformSuffix>" },
215
+ { "NetFxScheduleNativeImage", "Wix4NetFxScheduleNativeImage_<PlatformSuffix>" },
216
+ { "NetFxExecuteNativeImageCommitUninstall", "Wix4NetFxExecuteNativeImageCommitUninstall_<PlatformSuffix>" },
217
+ { "NetFxExecuteNativeImageUninstall", "Wix4NetFxExecuteNativeImageUninstall_<PlatformSuffix>" },
218
+ { "NetFxExecuteNativeImageCommitInstall", "Wix4NetFxExecuteNativeImageCommitInstall_<PlatformSuffix>" },
219
+ { "NetFxExecuteNativeImageInstall", "Wix4NetFxExecuteNativeImageInstall_<PlatformSuffix>" },
220
+ { "UninstallSqlData", "Wix4UninstallSqlData_<PlatformSuffix>" },
221
+ { "InstallSqlData", "Wix4InstallSqlData_<PlatformSuffix>" },
222
+ { "WixCheckRebootRequired", "Wix4CheckRebootRequired_<PlatformSuffix>" },
223
+ { "WixCloseApplications", "Wix4CloseApplications_<PlatformSuffix>" },
224
+ { "WixRegisterRestartResources", "Wix4RegisterRestartResources_<PlatformSuffix>" },
225
+ { "ConfigureUsers", "Wix4ConfigureUsers_<PlatformSuffix>" },
226
+ { "ConfigureSmbInstall", "Wix4ConfigureSmbInstall_<PlatformSuffix>" },
227
+ { "ConfigureSmbUninstall", "Wix4ConfigureSmbUninstall_<PlatformSuffix>" },
228
+ { "InstallPerfCounterData", "Wix4InstallPerfCounterData_<PlatformSuffix>" },
229
+ { "UninstallPerfCounterData", "Wix4UninstallPerfCounterData_<PlatformSuffix>" },
230
+ { "ConfigurePerfmonInstall", "Wix4ConfigurePerfmonInstall_<PlatformSuffix>" },
231
+ { "ConfigurePerfmonUninstall", "Wix4ConfigurePerfmonUninstall_<PlatformSuffix>" },
232
+ { "ConfigurePerfmonManifestRegister", "Wix4ConfigurePerfmonManifestRegister_<PlatformSuffix>" },
233
+ { "ConfigurePerfmonManifestUnregister", "Wix4ConfigurePerfmonManifestUnregister_<PlatformSuffix>" },
234
+ { "ConfigureEventManifestRegister", "Wix4ConfigureEventManifestRegister_<PlatformSuffix>" },
235
+ { "ConfigureEventManifestUnregister", "Wix4ConfigureEventManifestUnregister_<PlatformSuffix>" },
236
+ { "SchedServiceConfig", "Wix4SchedServiceConfig_<PlatformSuffix>" },
237
+ { "SchedXmlFile", "Wix4SchedXmlFile_<PlatformSuffix>" },
238
+ { "SchedXmlConfig", "Wix4SchedXmlConfig_<PlatformSuffix>" },
239
+ { "WixSchedInternetShortcuts", "Wix4SchedInternetShortcuts_<PlatformSuffix>" },
240
+ { "WixRollbackInternetShortcuts", "Wix4RollbackInternetShortcuts_<PlatformSuffix>" },
241
+ { "WixCreateInternetShortcuts", "Wix4CreateInternetShortcuts_<PlatformSuffix>" },
242
+ { "WixQueryOsInfo", "Wix4QueryOsInfo_<PlatformSuffix>" },
243
+ { "WixQueryOsDirs", "Wix4QueryOsDirs_<PlatformSuffix>" },
244
+ { "WixQueryOsWellKnownSID", "Wix4QueryOsWellKnownSID_<PlatformSuffix>" },
245
+ { "WixQueryOsDriverInfo", "Wix4QueryOsDriverInfo_<PlatformSuffix>" },
246
+ { "WixQueryNativeMachine", "Wix4QueryNativeMachine_<PlatformSuffix>" },
247
+ { "WixFailWhenDeferred", "Wix4FailWhenDeferred_<PlatformSuffix>" },
248
+ { "WixWaitForEvent", "Wix4WaitForEvent_<PlatformSuffix>" },
249
+ { "WixWaitForEventDeferred", "Wix4WaitForEventDeferred_<PlatformSuffix>" },
250
+ { "WixExitEarlyWithSuccess", "Wix4ExitEarlyWithSuccess_<PlatformSuffix>" },
251
+ { "WixBroadcastSettingChange", "Wix4BroadcastSettingChange_<PlatformSuffix>" },
252
+ { "WixBroadcastEnvironmentChange", "Wix4BroadcastEnvironmentChange_<PlatformSuffix>" },
253
+ { "SchedSecureObjects", "Wix4SchedSecureObjects_<PlatformSuffix>" },
254
+ { "SchedSecureObjectsRollback", "Wix4SchedSecureObjectsRollback_<PlatformSuffix>" },
255
+ { "VSFindInstances", "Wix4VSFindInstances_<PlatformSuffix>" },
256
+ };
257
+
258
private readonly Dictionary<XName, Action<XElement>> ConvertElementMapping;
259
private readonly Regex DeprecatedPrefixRegex = new Regex(@"(?<=(^|[^\$])(\$\$)*)\$(?=\(loc\.[^.].*\))",
260
RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture);
@@ -224,6 +283,7 @@ namespace WixToolset.Converters
283
{ WixConverter.ColumnElementName, this.ConvertColumnElement },
284
{ WixConverter.ComponentElementName, this.ConvertComponentElement },
285
{ WixConverter.ControlElementName, this.ConvertControlElement },
286
+ { WixConverter.CustomElementName, this.ConvertCustomElement },
287
{ WixConverter.CustomActionElementName, this.ConvertCustomActionElement },
288
{ WixConverter.CustomTableElementName, this.ConvertCustomTableElement },
289
{ WixConverter.DataElementName, this.ConvertDataElement },
@@ -840,6 +900,18 @@ namespace WixToolset.Converters
900
}
901
}
902
903
+ private void ConvertCustomElement(XElement element)
904
+ {
905
+ var actionId = element.Attribute("Action")?.Value;
906
+
907
+ if (actionId != null
908
+ && CustomActionIdsWithPlatformSuffix.TryGetValue(actionId, out var replacementId))
909
+ {
910
+ this.OnError(ConverterTestType.CustomActionIdsIncludePlatformSuffix, element,
911
+ $"Custom action ids have changed in WiX v4 extensions to support platform-specific custom actions. The platform is applied as a suffix: _X86, _X64, _A64 (Arm64). When manually rescheduling custom action '{actionId}', you must use the new custom action id '{replacementId}'.");
912
+ }
913
+ }
914
+
915
private void ConvertCustomTableElement(XElement element)
916
{
917
var bootstrapperApplicationData = element.Attribute("BootstrapperApplicationData");
@@ -3056,6 +3128,11 @@ namespace WixToolset.Converters
3128
/// Namespace should be defined on the root. The '{0}' namespace was move to the root element.
3129
/// </summary>
3130
MoveNamespacesToRoot,
3131
+
3132
+ /// <summary>
3133
+ /// Custom action ids have changed in WiX v4 extensions. Because WiX v4 has platform-specific custom actions, the platform is applied as a suffix: _X86, _X64, _A64 (Arm64). When manually rescheduling custom actions, you must use the new custom action id, with platform suffix.
3134
+ /// </summary>
3135
+ CustomActionIdsIncludePlatformSuffix,
3136
}
3137
}
3138
}
src/wix/test/WixToolsetTest.Converters/ConverterFixture.cs
+32
@@ -512,5 +512,37 @@ namespace WixToolsetTest.Converters
512
Assert.Equal(3, errors);
513
WixAssert.CompareLineByLine(expected, actual);
514
}
515
+
516
+ [Fact]
517
+ public void CantConvertStandardCustomActionRescheduling()
518
+ {
519
+ var parse = String.Join(Environment.NewLine,
520
+ "<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>",
521
+ " <InstallExecuteSequence>",
522
+ " <Custom Action='WixCloseApplications' Before='StopServices' />",
523
+ " </InstallExecuteSequence>",
524
+ "</Wix>");
525
+
526
+ var expected = new[]
527
+ {
528
+ "<Wix xmlns=\"http://wixtoolset.org/schemas/v4/wxs\">",
529
+ " <InstallExecuteSequence>",
530
+ " <Custom Action=\"WixCloseApplications\" Before=\"StopServices\" />",
531
+ " </InstallExecuteSequence>",
532
+ "</Wix>",
533
+ };
534
+
535
+ var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
536
+
537
+ var messaging = new MockMessaging();
538
+ var converter = new WixConverter(messaging, 2, null, null);
539
+
540
+ var errors = converter.ConvertDocument(document);
541
+
542
+ var actual = UnformattedDocumentLines(document);
543
+
544
+ Assert.Equal(2, errors);
545
+ WixAssert.CompareLineByLine(expected, actual);
546
+ }
547
}
548
}