aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core/Linker.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core/Linker.cs')
-rw-r--r--src/WixToolset.Core/Linker.cs670
1 files changed, 2 insertions, 668 deletions
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.