diff --git a/README.md b/README.md index 38ac14641..5833877d3 100644 --- a/README.md +++ b/README.md @@ -25,4 +25,5 @@ This repository contains the PanelSwWix4: A custom WiX Toolset codebase - Support sending custom messages on embedded pipe - Best effort to log premature termination of companion process - Monitor UX folder and re-extract any UX payloads that were deleted for any reason -- Reorder cache actions: moves non-executing package caching to the end of the plan. This optimizes run time as packages that are cached but not executed will not stand in the way of executing packages. \ No newline at end of file +- Reorder cache actions: moves non-executing package caching to the end of the plan. This optimizes run time as packages that are cached but not executed will not stand in the way of executing packages. +- [8896](https://github.com/wixtoolset/issues/issues/8896): Component/@WiX3CompatibleGuid- Support WiX3-compantible auto-guids for registry key path diff --git a/src/api/wix/WixToolset.Data/Symbols/ComponentSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/ComponentSymbol.cs index 13d398b1e..459c0fe8e 100644 --- a/src/api/wix/WixToolset.Data/Symbols/ComponentSymbol.cs +++ b/src/api/wix/WixToolset.Data/Symbols/ComponentSymbol.cs @@ -24,6 +24,7 @@ public static partial class SymbolDefinitions new IntermediateFieldDefinition(nameof(ComponentSymbolFields.Condition), IntermediateFieldType.String), new IntermediateFieldDefinition(nameof(ComponentSymbolFields.KeyPath), IntermediateFieldType.String), new IntermediateFieldDefinition(nameof(ComponentSymbolFields.KeyPathType), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(ComponentSymbolFields.WiX3CompatibleGuid), IntermediateFieldType.Bool), }, typeof(ComponentSymbol)); } @@ -47,6 +48,7 @@ public enum ComponentSymbolFields Condition, KeyPath, KeyPathType, + WiX3CompatibleGuid, } public enum ComponentLocation @@ -151,5 +153,11 @@ public ComponentKeyPathType KeyPathType get => (ComponentKeyPathType)this.Fields[(int)ComponentSymbolFields.KeyPathType].AsNumber(); set => this.Set((int)ComponentSymbolFields.KeyPathType, (int)value); } + + public bool WiX3CompatibleGuid + { + get => this.Fields[(int)ComponentSymbolFields.WiX3CompatibleGuid].AsBool(); + set => this.Set((int)ComponentSymbolFields.WiX3CompatibleGuid, value); + } } -} \ No newline at end of file +} diff --git a/src/api/wix/WixToolset.Data/WarningMessages.cs b/src/api/wix/WixToolset.Data/WarningMessages.cs index 80a47aa6c..7e10fcd74 100644 --- a/src/api/wix/WixToolset.Data/WarningMessages.cs +++ b/src/api/wix/WixToolset.Data/WarningMessages.cs @@ -719,6 +719,11 @@ public static Message MissingContainerExtension(SourceLineNumber sourceLineNumbe return Message(sourceLineNumbers, Ids.MissingContainerExtension, "Container '{0}' has BundleExtensionRef set to '{1}', which could not be resolved to a container extension. To extract this container add the missing extension to the extraction command line", containerId, bundleExtensionRef); } + public static Message AlreadyWiX3CompatibleGuid(SourceLineNumber sourceLineNumbers, ComponentKeyPathType keyPathType) + { + return Message(sourceLineNumbers, Ids.AlreadyWiX3CompatibleGuid, "Components with KeyPath type {0} have WiX3-compatible GUID by default. Attribute WiX3CompatibleGuid is redundant.", keyPathType); + } + private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args) { return new Message(sourceLineNumber, MessageLevel.Warning, (int)id, format, args); @@ -861,6 +866,7 @@ public enum Ids ExePackageDetectInformationRecommended = 1161, InvalidWixVersion = 1162, MissingContainerExtension = 1163, + AlreadyWiX3CompatibleGuid = 1164, } } } diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/FinalizeComponentGuids.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/FinalizeComponentGuids.cs index 3cdc0c282..9edbc3cce 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/FinalizeComponentGuids.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/FinalizeComponentGuids.cs @@ -99,6 +99,10 @@ private void GenerateComponentGuid(ComponentSymbol componentSymbol) { var bitness = componentSymbol.Win64 ? "64" : String.Empty; var regkey = String.Concat(bitness, registrySymbol.Root, "\\", registrySymbol.Key, "\\", registrySymbol.Name); + if (componentSymbol.WiX3CompatibleGuid) + { + regkey = String.Concat(bitness, (int)registrySymbol.Root, "\\", registrySymbol.Key, "\\", registrySymbol.Name); + } componentSymbol.ComponentId = this.BackendHelper.CreateGuid(BindDatabaseCommand.WixComponentGuidNamespace, regkey.ToLowerInvariant()); } } diff --git a/src/wix/WixToolset.Core/Compiler.cs b/src/wix/WixToolset.Core/Compiler.cs index 73fd494db..a0ce5937a 100644 --- a/src/wix/WixToolset.Core/Compiler.cs +++ b/src/wix/WixToolset.Core/Compiler.cs @@ -2120,6 +2120,7 @@ private void ParseComponentElement(XElement node, ComplexReferenceParentType par var location = ComponentLocation.LocalOnly; var disableRegistryReflection = false; + var wiX3CompatibleGuid = false; var neverOverwrite = false; var permanent = false; var shared = false; @@ -2184,6 +2185,9 @@ private void ParseComponentElement(XElement node, ComplexReferenceParentType par case "Guid": guid = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, true, true); break; + case "WiX3CompatibleGuid": + wiX3CompatibleGuid = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); + break; case "KeyPath": if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { @@ -2515,6 +2519,15 @@ private void ParseComponentElement(XElement node, ComplexReferenceParentType par } } + if (wiX3CompatibleGuid && (guid != "*")) + { + this.Core.Write(ErrorMessages.IllegalAttributeValueWithoutOtherAttribute(sourceLineNumbers, node.Name.LocalName, "WiX3CompatibleGuid", "yes", "Guid", "*")); + } + if (wiX3CompatibleGuid && (ComponentKeyPathType.Registry != keyPathType)) + { + this.Core.Write(WarningMessages.AlreadyWiX3CompatibleGuid(sourceLineNumbers, keyPathType)); + } + // finally add the Component table row if (!this.Core.EncounteredError) { @@ -2534,6 +2547,7 @@ private void ParseComponentElement(XElement node, ComplexReferenceParentType par Transitive = transitive, UninstallWhenSuperseded = uninstallWhenSuperseded, Win64 = win64, + WiX3CompatibleGuid = wiX3CompatibleGuid, }); if (multiInstance) diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/MsiQueryFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/MsiQueryFixture.cs index 945e2133e..58b3f00a8 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/MsiQueryFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/MsiQueryFixture.cs @@ -183,6 +183,37 @@ public void PopulatesAppSearchTablesFromRegistrySearch64() } } + [Fact] + public void WiX3CompatibleGuid() + { + var folder = TestData.Get(@"TestData\WiX3CompatibleGuid"); + + using (var fs = new DisposableFileSystem()) + { + var baseFolder = fs.GetFolder(); + var intermediateFolder = Path.Combine(baseFolder, "obj"); + var msiPath = Path.Combine(baseFolder, @"bin\test.msi"); + + var result = WixRunner.Execute(new[] + { + "build", + Path.Combine(folder, "Package.wxs"), + Path.Combine(folder, "WiX3CompatibleGuid.wxs"), + "-intermediateFolder", intermediateFolder, + "-o", msiPath + }); + + result.AssertSuccess(); + + Assert.True(File.Exists(msiPath)); + var results = Query.QueryDatabase(msiPath, new[] { "Component" }); + + Assert.Equal(2, results.Length); + Assert.Contains(results, component => component.Contains("WiX3CompatibleGuid") && component.Contains("8BAF5399-2FD2-50B6-ABDA-98FB3A5BB148", StringComparison.InvariantCultureIgnoreCase)); + Assert.Contains(results, component => component.Contains("WiX4CompatibleGuid") && !component.Contains("8BAF5399-2FD2-50B6-ABDA-98FB3A5BB148", StringComparison.InvariantCultureIgnoreCase)); + } + } + [Fact] public void PopulatesCreateFolderTableForNullKeypathComponents() { diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/WiX3CompatibleGuid/Package.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/WiX3CompatibleGuid/Package.wxs new file mode 100644 index 000000000..b94caae3b --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/WiX3CompatibleGuid/Package.wxs @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/WiX3CompatibleGuid/WiX3CompatibleGuid.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/WiX3CompatibleGuid/WiX3CompatibleGuid.wxs new file mode 100644 index 000000000..e635c8630 --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/WiX3CompatibleGuid/WiX3CompatibleGuid.wxs @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + +