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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+