diff --git a/Source/src/WixSharp.Samples/Support/testpad/setup.cs b/Source/src/WixSharp.Samples/Support/testpad/setup.cs
index bdebac65..c822e480 100644
--- a/Source/src/WixSharp.Samples/Support/testpad/setup.cs
+++ b/Source/src/WixSharp.Samples/Support/testpad/setup.cs
@@ -54,6 +54,7 @@ static void Issue_298()
GUID = new Guid("6fe30b47-2577-43ad-9095-1861ba25889b")
};
+ project.AddRegValue(new RegValue(RegistryHive.LocalMachine, @"Software\test", "foo_value", "bar") { Win64 = true });
project.AddRegValue(new RegValue(RegistryHive.LocalMachine, @"Software\test", "foo_value", "bar") { Win64 = false });
// Compiler.LightOptions += " -sice:ICE80";
diff --git a/Source/src/WixSharp.Samples/Wix# Samples/Extensions/setup.cs b/Source/src/WixSharp.Samples/Wix# Samples/Extensions/setup.cs
index a6143418..6278abc9 100644
--- a/Source/src/WixSharp.Samples/Wix# Samples/Extensions/setup.cs
+++ b/Source/src/WixSharp.Samples/Wix# Samples/Extensions/setup.cs
@@ -76,8 +76,8 @@ public class RemoveFolderEx : WixEntity, IGenericEntity
[Xml]
public new string Id
{
- get => base.Id;
- set => base.Id = value;
+ get { return base.Id; }
+ set { base.Id = value; }
}
///
diff --git a/Source/src/WixSharp.Samples/Wix# Samples/External_UI/Msi/MyProduct.msi b/Source/src/WixSharp.Samples/Wix# Samples/External_UI/Msi/MyProduct.msi
index 6ac50a2f..ce333cf4 100644
Binary files a/Source/src/WixSharp.Samples/Wix# Samples/External_UI/Msi/MyProduct.msi and b/Source/src/WixSharp.Samples/Wix# Samples/External_UI/Msi/MyProduct.msi differ
diff --git a/Source/src/WixSharp.Samples/Wix# Samples/Managed Setup/CustomUIDialog/setup.cs b/Source/src/WixSharp.Samples/Wix# Samples/Managed Setup/CustomUIDialog/setup.cs
index eaa9b6b8..42d8bf49 100644
--- a/Source/src/WixSharp.Samples/Wix# Samples/Managed Setup/CustomUIDialog/setup.cs
+++ b/Source/src/WixSharp.Samples/Wix# Samples/Managed Setup/CustomUIDialog/setup.cs
@@ -26,8 +26,6 @@ static public void Main(string[] args)
//Note if the property 'PASSWORD' is not preserved as deferred then it will not be available
//from the Project_AfterInstall, which is a deferred custom action.
- AutoElements.LagacyDummyDirAlgorithm = true;
-
var project = new ManagedProject("ManagedSetup",
new User
{
diff --git a/Source/src/WixSharp.Samples/WixSharp.xml b/Source/src/WixSharp.Samples/WixSharp.xml
index 57678935..db55e3e5 100644
--- a/Source/src/WixSharp.Samples/WixSharp.xml
+++ b/Source/src/WixSharp.Samples/WixSharp.xml
@@ -1375,6 +1375,19 @@
Forces all values to be always encoded as CDATA.
+
+
+ Flag indicating if the legacy algorithm should be used for handling setups with no directories
+ to be installed but only non-file system components (e.g. RegKey, User, Firewall exceptions).
+ The algorithm used in early versions of WixSharp (legacy algorithm) injects a dummy
+ directory into the setup definition so it satisfies the MSI constraint that every component must
+ belong to a directory. As many other rules this one has no practical value and rather reflection
+ of the outdated (~20 years ago) deployment approaches.
+ The current algorithm also ensures the that there is a XML directory to host the components.
+ However instead of custom (dummy) directory it inserts 'ProgramFilesFolder'. This way MSI constraint
+ is satisfied and yet there is no impact on the target file system.
+
+
Disables automatic insertion of user profile registry elements.
diff --git a/Source/src/WixSharp/AutoElements.cs b/Source/src/WixSharp/AutoElements.cs
index 0adbe6c4..ac09c780 100644
--- a/Source/src/WixSharp/AutoElements.cs
+++ b/Source/src/WixSharp/AutoElements.cs
@@ -132,7 +132,18 @@ public static class AutoElements
///
public static bool ForceCDataForConditions = false;
- public static bool LagacyDummyDirAlgorithm = false;
+ ///
+ /// Flag indicating if the legacy algorithm should be used for handling setups with no directories
+ /// to be installed but only non-file system components (e.g. RegKey, User, Firewall exceptions).
+ /// The algorithm used in early versions of WixSharp (legacy algorithm) injects a dummy
+ /// directory into the setup definition so it satisfies the MSI constraint that every component must
+ /// belong to a directory. As many other rules this one has no practical value and rather reflection
+ /// of the outdated (~20 years ago) deployment approaches.
+ /// The current algorithm also ensures the that there is a XML directory to host the components.
+ /// However instead of custom (dummy) directory it inserts 'ProgramFilesFolder'. This way MSI constraint
+ /// is satisfied and yet there is no impact on the target file system.
+ ///
+ public static bool LegacyDummyDirAlgorithm = false;
///
/// Disables automatic insertion of user profile registry elements.
@@ -549,7 +560,7 @@ internal static void HandleEmptyDirectories(XDocument doc)
//'EMPTY DIRECTORY' support processing section
foreach (XElement item in componentsWithNoFiles)
{
- // Ridiculous MSI constrains:
+ // Ridiculous MSI constraints:
// * you cannot install install empty folders
// - workaround is to insert empty component with CreateFolder element
// * if Component+CreateFolder element is inserted the folder will not be removed on uninstall
diff --git a/Source/src/WixSharp/CommonTasks.cs b/Source/src/WixSharp/CommonTasks.cs
index 19be607f..a4e3a69b 100644
--- a/Source/src/WixSharp/CommonTasks.cs
+++ b/Source/src/WixSharp/CommonTasks.cs
@@ -1285,6 +1285,20 @@ static public XElement CreateParentComponent(this WixEntity entity)
return new XElement("Component").AddAttributes($@"Id={entity.Id}; Guid={WixGuid.NewGuid(entity.Id)}");
}
+ static public XElement FistProgramFilesDir(this XElement element)
+ {
+ XElement dir = element.FindFirst("Directory");
+ while (dir != null)
+ {
+ if (dir.HasAttribute("Name", x => x.StartsWith("ProgramFiles") && x.EndsWith("Folder")))
+ return dir;
+
+ dir = dir.Elements("Directory").FirstOrDefault();
+ }
+
+ return null;
+ }
+
///
/// Installs the windows service. It uses InstallUtil.exe to complete the actual installation/uninstallation.
/// During the run for the InstallUtil.exe console window is hidden.
diff --git a/Source/src/WixSharp/Compiler.cs b/Source/src/WixSharp/Compiler.cs
index 7c919d91..48d3813c 100644
--- a/Source/src/WixSharp/Compiler.cs
+++ b/Source/src/WixSharp/Compiler.cs
@@ -1406,7 +1406,7 @@ public static XDocument GenerateWixProj(Project project)
if (!project.LicenceFile.IsEmpty())
{
if (!AllowNonRtfLicense && !project.LicenceFile.EndsWith(".rtf", StringComparison.OrdinalIgnoreCase))
- throw new ApplicationException("License file must have 'rtf' file extension. Specify 'Compiler.AllowNonRtfLicense=true' to overcome this constrain.");
+ throw new ApplicationException("License file must have 'rtf' file extension. Specify 'Compiler.AllowNonRtfLicense=true' to overcome this constraint.");
product.Add(
new XElement("WixVariable",
@@ -1450,7 +1450,7 @@ static string AutoAssignInstallDirId(Dir[] wDirs, string dirId)
Compiler.OutputWriteLine($"WARNING: Special folder directory ID '{firstDirWithItems.Id}' has been reset to '{dirId}'.\n" +
"If it was not intended disable auto assignment by setting 'Compiler.AutoGeneration.InstallDirDefaultId' to null.\n" +
"Or set 'Dir.IsInstallDir = true' for the installation directory.\r" +
- "Or use instead of 'new Dir(...' use 'new InstallDir(...' for the installation directory.");
+ "Or instead of 'new Dir(...' use 'new InstallDir(...' for the installation directory.");
firstDirWithItems.Id = dirId;
return logicalPath;
@@ -1709,7 +1709,7 @@ static void ProcessDirectory(Dir wDir, Project wProject, Dictionary