aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2017-11-11 01:45:59 -0800
committerRob Mensching <rob@firegiant.com>2017-11-11 01:45:59 -0800
commit9f8cb5374481b6c8a06eb2739858332350f72666 (patch)
tree4b09b90d8a516cb5e7d8203759bd2489b6a5d20c /src/WixToolset.Core
parent2bb37beda887d120a0ddabf874ad25357101faa1 (diff)
downloadwix-9f8cb5374481b6c8a06eb2739858332350f72666.tar.gz
wix-9f8cb5374481b6c8a06eb2739858332350f72666.tar.bz2
wix-9f8cb5374481b6c8a06eb2739858332350f72666.zip
Additional IR updates
Diffstat (limited to 'src/WixToolset.Core')
-rw-r--r--src/WixToolset.Core/Bind/ExtractEmbeddedFilesCommand.cs15
-rw-r--r--src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs78
-rw-r--r--src/WixToolset.Core/Bind/ResolvedDirectory.cs18
-rw-r--r--src/WixToolset.Core/Binder.cs8
-rw-r--r--src/WixToolset.Core/Compiler.cs8
-rw-r--r--src/WixToolset.Core/Linker.cs670
-rw-r--r--src/WixToolset.Core/WindowsInstallerStandard.cs260
-rw-r--r--src/WixToolset.Core/WixStrings.Designer.cs4
8 files changed, 65 insertions, 996 deletions
diff --git a/src/WixToolset.Core/Bind/ExtractEmbeddedFilesCommand.cs b/src/WixToolset.Core/Bind/ExtractEmbeddedFilesCommand.cs
index 7de40fb8..7e7c21b1 100644
--- a/src/WixToolset.Core/Bind/ExtractEmbeddedFilesCommand.cs
+++ b/src/WixToolset.Core/Bind/ExtractEmbeddedFilesCommand.cs
@@ -11,7 +11,12 @@ namespace WixToolset.Core.Bind
11 11
12 public class ExtractEmbeddedFilesCommand 12 public class ExtractEmbeddedFilesCommand
13 { 13 {
14 public IEnumerable<IExpectedExtractFile> FilesWithEmbeddedFiles { private get; set; } 14 public ExtractEmbeddedFilesCommand(IEnumerable<IExpectedExtractFile> embeddedFiles)
15 {
16 this.FilesWithEmbeddedFiles = embeddedFiles;
17 }
18
19 private IEnumerable<IExpectedExtractFile> FilesWithEmbeddedFiles { get; }
15 20
16 public void Execute() 21 public void Execute()
17 { 22 {
@@ -28,10 +33,10 @@ namespace WixToolset.Core.Bind
28 // a .wixlib embedded in a WixExtension). 33 // a .wixlib embedded in a WixExtension).
29 if ("embeddedresource" == baseUri.Scheme) 34 if ("embeddedresource" == baseUri.Scheme)
30 { 35 {
31 string assemblyPath = Path.GetFullPath(baseUri.LocalPath); 36 var assemblyPath = Path.GetFullPath(baseUri.LocalPath);
32 string resourceName = baseUri.Fragment.TrimStart('#'); 37 var resourceName = baseUri.Fragment.TrimStart('#');
33 38
34 Assembly assembly = Assembly.LoadFile(assemblyPath); 39 var assembly = Assembly.LoadFile(assemblyPath);
35 stream = assembly.GetManifestResourceStream(resourceName); 40 stream = assembly.GetManifestResourceStream(resourceName);
36 } 41 }
37 else // normal file (usually a binary .wixlib on disk). 42 else // normal file (usually a binary .wixlib on disk).
@@ -39,7 +44,7 @@ namespace WixToolset.Core.Bind
39 stream = File.OpenRead(baseUri.LocalPath); 44 stream = File.OpenRead(baseUri.LocalPath);
40 } 45 }
41 46
42 using (FileStructure fs = FileStructure.Read(stream)) 47 using (var fs = FileStructure.Read(stream))
43 { 48 {
44 var uniqueIndicies = new SortedSet<int>(); 49 var uniqueIndicies = new SortedSet<int>();
45 50
diff --git a/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs b/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs
index d05135cf..4585b71a 100644
--- a/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs
+++ b/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs
@@ -12,25 +12,28 @@ namespace WixToolset.Core.Bind
12 /// Resolves the fields which had variables that needed to be resolved after the file information 12 /// Resolves the fields which had variables that needed to be resolved after the file information
13 /// was loaded. 13 /// was loaded.
14 /// </summary> 14 /// </summary>
15 public class ResolveDelayedFieldsCommand : ICommand 15 public class ResolveDelayedFieldsCommand
16 { 16 {
17 public OutputType OutputType { private get; set;} 17 /// <summary>
18 18 /// Resolve delayed fields.
19 public IEnumerable<IDelayedField> DelayedFields { private get; set;} 19 /// </summary>
20 /// <param name="delayedFields">The fields which had resolution delayed.</param>
21 /// <param name="variableCache">The file information to use when resolving variables.</param>
22 public ResolveDelayedFieldsCommand(IEnumerable<IDelayedField> delayedFields, Dictionary<string, string> variableCache)
23 {
24 this.DelayedFields = delayedFields;
25 this.VariableCache = variableCache;
26 }
20 27
21 public IDictionary<string, string> VariableCache { private get; set; } 28 private IEnumerable<IDelayedField> DelayedFields { get;}
22 29
23 public string ModularizationGuid { private get; set; } 30 private IDictionary<string, string> VariableCache { get; }
24 31
25 /// <param name="output">Internal representation of the msi database to operate upon.</param>
26 /// <param name="delayedFields">The fields which had resolution delayed.</param>
27 /// <param name="variableCache">The file information to use when resolving variables.</param>
28 /// <param name="modularizationGuid">The modularization guid (used in case of a merge module).</param>
29 public void Execute() 32 public void Execute()
30 { 33 {
31 var deferredFields = new List<IDelayedField>(); 34 var deferredFields = new List<IDelayedField>();
32 35
33 foreach (IDelayedField delayedField in this.DelayedFields) 36 foreach (var delayedField in this.DelayedFields)
34 { 37 {
35 try 38 try
36 { 39 {
@@ -42,7 +45,7 @@ namespace WixToolset.Core.Bind
42 var value = WixVariableResolver.ResolveDelayedVariables(propertyRow.SourceLineNumbers, delayedField.Field.AsString(), this.VariableCache); 45 var value = WixVariableResolver.ResolveDelayedVariables(propertyRow.SourceLineNumbers, delayedField.Field.AsString(), this.VariableCache);
43 46
44 // update the variable cache with the new value 47 // update the variable cache with the new value
45 var key = String.Concat("property.", Common.Demodularize(this.OutputType, this.ModularizationGuid, (string)propertyRow[0])); 48 var key = String.Concat("property.", propertyRow.AsString(0));
46 this.VariableCache[key] = value; 49 this.VariableCache[key] = value;
47 50
48 // update the field data 51 // update the field data
@@ -62,43 +65,31 @@ namespace WixToolset.Core.Bind
62 65
63 // add specialization for ProductVersion fields 66 // add specialization for ProductVersion fields
64 string keyProductVersion = "property.ProductVersion"; 67 string keyProductVersion = "property.ProductVersion";
65 if (this.VariableCache.ContainsKey(keyProductVersion)) 68 if (this.VariableCache.TryGetValue(keyProductVersion, out var versionValue) && Version.TryParse(versionValue, out Version productVersion))
66 { 69 {
67 string value = this.VariableCache[keyProductVersion]; 70 // Don't add the variable if it already exists (developer defined a property with the same name).
68 Version productVersion = null; 71 string fieldKey = String.Concat(keyProductVersion, ".Major");
69 72 if (!this.VariableCache.ContainsKey(fieldKey))
70 try
71 { 73 {
72 productVersion = new Version(value); 74 this.VariableCache[fieldKey] = productVersion.Major.ToString(CultureInfo.InvariantCulture);
73 75 }
74 // Don't add the variable if it already exists (developer defined a property with the same name).
75 string fieldKey = String.Concat(keyProductVersion, ".Major");
76 if (!this.VariableCache.ContainsKey(fieldKey))
77 {
78 this.VariableCache[fieldKey] = productVersion.Major.ToString(CultureInfo.InvariantCulture);
79 }
80
81 fieldKey = String.Concat(keyProductVersion, ".Minor");
82 if (!this.VariableCache.ContainsKey(fieldKey))
83 {
84 this.VariableCache[fieldKey] = productVersion.Minor.ToString(CultureInfo.InvariantCulture);
85 }
86 76
87 fieldKey = String.Concat(keyProductVersion, ".Build"); 77 fieldKey = String.Concat(keyProductVersion, ".Minor");
88 if (!this.VariableCache.ContainsKey(fieldKey)) 78 if (!this.VariableCache.ContainsKey(fieldKey))
89 { 79 {
90 this.VariableCache[fieldKey] = productVersion.Build.ToString(CultureInfo.InvariantCulture); 80 this.VariableCache[fieldKey] = productVersion.Minor.ToString(CultureInfo.InvariantCulture);
91 } 81 }
92 82
93 fieldKey = String.Concat(keyProductVersion, ".Revision"); 83 fieldKey = String.Concat(keyProductVersion, ".Build");
94 if (!this.VariableCache.ContainsKey(fieldKey)) 84 if (!this.VariableCache.ContainsKey(fieldKey))
95 { 85 {
96 this.VariableCache[fieldKey] = productVersion.Revision.ToString(CultureInfo.InvariantCulture); 86 this.VariableCache[fieldKey] = productVersion.Build.ToString(CultureInfo.InvariantCulture);
97 }
98 } 87 }
99 catch 88
89 fieldKey = String.Concat(keyProductVersion, ".Revision");
90 if (!this.VariableCache.ContainsKey(fieldKey))
100 { 91 {
101 // Ignore the error introduced by new behavior. 92 this.VariableCache[fieldKey] = productVersion.Revision.ToString(CultureInfo.InvariantCulture);
102 } 93 }
103 } 94 }
104 95
@@ -113,7 +104,6 @@ namespace WixToolset.Core.Bind
113 catch (WixException we) 104 catch (WixException we)
114 { 105 {
115 Messaging.Instance.OnMessage(we.Error); 106 Messaging.Instance.OnMessage(we.Error);
116 continue;
117 } 107 }
118 } 108 }
119 } 109 }
diff --git a/src/WixToolset.Core/Bind/ResolvedDirectory.cs b/src/WixToolset.Core/Bind/ResolvedDirectory.cs
index fca706d8..9d07fc93 100644
--- a/src/WixToolset.Core/Bind/ResolvedDirectory.cs
+++ b/src/WixToolset.Core/Bind/ResolvedDirectory.cs
@@ -7,15 +7,6 @@ namespace WixToolset.Bind
7 /// </summary> 7 /// </summary>
8 public struct ResolvedDirectory 8 public struct ResolvedDirectory
9 { 9 {
10 /// <summary>The directory parent.</summary>
11 public string DirectoryParent;
12
13 /// <summary>The name of this directory.</summary>
14 public string Name;
15
16 /// <summary>The path of this directory.</summary>
17 public string Path;
18
19 /// <summary> 10 /// <summary>
20 /// Constructor for ResolvedDirectory. 11 /// Constructor for ResolvedDirectory.
21 /// </summary> 12 /// </summary>
@@ -27,5 +18,14 @@ namespace WixToolset.Bind
27 this.Name = name; 18 this.Name = name;
28 this.Path = null; 19 this.Path = null;
29 } 20 }
21
22 /// <summary>The directory parent.</summary>
23 public string DirectoryParent { get; set; }
24
25 /// <summary>The name of this directory.</summary>
26 public string Name { get; set; }
27
28 /// <summary>The path of this directory.</summary>
29 public string Path { get; set; }
30 } 30 }
31} 31}
diff --git a/src/WixToolset.Core/Binder.cs b/src/WixToolset.Core/Binder.cs
index 07a92d02..e282ead8 100644
--- a/src/WixToolset.Core/Binder.cs
+++ b/src/WixToolset.Core/Binder.cs
@@ -609,9 +609,9 @@ namespace WixToolset.Core
609 /// <param name="directory">Directory identifier.</param> 609 /// <param name="directory">Directory identifier.</param>
610 /// <param name="canonicalize">Canonicalize the path for standard directories.</param> 610 /// <param name="canonicalize">Canonicalize the path for standard directories.</param>
611 /// <returns>Source path of a directory.</returns> 611 /// <returns>Source path of a directory.</returns>
612 public static string GetDirectoryPath(Hashtable directories, Hashtable componentIdGenSeeds, string directory, bool canonicalize) 612 public static string GetDirectoryPath(Dictionary<string, ResolvedDirectory> directories, Dictionary<string, string> componentIdGenSeeds, string directory, bool canonicalize)
613 { 613 {
614 if (!directories.Contains(directory)) 614 if (!directories.ContainsKey(directory))
615 { 615 {
616 throw new WixException(WixErrors.ExpectedDirectory(directory)); 616 throw new WixException(WixErrors.ExpectedDirectory(directory));
617 } 617 }
@@ -620,7 +620,7 @@ namespace WixToolset.Core
620 620
621 if (null == resolvedDirectory.Path) 621 if (null == resolvedDirectory.Path)
622 { 622 {
623 if (null != componentIdGenSeeds && componentIdGenSeeds.Contains(directory)) 623 if (null != componentIdGenSeeds && componentIdGenSeeds.ContainsKey(directory))
624 { 624 {
625 resolvedDirectory.Path = (string)componentIdGenSeeds[directory]; 625 resolvedDirectory.Path = (string)componentIdGenSeeds[directory];
626 } 626 }
@@ -670,7 +670,7 @@ namespace WixToolset.Core
670 /// <param name="compressed">Specifies the package is compressed.</param> 670 /// <param name="compressed">Specifies the package is compressed.</param>
671 /// <param name="useLongName">Specifies the package uses long file names.</param> 671 /// <param name="useLongName">Specifies the package uses long file names.</param>
672 /// <returns>Source path of file relative to package directory.</returns> 672 /// <returns>Source path of file relative to package directory.</returns>
673 public static string GetFileSourcePath(Hashtable directories, string directoryId, string fileName, bool compressed, bool useLongName) 673 public static string GetFileSourcePath(Dictionary<string, ResolvedDirectory> directories, string directoryId, string fileName, bool compressed, bool useLongName)
674 { 674 {
675 string fileSourcePath = Common.GetName(fileName, true, useLongName); 675 string fileSourcePath = Common.GetName(fileName, true, useLongName);
676 676
diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs
index e0475baa..903aae61 100644
--- a/src/WixToolset.Core/Compiler.cs
+++ b/src/WixToolset.Core/Compiler.cs
@@ -7137,7 +7137,7 @@ namespace WixToolset
7137 } 7137 }
7138 7138
7139 // finally, schedule RemoveExistingProducts 7139 // finally, schedule RemoveExistingProducts
7140 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixAction); 7140 row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixAction, new Identifier("InstallExecuteSequence/RemoveExistingProducts", AccessModifier.Public));
7141 row.Set(0, "InstallExecuteSequence"); 7141 row.Set(0, "InstallExecuteSequence");
7142 row.Set(1, "RemoveExistingProducts"); 7142 row.Set(1, "RemoveExistingProducts");
7143 // row.Set(2, condition); 7143 // row.Set(2, condition);
@@ -7641,11 +7641,11 @@ namespace WixToolset
7641 row.Set(4, diskId); 7641 row.Set(4, diskId);
7642 if (YesNoType.Yes == fileCompression) 7642 if (YesNoType.Yes == fileCompression)
7643 { 7643 {
7644 row.Set(5, 1); 7644 row.Set(5, true);
7645 } 7645 }
7646 else if (YesNoType.No == fileCompression) 7646 else if (YesNoType.No == fileCompression)
7647 { 7647 {
7648 row.Set(5, 0); 7648 row.Set(5, false);
7649 } 7649 }
7650 else // YesNoType.NotSet == fileCompression 7650 else // YesNoType.NotSet == fileCompression
7651 { 7651 {
@@ -9525,7 +9525,7 @@ namespace WixToolset
9525 var patchIdRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchId); 9525 var patchIdRow = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.WixPatchId);
9526 patchIdRow.Set(0, patchId); 9526 patchIdRow.Set(0, patchId);
9527 patchIdRow.Set(1, clientPatchId); 9527 patchIdRow.Set(1, clientPatchId);
9528 patchIdRow.Set(2, optimizePatchSizeForLargeFiles ? 1 : 0); 9528 patchIdRow.Set(2, optimizePatchSizeForLargeFiles);
9529 patchIdRow.Set(3, apiPatchingSymbolFlags); 9529 patchIdRow.Set(3, apiPatchingSymbolFlags);
9530 9530
9531 if (allowRemoval) 9531 if (allowRemoval)
diff --git a/src/WixToolset.Core/Linker.cs b/src/WixToolset.Core/Linker.cs
index 59481387..7faf69ba 100644
--- a/src/WixToolset.Core/Linker.cs
+++ b/src/WixToolset.Core/Linker.cs
@@ -23,9 +23,6 @@ namespace WixToolset.Core
23 private static readonly string emptyGuid = Guid.Empty.ToString("B"); 23 private static readonly string emptyGuid = Guid.Empty.ToString("B");
24 24
25 private bool sectionIdOnRows; 25 private bool sectionIdOnRows;
26 //private WixActionRowCollection standardActions;
27 //private Output activeOutput;
28 //private TableDefinitionCollection tableDefinitions;
29 26
30 /// <summary> 27 /// <summary>
31 /// Creates a linker. 28 /// Creates a linker.
@@ -34,9 +31,6 @@ namespace WixToolset.Core
34 { 31 {
35 this.sectionIdOnRows = true; // TODO: what is the correct value for this? 32 this.sectionIdOnRows = true; // TODO: what is the correct value for this?
36 33
37 //this.standardActions = WindowsInstallerStandard.GetStandardActions();
38 //this.tableDefinitions = new TableDefinitionCollection(WindowsInstallerStandard.GetTableDefinitions());
39
40 //this.extensionData = new List<IExtensionData>(); 34 //this.extensionData = new List<IExtensionData>();
41 //this.inspectorExtensions = new List<InspectorExtension>(); 35 //this.inspectorExtensions = new List<InspectorExtension>();
42 } 36 }
@@ -108,11 +102,6 @@ namespace WixToolset.Core
108 102
109 //this.activeOutput = null; 103 //this.activeOutput = null;
110 104
111#if MOVE_TO_BACKEND
112 var actionRows = new List<IntermediateTuple>();
113 var suppressActionRows = new List<IntermediateTuple>();
114#endif
115
116 //TableDefinitionCollection customTableDefinitions = new TableDefinitionCollection(); 105 //TableDefinitionCollection customTableDefinitions = new TableDefinitionCollection();
117 //IntermediateTuple customRows = new List<IntermediateTuple>(); 106 //IntermediateTuple customRows = new List<IntermediateTuple>();
118 107
@@ -232,7 +221,7 @@ namespace WixToolset.Core
232 } 221 }
233 222
234 // Report duplicates that would ultimately end up being primary key collisions. 223 // Report duplicates that would ultimately end up being primary key collisions.
235 ReportConflictingSymbolsCommand reportDupes = new ReportConflictingSymbolsCommand(find.PossiblyConflictingSymbols, resolve.ResolvedSections); 224 var reportDupes = new ReportConflictingSymbolsCommand(find.PossiblyConflictingSymbols, resolve.ResolvedSections);
236 reportDupes.Execute(); 225 reportDupes.Execute();
237 226
238 if (Messaging.Instance.EncounteredError) 227 if (Messaging.Instance.EncounteredError)
@@ -394,19 +383,6 @@ namespace WixToolset.Core
394 } 383 }
395 break; 384 break;
396 385
397#if MOVE_TO_BACKEND
398 case TupleDefinitionType.WixAction:
399 //if (this.sectionIdOnRows)
400 //{
401 // foreach (Row row in table.Rows)
402 // {
403 // row.SectionId = sectionId;
404 // }
405 //}
406 actionRows.Add(tuple);
407 break;
408#endif
409
410#if SOLVE_CUSTOM_TABLE 386#if SOLVE_CUSTOM_TABLE
411 case "WixCustomTable": 387 case "WixCustomTable":
412 this.LinkCustomTable(table, customTableDefinitions); 388 this.LinkCustomTable(table, customTableDefinitions);
@@ -455,12 +431,6 @@ namespace WixToolset.Core
455 } 431 }
456 break; 432 break;
457 433
458#if MOVE_TO_BACKEND
459 case TupleDefinitionType.WixSuppressAction:
460 suppressActionRows.Add(tuple);
461 break;
462#endif
463
464 case TupleDefinitionType.WixComplexReference: 434 case TupleDefinitionType.WixComplexReference:
465 copyTuple = false; 435 copyTuple = false;
466 break; 436 break;
@@ -539,11 +509,6 @@ namespace WixToolset.Core
539#endif 509#endif
540 510
541#if MOVE_TO_BACKEND 511#if MOVE_TO_BACKEND
542 // sequence all the actions
543 this.SequenceActions(actionRows, suppressActionRows);
544#endif
545
546#if MOVE_TO_BACKEND
547 // check for missing table and add them or display an error as appropriate 512 // check for missing table and add them or display an error as appropriate
548 switch (this.activeOutput.Type) 513 switch (this.activeOutput.Type)
549 { 514 {
@@ -1140,6 +1105,7 @@ namespace WixToolset.Core
1140 } 1105 }
1141 } 1106 }
1142#endif 1107#endif
1108
1143 /// <summary> 1109 /// <summary>
1144 /// Sends a message to the message delegate if there is one. 1110 /// Sends a message to the message delegate if there is one.
1145 /// </summary> 1111 /// </summary>
@@ -1726,638 +1692,6 @@ namespace WixToolset.Core
1726 } 1692 }
1727#endif 1693#endif
1728 1694
1729#if MOVE_TO_BACKEND
1730 /// <summary>
1731 /// Set sequence numbers for all the actions and create rows in the output object.
1732 /// </summary>
1733 /// <param name="actionRows">Collection of actions to schedule.</param>
1734 /// <param name="suppressActionRows">Collection of actions to suppress.</param>
1735 private void SequenceActions(List<IntermediateTuple> actionRows, List<IntermediateTuple> suppressActionRows)
1736 {
1737 var overridableActionRows = new WixActionRowCollection();
1738 var requiredActionRows = new WixActionRowCollection();
1739 ArrayList scheduledActionRows = new ArrayList();
1740
1741 // gather the required actions for the output type
1742 if (OutputType.Product == this.activeOutput.Type)
1743 {
1744 // AdminExecuteSequence table
1745 overridableActionRows.Add(this.standardActions[SequenceTable.AdminExecuteSequence, "CostFinalize"]);
1746 overridableActionRows.Add(this.standardActions[SequenceTable.AdminExecuteSequence, "CostInitialize"]);
1747 overridableActionRows.Add(this.standardActions[SequenceTable.AdminExecuteSequence, "FileCost"]);
1748 overridableActionRows.Add(this.standardActions[SequenceTable.AdminExecuteSequence, "InstallAdminPackage"]);
1749 overridableActionRows.Add(this.standardActions[SequenceTable.AdminExecuteSequence, "InstallFiles"]);
1750 overridableActionRows.Add(this.standardActions[SequenceTable.AdminExecuteSequence, "InstallFinalize"]);
1751 overridableActionRows.Add(this.standardActions[SequenceTable.AdminExecuteSequence, "InstallInitialize"]);
1752 overridableActionRows.Add(this.standardActions[SequenceTable.AdminExecuteSequence, "InstallValidate"]);
1753
1754 // AdminUISequence table
1755 overridableActionRows.Add(this.standardActions[SequenceTable.AdminUISequence, "CostFinalize"]);
1756 overridableActionRows.Add(this.standardActions[SequenceTable.AdminUISequence, "CostInitialize"]);
1757 overridableActionRows.Add(this.standardActions[SequenceTable.AdminUISequence, "ExecuteAction"]);
1758 overridableActionRows.Add(this.standardActions[SequenceTable.AdminUISequence, "FileCost"]);
1759
1760 // AdvtExecuteSequence table
1761 overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "CostFinalize"]);
1762 overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "CostInitialize"]);
1763 overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "InstallFinalize"]);
1764 overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "InstallInitialize"]);
1765 overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "InstallValidate"]);
1766 overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "PublishFeatures"]);
1767 overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "PublishProduct"]);
1768
1769 // InstallExecuteSequence table
1770 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "CostFinalize"]);
1771 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "CostInitialize"]);
1772 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "FileCost"]);
1773 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "InstallFinalize"]);
1774 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "InstallInitialize"]);
1775 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "InstallValidate"]);
1776 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "ProcessComponents"]);
1777 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "PublishFeatures"]);
1778 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "PublishProduct"]);
1779 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterProduct"]);
1780 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterUser"]);
1781 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnpublishFeatures"]);
1782 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "ValidateProductID"]);
1783
1784 // InstallUISequence table
1785 overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "CostFinalize"]);
1786 overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "CostInitialize"]);
1787 overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "ExecuteAction"]);
1788 overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "FileCost"]);
1789 overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "ValidateProductID"]);
1790 }
1791
1792 // gather the required actions for each table
1793 foreach (Table table in this.activeOutput.Tables)
1794 {
1795 switch (table.Name)
1796 {
1797 case "AppSearch":
1798 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "AppSearch"], true);
1799 overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "AppSearch"], true);
1800 break;
1801 case "BindImage":
1802 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "BindImage"], true);
1803 break;
1804 case "CCPSearch":
1805 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "AppSearch"], true);
1806 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "CCPSearch"], true);
1807 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RMCCPSearch"], true);
1808 overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "AppSearch"], true);
1809 overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "CCPSearch"], true);
1810 overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "RMCCPSearch"], true);
1811 break;
1812 case "Class":
1813 overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "RegisterClassInfo"], true);
1814 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterClassInfo"], true);
1815 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnregisterClassInfo"], true);
1816 break;
1817 case "Complus":
1818 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterComPlus"], true);
1819 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnregisterComPlus"], true);
1820 break;
1821 case "CreateFolder":
1822 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "CreateFolders"], true);
1823 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveFolders"], true);
1824 break;
1825 case "DuplicateFile":
1826 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "DuplicateFiles"], true);
1827 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveDuplicateFiles"], true);
1828 break;
1829 case "Environment":
1830 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "WriteEnvironmentStrings"], true);
1831 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveEnvironmentStrings"], true);
1832 break;
1833 case "Extension":
1834 overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "RegisterExtensionInfo"], true);
1835 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterExtensionInfo"], true);
1836 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnregisterExtensionInfo"], true);
1837 break;
1838 case "File":
1839 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "InstallFiles"], true);
1840 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveFiles"], true);
1841 break;
1842 case "Font":
1843 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterFonts"], true);
1844 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnregisterFonts"], true);
1845 break;
1846 case "IniFile":
1847 case "RemoveIniFile":
1848 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "WriteIniValues"], true);
1849 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveIniValues"], true);
1850 break;
1851 case "IsolatedComponent":
1852 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "IsolateComponents"], true);
1853 break;
1854 case "LaunchCondition":
1855 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "LaunchConditions"], true);
1856 overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "LaunchConditions"], true);
1857 break;
1858 case "MIME":
1859 overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "RegisterMIMEInfo"], true);
1860 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterMIMEInfo"], true);
1861 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnregisterMIMEInfo"], true);
1862 break;
1863 case "MoveFile":
1864 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "MoveFiles"], true);
1865 break;
1866 case "MsiAssembly":
1867 overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "MsiPublishAssemblies"], true);
1868 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "MsiPublishAssemblies"], true);
1869 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "MsiUnpublishAssemblies"], true);
1870 break;
1871 case "MsiServiceConfig":
1872 case "MsiServiceConfigFailureActions":
1873 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "MsiConfigureServices"], true);
1874 break;
1875 case "ODBCDataSource":
1876 case "ODBCTranslator":
1877 case "ODBCDriver":
1878 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "SetODBCFolders"], true);
1879 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "InstallODBC"], true);
1880 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveODBC"], true);
1881 break;
1882 case "ProgId":
1883 overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "RegisterProgIdInfo"], true);
1884 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterProgIdInfo"], true);
1885 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnregisterProgIdInfo"], true);
1886 break;
1887 case "PublishComponent":
1888 overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "PublishComponents"], true);
1889 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "PublishComponents"], true);
1890 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnpublishComponents"], true);
1891 break;
1892 case "Registry":
1893 case "RemoveRegistry":
1894 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "WriteRegistryValues"], true);
1895 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveRegistryValues"], true);
1896 break;
1897 case "RemoveFile":
1898 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveFiles"], true);
1899 break;
1900 case "SelfReg":
1901 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "SelfRegModules"], true);
1902 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "SelfUnregModules"], true);
1903 break;
1904 case "ServiceControl":
1905 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "StartServices"], true);
1906 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "StopServices"], true);
1907 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "DeleteServices"], true);
1908 break;
1909 case "ServiceInstall":
1910 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "InstallServices"], true);
1911 break;
1912 case "Shortcut":
1913 overridableActionRows.Add(this.standardActions[SequenceTable.AdvtExecuteSequence, "CreateShortcuts"], true);
1914 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "CreateShortcuts"], true);
1915 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RemoveShortcuts"], true);
1916 break;
1917 case "TypeLib":
1918 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "RegisterTypeLibraries"], true);
1919 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "UnregisterTypeLibraries"], true);
1920 break;
1921 case "Upgrade":
1922 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "FindRelatedProducts"], true);
1923 overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "FindRelatedProducts"], true);
1924 // Only add the MigrateFeatureStates action if MigrateFeature attribute is set to yes on at least one UpgradeVersion element.
1925 foreach (Row row in table.Rows)
1926 {
1927 int options = (int)row[4];
1928 if (MsiInterop.MsidbUpgradeAttributesMigrateFeatures == (options & MsiInterop.MsidbUpgradeAttributesMigrateFeatures))
1929 {
1930 overridableActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "MigrateFeatureStates"], true);
1931 overridableActionRows.Add(this.standardActions[SequenceTable.InstallUISequence, "MigrateFeatureStates"], true);
1932 break;
1933 }
1934 }
1935 break;
1936 }
1937 }
1938
1939 // index all the action rows (look for collisions)
1940 foreach (WixActionRow actionRow in actionRows)
1941 {
1942 if (actionRow.Overridable) // overridable action
1943 {
1944 WixActionRow collidingActionRow = overridableActionRows[actionRow.SequenceTable, actionRow.Action];
1945
1946 if (null != collidingActionRow)
1947 {
1948 this.OnMessage(WixErrors.OverridableActionCollision(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action));
1949 if (null != collidingActionRow.SourceLineNumbers)
1950 {
1951 this.OnMessage(WixErrors.OverridableActionCollision2(collidingActionRow.SourceLineNumbers));
1952 }
1953 }
1954 else
1955 {
1956 overridableActionRows.Add(actionRow);
1957 }
1958 }
1959 else // unscheduled/scheduled action
1960 {
1961 // unscheduled action (allowed for certain standard actions)
1962 if (null == actionRow.Before && null == actionRow.After && 0 == actionRow.Sequence)
1963 {
1964 WixActionRow standardAction = this.standardActions[actionRow.SequenceTable, actionRow.Action];
1965
1966 if (null != standardAction)
1967 {
1968 // populate the sequence from the standard action
1969 actionRow.Sequence = standardAction.Sequence;
1970 }
1971 else // not a supported unscheduled action
1972 {
1973 throw new InvalidOperationException(WixStrings.EXP_FoundActionRowWithNoSequenceBeforeOrAfterColumnSet);
1974 }
1975 }
1976
1977 WixActionRow collidingActionRow = requiredActionRows[actionRow.SequenceTable, actionRow.Action];
1978
1979 if (null != collidingActionRow)
1980 {
1981 this.OnMessage(WixErrors.ActionCollision(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action));
1982 if (null != collidingActionRow.SourceLineNumbers)
1983 {
1984 this.OnMessage(WixErrors.ActionCollision2(collidingActionRow.SourceLineNumbers));
1985 }
1986 }
1987 else
1988 {
1989 requiredActionRows.Add(actionRow.Clone());
1990 }
1991 }
1992 }
1993
1994 // add the overridable action rows that are not overridden to the required action rows
1995 foreach (WixActionRow actionRow in overridableActionRows)
1996 {
1997 if (null == requiredActionRows[actionRow.SequenceTable, actionRow.Action])
1998 {
1999 requiredActionRows.Add(actionRow.Clone());
2000 }
2001 }
2002
2003 // suppress the required actions that are overridable
2004 foreach (Row suppressActionRow in suppressActionRows)
2005 {
2006 SequenceTable sequenceTable = (SequenceTable)Enum.Parse(typeof(SequenceTable), (string)suppressActionRow[0]);
2007 string action = (string)suppressActionRow[1];
2008
2009 // get the action being suppressed (if it exists)
2010 WixActionRow requiredActionRow = requiredActionRows[sequenceTable, action];
2011
2012 // if there is an overridable row to suppress; suppress it
2013 // there is no warning if there is no action to suppress because the action may be suppressed from a merge module in the binder
2014 if (null != requiredActionRow)
2015 {
2016 if (requiredActionRow.Overridable)
2017 {
2018 this.OnMessage(WixWarnings.SuppressAction(suppressActionRow.SourceLineNumbers, action, sequenceTable.ToString()));
2019 if (null != requiredActionRow.SourceLineNumbers)
2020 {
2021 this.OnMessage(WixWarnings.SuppressAction2(requiredActionRow.SourceLineNumbers));
2022 }
2023 requiredActionRows.Remove(sequenceTable, action);
2024 }
2025 else // suppressing a non-overridable action row
2026 {
2027 this.OnMessage(WixErrors.SuppressNonoverridableAction(suppressActionRow.SourceLineNumbers, sequenceTable.ToString(), action));
2028 if (null != requiredActionRow.SourceLineNumbers)
2029 {
2030 this.OnMessage(WixErrors.SuppressNonoverridableAction2(requiredActionRow.SourceLineNumbers));
2031 }
2032 }
2033 }
2034 }
2035
2036 // create a copy of the required action rows so that new rows can be added while enumerating
2037 WixActionRow[] copyOfRequiredActionRows = new WixActionRow[requiredActionRows.Count];
2038 requiredActionRows.CopyTo(copyOfRequiredActionRows, 0);
2039
2040 // build up dependency trees of the relatively scheduled actions
2041 foreach (WixActionRow actionRow in copyOfRequiredActionRows)
2042 {
2043 if (0 == actionRow.Sequence)
2044 {
2045 // check for standard actions that don't have a sequence number in a merge module
2046 if (OutputType.Module == this.activeOutput.Type && WindowsInstallerStandard.IsStandardAction(actionRow.Action))
2047 {
2048 this.OnMessage(WixErrors.StandardActionRelativelyScheduledInModule(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action));
2049 }
2050
2051 this.SequenceActionRow(actionRow, requiredActionRows);
2052 }
2053 else if (OutputType.Module == this.activeOutput.Type && 0 < actionRow.Sequence && !WindowsInstallerStandard.IsStandardAction(actionRow.Action)) // check for custom actions and dialogs that have a sequence number
2054 {
2055 this.OnMessage(WixErrors.CustomActionSequencedInModule(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action));
2056 }
2057 }
2058
2059 // look for standard actions with sequence restrictions that aren't necessarily scheduled based on the presence of a particular table
2060 if (requiredActionRows.Contains(SequenceTable.InstallExecuteSequence, "DuplicateFiles") && !requiredActionRows.Contains(SequenceTable.InstallExecuteSequence, "InstallFiles"))
2061 {
2062 requiredActionRows.Add(this.standardActions[SequenceTable.InstallExecuteSequence, "InstallFiles"], true);
2063 }
2064
2065 // schedule actions
2066 if (OutputType.Module == this.activeOutput.Type)
2067 {
2068 // add the action row to the list of scheduled action rows
2069 scheduledActionRows.AddRange(requiredActionRows);
2070 }
2071 else
2072 {
2073 // process each sequence table individually
2074 foreach (SequenceTable sequenceTable in Enum.GetValues(typeof(SequenceTable)))
2075 {
2076 // create a collection of just the action rows in this sequence
2077 WixActionRowCollection sequenceActionRows = new WixActionRowCollection();
2078 foreach (WixActionRow actionRow in requiredActionRows)
2079 {
2080 if (sequenceTable == actionRow.SequenceTable)
2081 {
2082 sequenceActionRows.Add(actionRow);
2083 }
2084 }
2085
2086 // schedule the absolutely scheduled actions (by sorting them by their sequence numbers)
2087 ArrayList absoluteActionRows = new ArrayList();
2088 foreach (WixActionRow actionRow in sequenceActionRows)
2089 {
2090 if (0 != actionRow.Sequence)
2091 {
2092 // look for sequence number collisions
2093 foreach (WixActionRow sequenceScheduledActionRow in absoluteActionRows)
2094 {
2095 if (sequenceScheduledActionRow.Sequence == actionRow.Sequence)
2096 {
2097 this.OnMessage(WixWarnings.ActionSequenceCollision(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, sequenceScheduledActionRow.Action, actionRow.Sequence));
2098 if (null != sequenceScheduledActionRow.SourceLineNumbers)
2099 {
2100 this.OnMessage(WixWarnings.ActionSequenceCollision2(sequenceScheduledActionRow.SourceLineNumbers));
2101 }
2102 }
2103 }
2104
2105 absoluteActionRows.Add(actionRow);
2106 }
2107 }
2108 absoluteActionRows.Sort();
2109
2110 // schedule the relatively scheduled actions (by resolving the dependency trees)
2111 int previousUsedSequence = 0;
2112 ArrayList relativeActionRows = new ArrayList();
2113 for (int j = 0; j < absoluteActionRows.Count; j++)
2114 {
2115 WixActionRow absoluteActionRow = (WixActionRow)absoluteActionRows[j];
2116 int unusedSequence;
2117
2118 // get all the relatively scheduled action rows occuring before this absolutely scheduled action row
2119 RowIndexedList<WixActionRow> allPreviousActionRows = new RowIndexedList<WixActionRow>();
2120 absoluteActionRow.GetAllPreviousActionRows(sequenceTable, allPreviousActionRows);
2121
2122 // get all the relatively scheduled action rows occuring after this absolutely scheduled action row
2123 RowIndexedList<WixActionRow> allNextActionRows = new RowIndexedList<WixActionRow>();
2124 absoluteActionRow.GetAllNextActionRows(sequenceTable, allNextActionRows);
2125
2126 // check for relatively scheduled actions occuring before/after a special action (these have a negative sequence number)
2127 if (0 > absoluteActionRow.Sequence && (0 < allPreviousActionRows.Count || 0 < allNextActionRows.Count))
2128 {
2129 // create errors for all the before actions
2130 foreach (WixActionRow actionRow in allPreviousActionRows)
2131 {
2132 this.OnMessage(WixErrors.ActionScheduledRelativeToTerminationAction(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, absoluteActionRow.Action));
2133 }
2134
2135 // create errors for all the after actions
2136 foreach (WixActionRow actionRow in allNextActionRows)
2137 {
2138 this.OnMessage(WixErrors.ActionScheduledRelativeToTerminationAction(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, absoluteActionRow.Action));
2139 }
2140
2141 // if there is source line information for the absolutely scheduled action display it
2142 if (null != absoluteActionRow.SourceLineNumbers)
2143 {
2144 this.OnMessage(WixErrors.ActionScheduledRelativeToTerminationAction2(absoluteActionRow.SourceLineNumbers));
2145 }
2146
2147 continue;
2148 }
2149
2150 // schedule the action rows before this one
2151 unusedSequence = absoluteActionRow.Sequence - 1;
2152 for (int i = allPreviousActionRows.Count - 1; i >= 0; i--)
2153 {
2154 WixActionRow relativeActionRow = (WixActionRow)allPreviousActionRows[i];
2155
2156 // look for collisions
2157 if (unusedSequence == previousUsedSequence)
2158 {
2159 this.OnMessage(WixErrors.NoUniqueActionSequenceNumber(relativeActionRow.SourceLineNumbers, relativeActionRow.SequenceTable.ToString(), relativeActionRow.Action, absoluteActionRow.Action));
2160 if (null != absoluteActionRow.SourceLineNumbers)
2161 {
2162 this.OnMessage(WixErrors.NoUniqueActionSequenceNumber2(absoluteActionRow.SourceLineNumbers));
2163 }
2164
2165 unusedSequence++;
2166 }
2167
2168 relativeActionRow.Sequence = unusedSequence;
2169 relativeActionRows.Add(relativeActionRow);
2170
2171 unusedSequence--;
2172 }
2173
2174 // determine the next used action sequence number
2175 int nextUsedSequence;
2176 if (absoluteActionRows.Count > j + 1)
2177 {
2178 nextUsedSequence = ((WixActionRow)absoluteActionRows[j + 1]).Sequence;
2179 }
2180 else
2181 {
2182 nextUsedSequence = short.MaxValue + 1;
2183 }
2184
2185 // schedule the action rows after this one
2186 unusedSequence = absoluteActionRow.Sequence + 1;
2187 for (int i = 0; i < allNextActionRows.Count; i++)
2188 {
2189 WixActionRow relativeActionRow = (WixActionRow)allNextActionRows[i];
2190
2191 if (unusedSequence == nextUsedSequence)
2192 {
2193 this.OnMessage(WixErrors.NoUniqueActionSequenceNumber(relativeActionRow.SourceLineNumbers, relativeActionRow.SequenceTable.ToString(), relativeActionRow.Action, absoluteActionRow.Action));
2194 if (null != absoluteActionRow.SourceLineNumbers)
2195 {
2196 this.OnMessage(WixErrors.NoUniqueActionSequenceNumber2(absoluteActionRow.SourceLineNumbers));
2197 }
2198
2199 unusedSequence--;
2200 }
2201
2202 relativeActionRow.Sequence = unusedSequence;
2203 relativeActionRows.Add(relativeActionRow);
2204
2205 unusedSequence++;
2206 }
2207
2208 // keep track of this sequence number as the previous used sequence number for the next iteration
2209 previousUsedSequence = absoluteActionRow.Sequence;
2210 }
2211
2212 // add the absolutely and relatively scheduled actions to the list of scheduled actions
2213 scheduledActionRows.AddRange(absoluteActionRows);
2214 scheduledActionRows.AddRange(relativeActionRows);
2215 }
2216 }
2217
2218 // create the action rows for sequences that are not suppressed
2219 foreach (WixActionRow actionRow in scheduledActionRows)
2220 {
2221 // get the table definition for the action (and ensure the proper table exists for a module)
2222 TableDefinition sequenceTableDefinition = null;
2223 switch (actionRow.SequenceTable)
2224 {
2225 case SequenceTable.AdminExecuteSequence:
2226 if (OutputType.Module == this.activeOutput.Type)
2227 {
2228 this.activeOutput.EnsureTable(this.tableDefinitions["AdminExecuteSequence"]);
2229 sequenceTableDefinition = this.tableDefinitions["ModuleAdminExecuteSequence"];
2230 }
2231 else
2232 {
2233 sequenceTableDefinition = this.tableDefinitions["AdminExecuteSequence"];
2234 }
2235 break;
2236 case SequenceTable.AdminUISequence:
2237 if (OutputType.Module == this.activeOutput.Type)
2238 {
2239 this.activeOutput.EnsureTable(this.tableDefinitions["AdminUISequence"]);
2240 sequenceTableDefinition = this.tableDefinitions["ModuleAdminUISequence"];
2241 }
2242 else
2243 {
2244 sequenceTableDefinition = this.tableDefinitions["AdminUISequence"];
2245 }
2246 break;
2247 case SequenceTable.AdvtExecuteSequence:
2248 if (OutputType.Module == this.activeOutput.Type)
2249 {
2250 this.activeOutput.EnsureTable(this.tableDefinitions["AdvtExecuteSequence"]);
2251 sequenceTableDefinition = this.tableDefinitions["ModuleAdvtExecuteSequence"];
2252 }
2253 else
2254 {
2255 sequenceTableDefinition = this.tableDefinitions["AdvtExecuteSequence"];
2256 }
2257 break;
2258 case SequenceTable.InstallExecuteSequence:
2259 if (OutputType.Module == this.activeOutput.Type)
2260 {
2261 this.activeOutput.EnsureTable(this.tableDefinitions["InstallExecuteSequence"]);
2262 sequenceTableDefinition = this.tableDefinitions["ModuleInstallExecuteSequence"];
2263 }
2264 else
2265 {
2266 sequenceTableDefinition = this.tableDefinitions["InstallExecuteSequence"];
2267 }
2268 break;
2269 case SequenceTable.InstallUISequence:
2270 if (OutputType.Module == this.activeOutput.Type)
2271 {
2272 this.activeOutput.EnsureTable(this.tableDefinitions["InstallUISequence"]);
2273 sequenceTableDefinition = this.tableDefinitions["ModuleInstallUISequence"];
2274 }
2275 else
2276 {
2277 sequenceTableDefinition = this.tableDefinitions["InstallUISequence"];
2278 }
2279 break;
2280 }
2281
2282 // create the action sequence row in the output
2283 Table sequenceTable = this.activeOutput.EnsureTable(sequenceTableDefinition);
2284 Row row = sequenceTable.CreateRow(actionRow.SourceLineNumbers);
2285 if (this.sectionIdOnRows)
2286 {
2287 row.SectionId = actionRow.SectionId;
2288 }
2289
2290 if (OutputType.Module == this.activeOutput.Type)
2291 {
2292 row[0] = actionRow.Action;
2293 if (0 != actionRow.Sequence)
2294 {
2295 row[1] = actionRow.Sequence;
2296 }
2297 else
2298 {
2299 bool after = (null == actionRow.Before);
2300 row[2] = after ? actionRow.After : actionRow.Before;
2301 row[3] = after ? 1 : 0;
2302 }
2303 row[4] = actionRow.Condition;
2304 }
2305 else
2306 {
2307 row[0] = actionRow.Action;
2308 row[1] = actionRow.Condition;
2309 row[2] = actionRow.Sequence;
2310 }
2311 }
2312 }
2313
2314 /// <summary>
2315 /// Sequence an action before or after a standard action.
2316 /// </summary>
2317 /// <param name="actionRow">The action row to be sequenced.</param>
2318 /// <param name="requiredActionRows">Collection of actions which must be included.</param>
2319 [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.InvalidOperationException.#ctor(System.String)")]
2320 private void SequenceActionRow(WixActionRow actionRow, WixActionRowCollection requiredActionRows)
2321 {
2322 bool after = false;
2323 if (actionRow.After != null)
2324 {
2325 after = true;
2326 }
2327 else if (actionRow.Before == null)
2328 {
2329 throw new InvalidOperationException(WixStrings.EXP_FoundActionRowWithNoSequenceBeforeOrAfterColumnSet);
2330 }
2331
2332 string parentActionName = (after ? actionRow.After : actionRow.Before);
2333 WixActionRow parentActionRow = requiredActionRows[actionRow.SequenceTable, parentActionName];
2334
2335 if (null == parentActionRow)
2336 {
2337 parentActionRow = this.standardActions[actionRow.SequenceTable, parentActionName];
2338
2339 // if the missing parent action is a standard action (with a suggested sequence number), add it
2340 if (null != parentActionRow)
2341 {
2342 // Create a clone to avoid modifying the static copy of the object.
2343 parentActionRow = parentActionRow.Clone();
2344 requiredActionRows.Add(parentActionRow);
2345 }
2346 else
2347 {
2348 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_FoundActionRowWinNonExistentAction, (after ? "After" : "Before"), parentActionName));
2349 }
2350 }
2351 else if (actionRow == parentActionRow || actionRow.ContainsChildActionRow(parentActionRow)) // cycle detected
2352 {
2353 throw new WixException(WixErrors.ActionCircularDependency(actionRow.SourceLineNumbers, actionRow.SequenceTable.ToString(), actionRow.Action, parentActionRow.Action));
2354 }
2355
2356 // Add this action to the appropriate list of dependent action rows.
2357 WixActionRowCollection relatedRows = (after ? parentActionRow.NextActionRows : parentActionRow.PreviousActionRows);
2358 relatedRows.Add(actionRow);
2359 }
2360#endif
2361 1695
2362 /// <summary> 1696 /// <summary>
2363 /// Resolve features for columns that have null guid placeholders. 1697 /// Resolve features for columns that have null guid placeholders.
diff --git a/src/WixToolset.Core/WindowsInstallerStandard.cs b/src/WixToolset.Core/WindowsInstallerStandard.cs
deleted file mode 100644
index 90a53e6a..00000000
--- a/src/WixToolset.Core/WindowsInstallerStandard.cs
+++ /dev/null
@@ -1,260 +0,0 @@
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
3namespace WixToolset.Core
4{
5 using System.Collections.Generic;
6 using WixToolset.Data;
7 using WixToolset.Data.Tuples;
8
9 internal class WindowsInstallerStandard
10 {
11 private static readonly HashSet<string> standardActionNames = new HashSet<string>
12 {
13 "AllocateRegistrySpace",
14 "AppSearch",
15 "BindImage",
16 "CCPSearch",
17 "CostFinalize",
18 "CostInitialize",
19 "CreateFolders",
20 "CreateShortcuts",
21 "DeleteServices",
22 "DisableRollback",
23 "DuplicateFiles",
24 "ExecuteAction",
25 "FileCost",
26 "FindRelatedProducts",
27 "ForceReboot",
28 "InstallAdminPackage",
29 "InstallExecute",
30 "InstallExecuteAgain",
31 "InstallFiles",
32 "InstallFinalize",
33 "InstallInitialize",
34 "InstallODBC",
35 "InstallServices",
36 "InstallSFPCatalogFile",
37 "InstallValidate",
38 "IsolateComponents",
39 "LaunchConditions",
40 "MigrateFeatureStates",
41 "MoveFiles",
42 "MsiConfigureServices",
43 "MsiPublishAssemblies",
44 "MsiUnpublishAssemblies",
45 "PatchFiles",
46 "ProcessComponents",
47 "PublishComponents",
48 "PublishFeatures",
49 "PublishProduct",
50 "RegisterClassInfo",
51 "RegisterComPlus",
52 "RegisterExtensionInfo",
53 "RegisterFonts",
54 "RegisterMIMEInfo",
55 "RegisterProduct",
56 "RegisterProgIdInfo",
57 "RegisterTypeLibraries",
58 "RegisterUser",
59 "RemoveDuplicateFiles",
60 "RemoveEnvironmentStrings",
61 "RemoveExistingProducts",
62 "RemoveFiles",
63 "RemoveFolders",
64 "RemoveIniValues",
65 "RemoveODBC",
66 "RemoveRegistryValues",
67 "RemoveShortcuts",
68 "ResolveSource",
69 "RMCCPSearch",
70 "ScheduleReboot",
71 "SelfRegModules",
72 "SelfUnregModules",
73 "SetODBCFolders",
74 "StartServices",
75 "StopServices",
76 "UnpublishComponents",
77 "UnpublishFeatures",
78 "UnregisterClassInfo",
79 "UnregisterComPlus",
80 "UnregisterExtensionInfo",
81 "UnregisterFonts",
82 "UnregisterMIMEInfo",
83 "UnregisterProgIdInfo",
84 "UnregisterTypeLibraries",
85 "ValidateProductID",
86 "WriteEnvironmentStrings",
87 "WriteIniValues",
88 "WriteRegistryValues",
89 };
90
91 private static readonly WixActionTuple[] standardActions = new[]
92 {
93 new WixActionTuple(null, new Identifier("AdminExecuteSequence/InstallInitialize", AccessModifier.Public)) { Action="InstallInitialize", Sequence=1500, SequenceTable=SequenceTable.AdminExecuteSequence },
94 new WixActionTuple(null, new Identifier("AdvtExecuteSequence/InstallInitialize", AccessModifier.Public)) { Action="InstallInitialize", Sequence=1500, SequenceTable=SequenceTable.AdvtExecuteSequence },
95 new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallInitialize", AccessModifier.Public)) { Action="InstallInitialize", Sequence=1500, SequenceTable=SequenceTable.InstallExecuteSequence },
96
97 new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallExecute", AccessModifier.Public)) { Action="InstallExecute", Sequence=6500, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="NOT Installed" },
98
99 new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallExecuteAgain", AccessModifier.Public)) { Action="InstallExecuteAgain", Sequence=6550, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="NOT Installed" },
100
101 new WixActionTuple(null, new Identifier("AdminExecuteSequence/InstallFinalize", AccessModifier.Public)) { Action="InstallFinalize", Sequence=6600, SequenceTable=SequenceTable.AdminExecuteSequence },
102 new WixActionTuple(null, new Identifier("AdvtExecuteSequence/InstallFinalize", AccessModifier.Public)) { Action="InstallFinalize", Sequence=6600, SequenceTable=SequenceTable.AdvtExecuteSequence },
103 new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallFinalize", AccessModifier.Public)) { Action="InstallFinalize", Sequence=6600, SequenceTable=SequenceTable.InstallExecuteSequence },
104
105 new WixActionTuple(null, new Identifier("AdminExecuteSequence/InstallFiles", AccessModifier.Public)) { Action="InstallFiles", Sequence=4000, SequenceTable=SequenceTable.AdminExecuteSequence },
106 new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallFiles", AccessModifier.Public)) { Action="InstallFiles", Sequence=4000, SequenceTable=SequenceTable.InstallExecuteSequence },
107
108 new WixActionTuple(null, new Identifier("AdminExecuteSequence/InstallAdminPackage", AccessModifier.Public)) { Action="InstallAdminPackage", Sequence=3900, SequenceTable=SequenceTable.AdminExecuteSequence },
109
110 new WixActionTuple(null, new Identifier("AdminExecuteSequence/FileCost", AccessModifier.Public)) { Action="FileCost", Sequence=900, SequenceTable=SequenceTable.AdminExecuteSequence },
111 new WixActionTuple(null, new Identifier("InstallExecuteSequence/FileCost", AccessModifier.Public)) { Action="FileCost", Sequence=900, SequenceTable=SequenceTable.InstallExecuteSequence },
112 new WixActionTuple(null, new Identifier("InstallUISequence/FileCost", AccessModifier.Public)) { Action="FileCost", Sequence=900, SequenceTable=SequenceTable.InstallUISequence },
113
114 new WixActionTuple(null, new Identifier("AdminExecuteSequence/CostInitialize", AccessModifier.Public)) { Action="CostInitialize", Sequence=800, SequenceTable=SequenceTable.AdminExecuteSequence },
115 new WixActionTuple(null, new Identifier("AdminUISequence/CostInitialize", AccessModifier.Public)) { Action="CostInitialize", Sequence=800, SequenceTable=SequenceTable.AdminUISequence },
116 new WixActionTuple(null, new Identifier("AdvtExecuteSequence/CostInitialize", AccessModifier.Public)) { Action="CostInitialize", Sequence=800, SequenceTable=SequenceTable.AdvtExecuteSequence },
117 new WixActionTuple(null, new Identifier("InstallExecuteSequence/CostInitialize", AccessModifier.Public)) { Action="CostInitialize", Sequence=800, SequenceTable=SequenceTable.InstallExecuteSequence },
118 new WixActionTuple(null, new Identifier("InstallUISequence/CostInitialize", AccessModifier.Public)) { Action="CostInitialize", Sequence=800, SequenceTable=SequenceTable.InstallUISequence },
119
120 new WixActionTuple(null, new Identifier("AdminExecuteSequence/CostFinalize", AccessModifier.Public)) { Action="CostFinalize", Sequence=1000, SequenceTable=SequenceTable.AdminExecuteSequence },
121 new WixActionTuple(null, new Identifier("AdminUISequence/CostFinalize", AccessModifier.Public)) { Action="CostFinalize", Sequence=1000, SequenceTable=SequenceTable.AdminUISequence },
122 new WixActionTuple(null, new Identifier("AdvtExecuteSequence/CostFinalize", AccessModifier.Public)) { Action="CostFinalize", Sequence=1000, SequenceTable=SequenceTable.AdvtExecuteSequence },
123 new WixActionTuple(null, new Identifier("InstallExecuteSequence/CostFinalize", AccessModifier.Public)) { Action="CostFinalize", Sequence=1000, SequenceTable=SequenceTable.InstallExecuteSequence },
124 new WixActionTuple(null, new Identifier("InstallUISequence/CostFinalize", AccessModifier.Public)) { Action="CostFinalize", Sequence=1000, SequenceTable=SequenceTable.InstallUISequence },
125
126 new WixActionTuple(null, new Identifier("AdminExecuteSequence/InstallValidate", AccessModifier.Public)) { Action="InstallValidate", Sequence=1400, SequenceTable=SequenceTable.AdminExecuteSequence },
127 new WixActionTuple(null, new Identifier("AdvtExecuteSequence/InstallValidate", AccessModifier.Public)) { Action="InstallValidate", Sequence=1400, SequenceTable=SequenceTable.AdvtExecuteSequence },
128 new WixActionTuple(null, new Identifier("InstallExecuteSequence/InstallValidate", AccessModifier.Public)) { Action="InstallValidate", Sequence=1400, SequenceTable=SequenceTable.InstallExecuteSequence },
129
130 new WixActionTuple(null, new Identifier("AdminUISequence/ExecuteAction", AccessModifier.Public)) { Action="ExecuteAction", Sequence=1300, SequenceTable=SequenceTable.AdminUISequence },
131 new WixActionTuple(null, new Identifier("InstallUISequence/ExecuteAction", AccessModifier.Public)) { Action="ExecuteAction", Sequence=1300, SequenceTable=SequenceTable.InstallUISequence },
132
133 new WixActionTuple(null, new Identifier("AdvtExecuteSequence/CreateShortcuts", AccessModifier.Public)) { Action="CreateShortcuts", Sequence=4500, SequenceTable=SequenceTable.AdvtExecuteSequence },
134 new WixActionTuple(null, new Identifier("InstallExecuteSequence/CreateShortcuts", AccessModifier.Public)) { Action="CreateShortcuts", Sequence=4500, SequenceTable=SequenceTable.InstallExecuteSequence },
135
136 new WixActionTuple(null, new Identifier("AdvtExecuteSequence/MsiPublishAssemblies", AccessModifier.Public)) { Action="MsiPublishAssemblies", Sequence=6250, SequenceTable=SequenceTable.AdvtExecuteSequence },
137 new WixActionTuple(null, new Identifier("InstallExecuteSequence/MsiPublishAssemblies", AccessModifier.Public)) { Action="MsiPublishAssemblies", Sequence=6250, SequenceTable=SequenceTable.InstallExecuteSequence },
138
139 //<action name="PublishComponents" sequence="6200" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
140 //<action name="PublishFeatures" sequence="6300" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
141 //<action name="PublishProduct" sequence="6400" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
142 //<action name="RegisterClassInfo" sequence="4600" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
143 //<action name="RegisterExtensionInfo" sequence="4700" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
144 //<action name="RegisterMIMEInfo" sequence="4900" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
145 //<action name="RegisterProgIdInfo" sequence="4800" AdvtExecuteSequence="yes" InstallExecuteSequence="yes" />
146 //<action name="AllocateRegistrySpace" condition="NOT Installed" sequence="1550" InstallExecuteSequence="yes" />
147 //<action name="AppSearch" sequence="50" InstallExecuteSequence="yes" InstallUISequence="yes" />
148 //<action name="BindImage" sequence="4300" InstallExecuteSequence="yes" />
149 //<action name="CreateFolders" sequence="3700" InstallExecuteSequence="yes" />
150 //<action name="DuplicateFiles" sequence="4210" InstallExecuteSequence="yes" />
151 //<action name="FindRelatedProducts" sequence="25" InstallExecuteSequence="yes" InstallUISequence="yes" />
152 //<action name="InstallODBC" sequence="5400" InstallExecuteSequence="yes" />
153 //<action name="InstallServices" condition="VersionNT" sequence="5800" InstallExecuteSequence="yes" />
154 //<action name="MsiConfigureServices" condition="VersionNT>=600" sequence="5850" InstallExecuteSequence="yes" />
155 //<action name="IsolateComponents" sequence="950" InstallExecuteSequence="yes" InstallUISequence="yes" />
156 //<action name="LaunchConditions" sequence="100" AdminExecuteSequence="yes" AdminUISequence="yes" InstallExecuteSequence="yes" InstallUISequence="yes" />
157 //<action name="MigrateFeatureStates" sequence="1200" InstallExecuteSequence="yes" InstallUISequence="yes" />
158 //<action name="MoveFiles" sequence="3800" InstallExecuteSequence="yes" />
159 //<action name="PatchFiles" sequence="4090" AdminExecuteSequence="yes" InstallExecuteSequence="yes" />
160 //<action name="ProcessComponents" sequence="1600" InstallExecuteSequence="yes" />
161 //<action name="RegisterComPlus" sequence="5700" InstallExecuteSequence="yes" />
162 //<action name="RegisterFonts" sequence="5300" InstallExecuteSequence="yes" />
163 //<action name="RegisterProduct" sequence="6100" InstallExecuteSequence="yes" />
164 //<action name="RegisterTypeLibraries" sequence="5500" InstallExecuteSequence="yes" />
165 //<action name="RegisterUser" sequence="6000" InstallExecuteSequence="yes" />
166 //<action name="RemoveDuplicateFiles" sequence="3400" InstallExecuteSequence="yes" />
167 //<action name="RemoveEnvironmentStrings" sequence="3300" InstallExecuteSequence="yes" />
168 //<action name="RemoveFiles" sequence="3500" InstallExecuteSequence="yes" />
169 //<action name="RemoveFolders" sequence="3600" InstallExecuteSequence="yes" />
170 //<action name="RemoveIniValues" sequence="3100" InstallExecuteSequence="yes" />
171 //<action name="RemoveODBC" sequence="2400" InstallExecuteSequence="yes" />
172 //<action name="RemoveRegistryValues" sequence="2600" InstallExecuteSequence="yes" />
173 //<action name="RemoveShortcuts" sequence="3200" InstallExecuteSequence="yes" />
174 //<action name="SelfRegModules" sequence="5600" InstallExecuteSequence="yes" />
175 //<action name="SelfUnregModules" sequence="2200" InstallExecuteSequence="yes" />
176 //<action name="SetODBCFolders" sequence="1100" InstallExecuteSequence="yes" />
177
178
179 new WixActionTuple(null, new Identifier("InstallExecuteSequence/CCPSearch", AccessModifier.Public)) { Action="CCPSearch", Sequence=500, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="NOT Installed" },
180 new WixActionTuple(null, new Identifier("InstallUISequence/CCPSearch", AccessModifier.Public)) { Action="CCPSearch", Sequence=500, SequenceTable=SequenceTable.InstallUISequence, Condition="NOT Installed" },
181
182 new WixActionTuple(null, new Identifier("InstallExecuteSequence/DeleteServices", AccessModifier.Public)) { Action="DeleteServices", Sequence=2000, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="VersionNT" },
183
184 new WixActionTuple(null, new Identifier("InstallExecuteSequence/RMCCPSearch", AccessModifier.Public)) { Action="RMCCPSearch", Sequence=600, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="NOT Installed" },
185 new WixActionTuple(null, new Identifier("InstallUISequence/RMCCPSearch", AccessModifier.Public)) { Action="RMCCPSearch", Sequence=600, SequenceTable=SequenceTable.InstallUISequence, Condition="NOT Installed" },
186
187 new WixActionTuple(null, new Identifier("InstallExecuteSequence/StartServices", AccessModifier.Public)) { Action="StartServices", Sequence=5900, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="VersionNT" },
188 new WixActionTuple(null, new Identifier("InstallExecuteSequence/StopServices", AccessModifier.Public)) { Action="StopServices", Sequence=1900, SequenceTable=SequenceTable.InstallExecuteSequence, Condition="VersionNT" },
189
190 new WixActionTuple(null, new Identifier("InstallExecuteSequence/MsiUnpublishAssemblies", AccessModifier.Public)) { Action="MsiUnpublishAssemblies", Sequence=1750, SequenceTable=SequenceTable.InstallExecuteSequence },
191 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnpublishComponents", AccessModifier.Public)) { Action="UnpublishComponents", Sequence=1700, SequenceTable=SequenceTable.InstallExecuteSequence },
192 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnpublishFeatures", AccessModifier.Public)) { Action="UnpublishFeatures", Sequence=1800, SequenceTable=SequenceTable.InstallExecuteSequence },
193 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterClassInfo", AccessModifier.Public)) { Action="UnregisterClassInfo", Sequence=2700, SequenceTable=SequenceTable.InstallExecuteSequence },
194 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterComPlus", AccessModifier.Public)) { Action="UnregisterComPlus", Sequence=2100, SequenceTable=SequenceTable.InstallExecuteSequence },
195 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterExtensionInfo", AccessModifier.Public)) { Action="UnregisterExtensionInfo", Sequence=2800, SequenceTable=SequenceTable.InstallExecuteSequence },
196 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterFonts", AccessModifier.Public)) { Action="UnregisterFonts", Sequence=2500, SequenceTable=SequenceTable.InstallExecuteSequence },
197 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterMIMEInfo", AccessModifier.Public)) { Action="UnregisterMIMEInfo", Sequence=3000, SequenceTable=SequenceTable.InstallExecuteSequence },
198 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterProgIdInfo", AccessModifier.Public)) { Action="UnregisterProgIdInfo", Sequence=2900, SequenceTable=SequenceTable.InstallExecuteSequence },
199 new WixActionTuple(null, new Identifier("InstallExecuteSequence/UnregisterTypeLibraries", AccessModifier.Public)) { Action="UnregisterTypeLibraries", Sequence=2300, SequenceTable=SequenceTable.InstallExecuteSequence },
200 new WixActionTuple(null, new Identifier("InstallExecuteSequence/ValidateProductID", AccessModifier.Public)) { Action="ValidateProductID", Sequence=700, SequenceTable=SequenceTable.InstallExecuteSequence },
201 new WixActionTuple(null, new Identifier("InstallExecuteSequence/WriteEnvironmentStrings", AccessModifier.Public)) { Action="WriteEnvironmentStrings", Sequence=5200, SequenceTable=SequenceTable.InstallExecuteSequence },
202 new WixActionTuple(null, new Identifier("InstallExecuteSequence/WriteIniValues", AccessModifier.Public)) { Action="WriteIniValues", Sequence=5100, SequenceTable=SequenceTable.InstallExecuteSequence },
203 new WixActionTuple(null, new Identifier("InstallExecuteSequence/WriteRegistryValues", AccessModifier.Public)) { Action="WriteRegistryValues", Sequence=5000, SequenceTable=SequenceTable.InstallExecuteSequence },
204 };
205
206 private static readonly HashSet<string> standardDirectories = new HashSet<string>
207 {
208 "TARGETDIR",
209 "AdminToolsFolder",
210 "AppDataFolder",
211 "CommonAppDataFolder",
212 "CommonFilesFolder",
213 "DesktopFolder",
214 "FavoritesFolder",
215 "FontsFolder",
216 "LocalAppDataFolder",
217 "MyPicturesFolder",
218 "PersonalFolder",
219 "ProgramFilesFolder",
220 "ProgramMenuFolder",
221 "SendToFolder",
222 "StartMenuFolder",
223 "StartupFolder",
224 "System16Folder",
225 "SystemFolder",
226 "TempFolder",
227 "TemplateFolder",
228 "WindowsFolder",
229 "CommonFiles64Folder",
230 "ProgramFiles64Folder",
231 "System64Folder",
232 "NetHoodFolder",
233 "PrintHoodFolder",
234 "RecentFolder",
235 "WindowsVolume",
236 };
237
238 /// <summary>
239 /// Find out if an action is a standard action.
240 /// </summary>
241 /// <param name="actionName">Name of the action.</param>
242 /// <returns>true if the action is standard, false otherwise.</returns>
243 public static bool IsStandardAction(string actionName)
244 {
245 return standardActionNames.Contains(actionName);
246 }
247
248 public static WixActionTuple[] StandardActions() => standardActions;
249
250 /// <summary>
251 /// Find out if a directory is a standard directory.
252 /// </summary>
253 /// <param name="directoryName">Name of the directory.</param>
254 /// <returns>true if the directory is standard, false otherwise.</returns>
255 public static bool IsStandardDirectory(string directoryName)
256 {
257 return standardDirectories.Contains(directoryName);
258 }
259 }
260}
diff --git a/src/WixToolset.Core/WixStrings.Designer.cs b/src/WixToolset.Core/WixStrings.Designer.cs
index 75e2b908..36e64267 100644
--- a/src/WixToolset.Core/WixStrings.Designer.cs
+++ b/src/WixToolset.Core/WixStrings.Designer.cs
@@ -163,7 +163,7 @@ namespace WixToolset {
163 /// <summary> 163 /// <summary>
164 /// Looks up a localized string similar to Found an ActionRow with a non-existent {0} action: {1}.. 164 /// Looks up a localized string similar to Found an ActionRow with a non-existent {0} action: {1}..
165 /// </summary> 165 /// </summary>
166 internal static string EXP_FoundActionRowWinNonExistentAction { 166 public static string EXP_FoundActionRowWinNonExistentAction {
167 get { 167 get {
168 return ResourceManager.GetString("EXP_FoundActionRowWinNonExistentAction", resourceCulture); 168 return ResourceManager.GetString("EXP_FoundActionRowWinNonExistentAction", resourceCulture);
169 } 169 }
@@ -172,7 +172,7 @@ namespace WixToolset {
172 /// <summary> 172 /// <summary>
173 /// Looks up a localized string similar to Found an ActionRow with no Sequence, Before, or After column set.. 173 /// Looks up a localized string similar to Found an ActionRow with no Sequence, Before, or After column set..
174 /// </summary> 174 /// </summary>
175 internal static string EXP_FoundActionRowWithNoSequenceBeforeOrAfterColumnSet { 175 public static string EXP_FoundActionRowWithNoSequenceBeforeOrAfterColumnSet {
176 get { 176 get {
177 return ResourceManager.GetString("EXP_FoundActionRowWithNoSequenceBeforeOrAfterColumnSet", resourceCulture); 177 return ResourceManager.GetString("EXP_FoundActionRowWithNoSequenceBeforeOrAfterColumnSet", resourceCulture);
178 } 178 }