System.Data.SQLite

Check-in [7529b275e1]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Maintainability improvements to registry handling in the design-time components installer.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | vs2017
Files: files | file ages | folders
SHA1: 7529b275e175fe5c3d20824c22f1eceae2c3961c
User & Date: mistachkin 2017-08-07 20:50:37.586
References
2017-11-01
12:59
In the design-time components installer, fix registry key name in GetAssemblyFoldersKeyName broken by check-in [7529b275e1]. check-in: 5010e3dca4 user: mistachkin tags: trunk
Context
2017-09-28
18:14
Merge updates from trunk. check-in: 37be32bdd4 user: mistachkin tags: vs2017
2017-08-07
20:50
Maintainability improvements to registry handling in the design-time components installer. check-in: 7529b275e1 user: mistachkin tags: vs2017
19:42
Merge updates from trunk. check-in: 3460b9641f user: mistachkin tags: vs2017
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to tools/install/Installer.cs.
19
20
21
22
23
24
25

26
27
28
29
30
31
32
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33







+








using System.Security;

#if NET_20 || NET_35
using System.Security.Permissions;
#endif

using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
using Microsoft.Win32;

namespace System.Data.SQLite
{
767
768
769
770
771
772
773

774
775

776
777
778
779
780
781
782
783
784
785
786
787
788
789
790

791
792

793
794
795
796
797
798
799
800
801
802
803
804
805
806
807

808
809

810
811
812
813
814
815
816
817
818
819
820
821
822
823
824

825
826

827
828
829
830
831
832
833
834
835
836
837
838
839
840
841

842
843

844
845
846
847
848
849
850
851
852
853
854
855
856
857
858

859
860

861
862
863
864
865
866
867
868
869
870
871
872
873
874
875

876
877

878
879
880
881
882
883
884
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899







+


+















+


+















+


+















+


+















+


+















+


+















+


+







            public MockRegistryKey ClassesRoot
            {
                get
                {
                    CheckDisposed();

                    if (classesRoot == null)
                    {
                        classesRoot = new MockRegistryKey(
                            Registry.ClassesRoot, whatIf, readOnly, safe);
                    }

                    return classesRoot;
                }
            }

            ///////////////////////////////////////////////////////////////////

            private MockRegistryKey currentConfig;
            public MockRegistryKey CurrentConfig
            {
                get
                {
                    CheckDisposed();

                    if (currentConfig == null)
                    {
                        currentConfig = new MockRegistryKey(
                            Registry.CurrentConfig, whatIf, readOnly, safe);
                    }

                    return currentConfig;
                }
            }

            ///////////////////////////////////////////////////////////////////

            private MockRegistryKey currentUser;
            public MockRegistryKey CurrentUser
            {
                get
                {
                    CheckDisposed();

                    if (currentUser == null)
                    {
                        currentUser = new MockRegistryKey(
                            Registry.CurrentUser, whatIf, readOnly, safe);
                    }

                    return currentUser;
                }
            }

            ///////////////////////////////////////////////////////////////////

            private MockRegistryKey dynData;
            public MockRegistryKey DynData
            {
                get
                {
                    CheckDisposed();

                    if (dynData == null)
                    {
                        dynData = new MockRegistryKey(
                            Registry.DynData, whatIf, readOnly, safe);
                    }

                    return dynData;
                }
            }

            ///////////////////////////////////////////////////////////////////

            private MockRegistryKey localMachine;
            public MockRegistryKey LocalMachine
            {
                get
                {
                    CheckDisposed();

                    if (localMachine == null)
                    {
                        localMachine = new MockRegistryKey(
                            Registry.LocalMachine, whatIf, readOnly, safe);
                    }

                    return localMachine;
                }
            }

            ///////////////////////////////////////////////////////////////////

            private MockRegistryKey performanceData;
            public MockRegistryKey PerformanceData
            {
                get
                {
                    CheckDisposed();

                    if (performanceData == null)
                    {
                        performanceData = new MockRegistryKey(
                            Registry.PerformanceData, whatIf, readOnly, safe);
                    }

                    return performanceData;
                }
            }

            ///////////////////////////////////////////////////////////////////

            private MockRegistryKey users;
            public MockRegistryKey Users
            {
                get
                {
                    CheckDisposed();

                    if (users == null)
                    {
                        users = new MockRegistryKey(
                            Registry.Users, whatIf, readOnly, safe);
                    }

                    return users;
                }
            }
            #endregion

            ///////////////////////////////////////////////////////////////////
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200










1201
1202
1203
1204
1205
1206
1207
1204
1205
1206
1207
1208
1209
1210





1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227







-
-
-
-
-
+
+
+
+
+
+
+
+
+
+







                    // HACK: Attempt to open the specified sub-key.  If this
                    //       fails, we will simply return the wrapped root key
                    //       itself since no writes are allowed in "what-if"
                    //       mode anyhow.
                    //
                    RegistryKey subKey = key.OpenSubKey(subKeyName);

                    return (subKey != null) ?
                        new MockRegistryKey(
                                subKey, whatIf, readOnly, safe) :
                        new MockRegistryKey(
                                key, subKeyName, whatIf, readOnly, safe);
                    if (subKey != null)
                    {
                        return new MockRegistryKey(
                            subKey, whatIf, readOnly, safe);
                    }
                    else
                    {
                        return new MockRegistryKey(
                            key, subKeyName, whatIf, readOnly, safe);
                    }
                }
                else
                {
                    return new MockRegistryKey(
                        key.CreateSubKey(subKeyName), whatIf, readOnly, safe);
                }
            }
1281
1282
1283
1284
1285
1286
1287












1288
1289
1290
1291
1292
1293
1294
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326







+
+
+
+
+
+
+
+
+
+
+
+







                    return null;

                return key.GetValue(name, defaultValue);
            }

            ///////////////////////////////////////////////////////////////////

            public string[] GetValueNames()
            {
                CheckDisposed();

                if (key == null)
                    return null;

                return key.GetValueNames();
            }

            ///////////////////////////////////////////////////////////////////

            public MockRegistryKey OpenSubKey(
                string subKeyName
                )
            {
                CheckDisposed();

                return OpenSubKey(subKeyName, false);
1308
1309
1310
1311
1312
1313
1314

1315
1316



1317
1318
1319
1320
1321
1322
1323
1340
1341
1342
1343
1344
1345
1346
1347


1348
1349
1350
1351
1352
1353
1354
1355
1356
1357







+
-
-
+
+
+








                if (key == null)
                    return null;

                RegistryKey subKey = key.OpenSubKey(
                    subKeyName, whatIf ? false : writable);

                if (subKey == null)
                return (subKey != null) ?
                    new MockRegistryKey(subKey, whatIf, readOnly, safe) : null;
                    return null;

                return new MockRegistryKey(subKey, whatIf, readOnly, safe);
            }

            ///////////////////////////////////////////////////////////////////

            public void SetValue(
                string name,
                object value
1343
1344
1345
1346
1347
1348
1349
1350

1351
1352
1353
1354
1355
1356
1357
1377
1378
1379
1380
1381
1382
1383

1384
1385
1386
1387
1388
1389
1390
1391







-
+







                {
                    CheckDisposed();

                    if (key == null)
                        return null;

                    return !String.IsNullOrEmpty(subKeyName) ?
                        String.Format("{0}\\{1}", key.Name, subKeyName) :
                        RegistryHelper.JoinKeyNames(key.Name, subKeyName) :
                        key.Name;
                }
            }

            ///////////////////////////////////////////////////////////////////

            private RegistryKey key;
1513
1514
1515
1516
1517
1518
1519








































1520












1521
1522
1523
















1524
1525
1526
1527
1528
1529
1530
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
+
+



+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







            }
            #endregion
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region RegistryRootKeyNames Class
        private static class RegistryRootKeyNames
        {
            public const string HKEY_CLASSES_ROOT = "HKEY_CLASSES_ROOT";
            public const string HKCR = "HKCR";

            ///////////////////////////////////////////////////////////////////

            public const string HKEY_CURRENT_CONFIG = "HKEY_CURRENT_CONFIG";
            public const string HKCC = "HKCC";

            ///////////////////////////////////////////////////////////////////

            public const string HKEY_CURRENT_USER = "HKEY_CURRENT_USER";
            public const string HKCU = "HKCU";

            ///////////////////////////////////////////////////////////////////

            public const string HKEY_DYN_DATA = "HKEY_DYN_DATA";
            public const string HKDD = "HKDD";

            ///////////////////////////////////////////////////////////////////

            public const string HKEY_LOCAL_MACHINE = "HKEY_LOCAL_MACHINE";
            public const string HKLM = "HKLM";

            ///////////////////////////////////////////////////////////////////

            public const string HKEY_PERFORMANCE_DATA = "HKEY_PERFORMANCE_DATA";
            public const string HKPD = "HKPD";

            ///////////////////////////////////////////////////////////////////

            public const string HKEY_USERS = "HKEY_USERS";
            public const string HKU = "HKU";
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region RegistryHelper Class
        #region Private Constants
        private const char KeyNameSeparator = '\\';

        ///////////////////////////////////////////////////////////////////////

        private static readonly char[] KeyNameSeparators = {
            KeyNameSeparator
        };
        #endregion

        ///////////////////////////////////////////////////////////////////////

        private static class RegistryHelper
        {
            #region Public Static Properties
            private static MockRegistry readOnlyRegistry;
            public static MockRegistry ReadOnlyRegistry
            {
                get { return readOnlyRegistry; }
            }

            ///////////////////////////////////////////////////////////////////

            private static MockRegistry readWriteRegistry;
            public static MockRegistry ReadWriteRegistry
            {
                get { return readWriteRegistry; }
            }

            ///////////////////////////////////////////////////////////////////

            private static int subKeysCreated;
            public static int SubKeysCreated
            {
                get { return subKeysCreated; }
            }

            ///////////////////////////////////////////////////////////////////
1559
1560
1561
1562
1563
1564
1565






























































































































































































1566
1567
1568
1569
1570
1571
1572
1573
1574
1575

1576
1577
1578
1579
1580
1581

1582
1583
1584
1585
1586
1587
1588
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+










+






+







                get { return keyValuesDeleted; }
            }
            #endregion

            ///////////////////////////////////////////////////////////////////

            #region Public Static Methods
            public static void ReinitializeDefaultRegistries(
                bool whatIf,
                bool safe
                )
            {
                if (readOnlyRegistry != null)
                {
                    readOnlyRegistry.Dispose();
                    readOnlyRegistry = null;
                }

                if (readWriteRegistry != null)
                {
                    readWriteRegistry.Dispose();
                    readWriteRegistry = null;
                }

                readOnlyRegistry = new MockRegistry(whatIf, true, safe);
                readWriteRegistry = new MockRegistry(whatIf, false, safe);
            }

            ///////////////////////////////////////////////////////////////////

            public static MockRegistryKey GetReadOnlyRootKey(
                string name
                )
            {
                return GetRootKey(readOnlyRegistry, name);
            }

            ///////////////////////////////////////////////////////////////////

            public static MockRegistryKey GetReadWriteRootKey(
                string name
                )
            {
                return GetRootKey(readWriteRegistry, name);
            }

            ///////////////////////////////////////////////////////////////////

            public static MockRegistryKey GetRootKey(
                MockRegistry registry,
                string name
                )
            {
                if (registry == null)
                    return null;

                if (String.Equals(
                        name, RegistryRootKeyNames.HKEY_CLASSES_ROOT,
                        StringComparison.OrdinalIgnoreCase) ||
                    String.Equals(
                        name, RegistryRootKeyNames.HKCR,
                        StringComparison.OrdinalIgnoreCase))
                {
                    return registry.ClassesRoot;
                }
                else if (String.Equals(
                        name, RegistryRootKeyNames.HKEY_CURRENT_CONFIG,
                        StringComparison.OrdinalIgnoreCase) ||
                    String.Equals(
                        name, RegistryRootKeyNames.HKCC,
                        StringComparison.OrdinalIgnoreCase))
                {
                    return registry.CurrentConfig;
                }
                else if (String.Equals(
                        name, RegistryRootKeyNames.HKEY_CURRENT_USER,
                        StringComparison.OrdinalIgnoreCase) ||
                    String.Equals(
                        name, RegistryRootKeyNames.HKCU,
                        StringComparison.OrdinalIgnoreCase))
                {
                    return registry.CurrentUser;
                }
                else if (String.Equals(
                        name, RegistryRootKeyNames.HKEY_DYN_DATA,
                        StringComparison.OrdinalIgnoreCase) ||
                    String.Equals(
                        name, RegistryRootKeyNames.HKDD,
                        StringComparison.OrdinalIgnoreCase))
                {
                    return registry.DynData;
                }
                else if (String.Equals(
                        name, RegistryRootKeyNames.HKEY_LOCAL_MACHINE,
                        StringComparison.OrdinalIgnoreCase) ||
                    String.Equals(
                        name, RegistryRootKeyNames.HKLM,
                        StringComparison.OrdinalIgnoreCase))
                {
                    return registry.LocalMachine;
                }
                else if (String.Equals(
                        name, RegistryRootKeyNames.HKEY_PERFORMANCE_DATA,
                        StringComparison.OrdinalIgnoreCase) ||
                    String.Equals(
                        name, RegistryRootKeyNames.HKPD,
                        StringComparison.OrdinalIgnoreCase))
                {
                    return registry.PerformanceData;
                }
                else if (String.Equals(
                        name, RegistryRootKeyNames.HKEY_USERS,
                        StringComparison.OrdinalIgnoreCase) ||
                    String.Equals(
                        name, RegistryRootKeyNames.HKU,
                        StringComparison.OrdinalIgnoreCase))
                {
                    return registry.Users;
                }

                return null;
            }

            ///////////////////////////////////////////////////////////////////

            public static string JoinKeyNames(
                params string[] names
                )
            {
                if ((names == null) || (names.Length == 0))
                    return null;

                StringBuilder builder = new StringBuilder();

                foreach (string name in names)
                {
                    if (name == null)
                        continue;

                    string newName = name.Trim(KeyNameSeparator);

                    if (String.IsNullOrEmpty(newName))
                        continue;

                    if (builder.Length > 0)
                        builder.Append(KeyNameSeparator);

                    builder.Append(newName);
                }

                return builder.ToString();
            }

            ///////////////////////////////////////////////////////////////////

            public static string JoinKeyNames(
                MockRegistryKey key,
                params string[] names
                )
            {
                string result = JoinKeyNames(names);

                if (key != null)
                    result = JoinKeyNames(key.Name, result);

                return result;
            }

            ///////////////////////////////////////////////////////////////////

            public static string[] SplitKeyName(
                string keyName
                )
            {
                if (keyName == null)
                    return null;

                return keyName.Split(
                    KeyNameSeparators, StringSplitOptions.RemoveEmptyEntries);
            }

            ///////////////////////////////////////////////////////////////////

            public static string LastSubKeyName(
                string keyName
                )
            {
                string[] subKeyNames = SplitKeyName(keyName);

                if ((subKeyNames == null) || (subKeyNames.Length == 0))
                    return null;

                return subKeyNames[subKeyNames.Length - 1];
            }

            ///////////////////////////////////////////////////////////////////

            [MethodImpl(MethodImplOptions.NoInlining)]
            public static MockRegistryKey OpenSubKey(
                MockRegistryKey rootKey,
                string subKeyName,
                bool writable,
                bool whatIf,
                bool verbose
                )
            {
                if (verbose)
                {
                    TraceOps.DebugAndTrace(writable ?
                        TracePriority.Highest : TracePriority.Higher,
                        debugCallback, traceCallback, String.Format(
                        "rootKey = {0}, subKeyName = {1}, writable = {2}",
                        ForDisplay(rootKey), ForDisplay(subKeyName),
                        ForDisplay(writable)), traceCategory);
                }

                if (rootKey == null)
                    return null;

                //
                // HACK: Always forbid writable access when operating in
                //       "what-if" mode.
1601
1602
1603
1604
1605
1606
1607

1608
1609
1610
1611
1612

1613
1614
1615
1616
1617
1618
1619
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915







+





+







                MockRegistryKey rootKey,
                string subKeyName,
                bool whatIf,
                bool verbose
                )
            {
                if (verbose)
                {
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "rootKey = {0}, subKeyName = {1}",
                        ForDisplay(rootKey), ForDisplay(subKeyName)),
                        traceCategory);
                }

                if (rootKey == null)
                    return null;

                try
                {
                    //
1655
1656
1657
1658
1659
1660
1661

1662
1663
1664
1665
1666

1667
1668
1669
1670
1671
1672
1673
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971







+





+







                string subKeyName,
                bool throwOnMissing,
                bool whatIf,
                bool verbose
                )
            {
                if (verbose)
                {
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "rootKey = {0}, subKeyName = {1}",
                        ForDisplay(rootKey), ForDisplay(subKeyName)),
                        traceCategory);
                }

                if (rootKey == null)
                    return;

                if (!whatIf)
                    rootKey.DeleteSubKey(subKeyName, throwOnMissing);

1681
1682
1683
1684
1685
1686
1687

1688
1689
1690
1691
1692

1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712

1713
1714
1715

1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734

1735
1736
1737
1738
1739

1740
1741
1742
1743
1744
1745
1746
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050







+





+




















+



+



















+





+







                MockRegistryKey rootKey,
                string subKeyName,
                bool whatIf,
                bool verbose
                )
            {
                if (verbose)
                {
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "rootKey = {0}, subKeyName = {1}",
                        ForDisplay(rootKey), ForDisplay(subKeyName)),
                        traceCategory);
                }

                if (rootKey == null)
                    return;

                if (!whatIf)
                    rootKey.DeleteSubKeyTree(subKeyName);

                subKeysDeleted++;
            }

            ///////////////////////////////////////////////////////////////////

            [MethodImpl(MethodImplOptions.NoInlining)]
            public static string[] GetSubKeyNames(
                MockRegistryKey key,
                bool whatIf,
                bool verbose
                )
            {
                if (verbose)
                {
                    TraceOps.DebugAndTrace(TracePriority.High,
                        debugCallback, traceCallback, String.Format(
                        "key = {0}", ForDisplay(key)), traceCategory);
                }

                if (key == null)
                    return null;

                return key.GetSubKeyNames();
            }

            ///////////////////////////////////////////////////////////////////

            [MethodImpl(MethodImplOptions.NoInlining)]
            public static object GetValue(
                MockRegistryKey key,
                string name,
                object defaultValue,
                bool whatIf,
                bool verbose
                )
            {
                if (verbose)
                {
                    TraceOps.DebugAndTrace(TracePriority.High,
                        debugCallback, traceCallback, String.Format(
                        "key = {0}, name = {1}, defaultValue = {2}",
                        ForDisplay(key), ForDisplay(name),
                        ForDisplay(defaultValue)), traceCategory);
                }

                if (key == null)
                    return null;

                object value = key.GetValue(name, defaultValue);

                keyValuesRead++;
1756
1757
1758
1759
1760
1761
1762

1763
1764
1765
1766
1767

1768
1769
1770
1771
1772
1773
1774
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080







+





+







                string name,
                object value,
                bool whatIf,
                bool verbose
                )
            {
                if (verbose)
                {
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "key = {0}, name = {1}, value = {2}",
                        ForDisplay(key), ForDisplay(name), ForDisplay(value)),
                        traceCategory);
                }

                if (key == null)
                    return;

                if (!whatIf)
                    key.SetValue(name, value);

1783
1784
1785
1786
1787
1788
1789

1790
1791
1792
1793

1794
1795
1796
1797
1798
1799
1800
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108







+




+







                string name,
                bool throwOnMissing,
                bool whatIf,
                bool verbose
                )
            {
                if (verbose)
                {
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "key = {0}, name = {1}", ForDisplay(key),
                        ForDisplay(name)), traceCategory);
                }

                if (key == null)
                    return;

                if (!whatIf)
                    key.DeleteValue(name, throwOnMissing);

3437
3438
3439
3440
3441
3442
3443

3444
3445
3446
3447

3448
3449
3450
3451
3452
3453
3454
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764







+




+







                    if (!configuration.whatIf)
                    {
                        //
                        // NOTE: If the debugger is attached and "what-if"
                        //       mode is [now] disabled, issue a warning.
                        //
                        if (Debugger.IsAttached)
                        {
                            TraceOps.DebugAndTrace(TracePriority.MediumHigh,
                                debugCallback, traceCallback,
                                "Forced to disable \"what-if\" mode with " +
                                "debugger attached.", traceCategory);
                        }
                    }
                    else
                    {
                        TraceOps.DebugAndTrace(TracePriority.MediumHigh,
                            debugCallback, traceCallback,
                            "No actual changes will be made to this " +
                            "system because \"what-if\" mode is enabled.",
5023
5024
5025
5026
5027
5028
5029
5030

5031
5032

5033
5034
5035
5036
5037
5038
5039
5333
5334
5335
5336
5337
5338
5339

5340
5341

5342
5343
5344
5345
5346
5347
5348
5349







-
+

-
+







        {
            //
            // BUGFIX: Apparently, the per-user registry hive does not use
            //         the "Wow6432Node" node to store settings for 32-bit
            //         applications running on a 64-bit operating system.
            //         Ticket [a0677309f0] has further details.
            //
            return String.Format("{0}{1}", RootKeyName,
            return RegistryHelper.JoinKeyNames(RootKeyName,
                !perUser && wow64 && Is64BitProcess() ?
                    "\\" + Wow64SubKeyName : String.Empty);
                    Wow64SubKeyName : String.Empty);
        }

        ///////////////////////////////////////////////////////////////////////

        private static string GetSystemDirectory(
            bool wow64
            )
5200
5201
5202
5203
5204
5205
5206
5207
5208



5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222


5223
5224

5225
5226


5227
5228
5229
5230
5231
5232
5233
5510
5511
5512
5513
5514
5515
5516


5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531


5532
5533

5534
5535


5536
5537
5538
5539
5540
5541
5542
5543
5544







-
-
+
+
+












-
-
+
+
-

+
-
-
+
+








        #region .NET Framework Handling
        private static string GetFrameworkRootKeyName(
            bool perUser,
            bool wow64
            )
        {
            return String.Format("{0}\\Microsoft\\.NETFramework",
                GetRootKeyName(perUser, wow64));
            return RegistryHelper.JoinKeyNames(
                GetRootKeyName(perUser, wow64),
                "Microsoft", ".NETFramework");
        }

        ///////////////////////////////////////////////////////////////////////

        private static string GetFrameworkKeyName(
            string frameworkName,
            Version frameworkVersion,
            string platformName,
            bool perUser,
            bool wow64
            )
        {
            string format = !String.IsNullOrEmpty(platformName) ?
                "{0}\\Microsoft\\{1}\\v{2}\\{3}" :
            string frameworkVersionString = (frameworkVersion != null) ?
                "v" + frameworkVersion.ToString() : null;
                "{0}\\Microsoft\\{1}\\v{2}";

            return RegistryHelper.JoinKeyNames(
            return String.Format(format, GetRootKeyName(perUser, wow64),
                frameworkName, frameworkVersion, platformName);
                GetRootKeyName(perUser, wow64), "Microsoft", frameworkName,
                frameworkVersionString, platformName);
        }

        ///////////////////////////////////////////////////////////////////////

        private static string GetImageRuntimeVersion(
            string fileName
            )
5701
5702
5703
5704
5705
5706
5707

5708
5709
5710
5711
5712

5713
5714
5715
5716
5717
5718
5719
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032







+





+







                    }
                    else
                    {
                        if (localSaved && !saved)
                            saved = true;

                        if (verbose)
                        {
                            TraceOps.DebugAndTrace(TracePriority.Lowest,
                                debugCallback, traceCallback, String.Format(
                                "localSaved = {0}, saved = {1}",
                                ForDisplay(localSaved), ForDisplay(saved)),
                                traceCategory);
                        }
                    }
                }
            }

            return true;
        }

6128
6129
6130
6131
6132
6133
6134

6135
6136
6137
6138

6139
6140
6141
6142
6143
6144
6145
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460







+




+







                addElement.SetAttribute("type", fullTypeName);
                dirty = true;
            }

            if (dirty || whatIf)
            {
                if (verbose)
                {
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "addElement = {0}", ForDisplay(addElement)),
                        traceCategory);
                }

                if (!whatIf)
                    document.Save(fileName);

                filesModified++;

                saved = true;
6171
6172
6173
6174
6175
6176
6177
6178
6179


6180
6181
6182
6183
6184
6185
6186
6187
6188
6189

6190
6191
6192
6193
6194

6195
6196
6197
6198
6199
6200
6201
6486
6487
6488
6489
6490
6491
6492


6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518







-
-
+
+










+





+








            if (addElement != null)
            {
                addElement.ParentNode.RemoveChild(addElement);
                dirty = true;
            }

            XmlElement removeElement = document.SelectSingleNode(
                String.Format(XPathForRemoveElement, invariantName)) as XmlElement;
            XmlElement removeElement = document.SelectSingleNode(String.Format(
                XPathForRemoveElement, invariantName)) as XmlElement;

            if (removeElement != null)
            {
                removeElement.ParentNode.RemoveChild(removeElement);
                dirty = true;
            }

            if (dirty || whatIf)
            {
                if (verbose)
                {
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "addElement = {0}, removeElement = {1}",
                        ForDisplay(addElement), ForDisplay(removeElement)),
                        traceCategory);
                }

                if (!whatIf)
                    document.Save(fileName);

                filesModified++;

                saved = true;
6257
6258
6259
6260
6261
6262
6263



6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274



6275
6276
6277
6278
6279
6280
6281
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588






6589
6590
6591
6592
6593
6594
6595
6596
6597
6598







+
+
+





-
-
-
-
-
-
+
+
+







            string frameworkName,
            Version frameworkVersion,
            string platformName,
            bool perUser,
            bool wow64
            )
        {
            string frameworkVersionString = (frameworkVersion != null) ?
                "v" + frameworkVersion.ToString() : null;

            //
            // NOTE: This registry key appears to always be 32-bit only
            //       (i.e. probably because it is only used by Visual
            //       Studio, which is currently always 32-bit only).
            //
            string format = !String.IsNullOrEmpty(platformName) ?
                "{0}\\Microsoft\\{1}\\v{2}\\{3}\\AssemblyFoldersEx" :
                "{0}\\Microsoft\\{1}\\v{2}\\AssemblyFoldersEx";

            return String.Format(format, GetRootKeyName(perUser, wow64),
                frameworkName, frameworkVersion, platformName);
            return String.Format(GetRootKeyName(perUser, wow64),
                "Microsoft", frameworkName, frameworkVersionString,
                platformName, "AssemblyFoldersEx");
        }

        ///////////////////////////////////////////////////////////////////////

        private static bool AddToAssemblyFolders(
            MockRegistryKey rootKey,
            string frameworkName,
6296
6297
6298
6299
6300
6301
6302
6303
6304


6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316


6317
6318
6319
6320
6321
6322
6323
6613
6614
6615
6616
6617
6618
6619


6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631


6632
6633
6634
6635
6636
6637
6638
6639
6640







-
-
+
+










-
-
+
+








            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, true, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
                        "could not open registry key: {0}\\{1}",
                        rootKey, keyName);
                        "could not open registry key: {0}",
                        RegistryHelper.JoinKeyNames(rootKey, keyName));

                    return false;
                }

                using (MockRegistryKey subKey = RegistryHelper.CreateSubKey(
                        key, subKeyName, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not create registry key: {0}\\{1}",
                            key, subKeyName);
                            "could not create registry key: {0}",
                            RegistryHelper.JoinKeyNames(key, subKeyName));

                        return false;
                    }

                    RegistryHelper.SetValue(
                        subKey, null, directory, whatIf, verbose);
                }
6348
6349
6350
6351
6352
6353
6354
6355
6356


6357
6358
6359
6360
6361
6362
6363
6665
6666
6667
6668
6669
6670
6671


6672
6673
6674
6675
6676
6677
6678
6679
6680







-
-
+
+








            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, true, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
                        "could not open registry key: {0}\\{1}",
                        rootKey, keyName);
                        "could not open registry key: {0}",
                        RegistryHelper.JoinKeyNames(rootKey, keyName));

                    return false;
                }

                RegistryHelper.DeleteSubKey(
                    key, subKeyName, throwOnMissing, whatIf, verbose);
            }
6415
6416
6417
6418
6419
6420
6421
6422
6423



6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440



6441
6442
6443
6444
6445
6446
6447
6732
6733
6734
6735
6736
6737
6738


6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755



6756
6757
6758
6759
6760
6761
6762
6763
6764
6765







-
-
+
+
+














-
-
-
+
+
+








        #region Visual Studio Handling
        private static string GetVsRootKeyName(
            bool perUser,
            bool wow64
            )
        {
            return String.Format("{0}\\Microsoft\\VisualStudio",
                GetRootKeyName(perUser, wow64));
            return RegistryHelper.JoinKeyNames(
                GetRootKeyName(perUser, wow64),
                "Microsoft", "VisualStudio");
        }

        ///////////////////////////////////////////////////////////////////////

        private static string GetVsKeyName(
            Version vsVersion,
            string suffix,
            bool perUser,
            bool wow64
            )
        {
            if (vsVersion == null)
                return null;

            return String.Format(
                "{0}\\{1}{2}", GetVsRootKeyName(perUser, wow64), vsVersion,
                suffix);
            return RegistryHelper.JoinKeyNames(
                GetVsRootKeyName(perUser, wow64),
                String.Format("{0}{1}", vsVersion, suffix));
        }

        ///////////////////////////////////////////////////////////////////////

        #region Visual Studio Data Source Handling
        private static bool AddVsDataSource(
            MockRegistryKey rootKey,
6471
6472
6473
6474
6475
6476
6477
6478
6479


6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491



6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505




6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525


6526
6527
6528
6529
6530
6531
6532
6789
6790
6791
6792
6793
6794
6795


6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807


6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822


6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844


6845
6846
6847
6848
6849
6850
6851
6852
6853







-
-
+
+










-
-
+
+
+












-
-
+
+
+
+


















-
-
+
+








            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
                        "could not open registry key: {0}\\{1}",
                        rootKey, keyName);
                        "could not open registry key: {0}",
                        RegistryHelper.JoinKeyNames(rootKey, keyName));

                    return false;
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "DataSources", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\DataSources",
                            key);
                            "could not open registry key: {0}",
                            RegistryHelper.JoinKeyNames(key,
                                "DataSources"));

                        return false;
                    }

                    using (MockRegistryKey dataSourceKey =
                            RegistryHelper.CreateSubKey(subKey,
                            package.DataSourceId.ToString(VsIdFormat),
                            whatIf, verbose))
                    {
                        if (dataSourceKey == null)
                        {
                            error = String.Format(
                                "could not create registry key: {0}\\{1}", key,
                                package.DataSourceId.ToString(VsIdFormat));
                                "could not create registry key: {0}",
                                RegistryHelper.JoinKeyNames(key,
                                    package.DataSourceId.ToString(
                                        VsIdFormat)));

                            return false;
                        }

                        RegistryHelper.SetValue(
                            dataSourceKey, null, String.Format(
                            "{0} Database File", ProjectName), whatIf,
                            verbose);

                        //
                        // NOTE: This value is new as of 1.0.83.0.
                        //
                        RegistryHelper.SetValue(
                            dataSourceKey, "DefaultProvider",
                            package.DataProviderId.ToString(VsIdFormat),
                            whatIf, verbose);

                        RegistryHelper.CreateSubKey(dataSourceKey,
                            String.Format("SupportingProviders\\{0}",
                            package.DataProviderId.ToString(VsIdFormat)),
                            RegistryHelper.JoinKeyNames("SupportingProviders",
                                package.DataProviderId.ToString(VsIdFormat)),
                            whatIf, verbose);
                    }
                }
            }

            return true;
        }
6561
6562
6563
6564
6565
6566
6567
6568
6569


6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581



6582
6583
6584
6585
6586
6587
6588
6882
6883
6884
6885
6886
6887
6888


6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900


6901
6902
6903
6904
6905
6906
6907
6908
6909
6910







-
-
+
+










-
-
+
+
+








            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
                        "could not open registry key: {0}\\{1}",
                        rootKey, keyName);
                        "could not open registry key: {0}",
                        RegistryHelper.JoinKeyNames(rootKey, keyName));

                    return false;
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "DataSources", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\DataSources",
                            key);
                            "could not open registry key: {0}",
                            RegistryHelper.JoinKeyNames(key,
                                "DataSources"));

                        return false;
                    }

                    RegistryHelper.DeleteSubKeyTree(
                        subKey, package.DataSourceId.ToString(VsIdFormat),
                        whatIf, verbose);
6670
6671
6672
6673
6674
6675
6676
6677
6678


6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690



6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704




6705
6706
6707
6708
6709
6710
6711
6992
6993
6994
6995
6996
6997
6998


6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010


7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025


7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036







-
-
+
+










-
-
+
+
+












-
-
+
+
+
+








            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
                        "could not open registry key: {0}\\{1}",
                        rootKey, keyName);
                        "could not open registry key: {0}",
                        RegistryHelper.JoinKeyNames(rootKey, keyName));

                    return false;
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "DataProviders", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\DataProviders",
                            key);
                            "could not open registry key: {0}",
                            RegistryHelper.JoinKeyNames(key,
                                "DataProviders"));

                        return false;
                    }

                    using (MockRegistryKey dataProviderKey =
                            RegistryHelper.CreateSubKey(subKey,
                            package.DataProviderId.ToString(VsIdFormat),
                            whatIf, verbose))
                    {
                        if (dataProviderKey == null)
                        {
                            error = String.Format(
                                "could not create registry key: {0}\\{1}", key,
                                package.DataProviderId.ToString(VsIdFormat));
                                "could not create registry key: {0}",
                                RegistryHelper.JoinKeyNames(key,
                                    package.DataProviderId.ToString(
                                        VsIdFormat)));

                            return false;
                        }

                        RegistryHelper.SetValue(
                            dataProviderKey, null, Description, whatIf,
                            verbose);
6747
6748
6749
6750
6751
6752
6753
6754
6755


6756
6757
6758
6759


6760
6761
6762
6763


6764
6765
6766
6767


6768
6769
6770
6771


6772
6773
6774
6775
6776
6777
6778
7072
7073
7074
7075
7076
7077
7078


7079
7080
7081
7082


7083
7084
7085
7086


7087
7088
7089
7090


7091
7092
7093
7094


7095
7096
7097
7098
7099
7100
7101
7102
7103







-
-
+
+


-
-
+
+


-
-
+
+


-
-
+
+


-
-
+
+








                        RegistryHelper.SetValue(
                            dataProviderKey, "FactoryService",
                            package.ServiceId.ToString(VsIdFormat), whatIf,
                            verbose);

                        RegistryHelper.CreateSubKey(dataProviderKey,
                            "SupportedObjects\\DataConnectionUIControl",
                            whatIf, verbose);
                            RegistryHelper.JoinKeyNames("SupportedObjects",
                                "DataConnectionUIControl"), whatIf, verbose);

                        RegistryHelper.CreateSubKey(dataProviderKey,
                            "SupportedObjects\\DataConnectionProperties",
                            whatIf, verbose);
                            RegistryHelper.JoinKeyNames("SupportedObjects",
                                "DataConnectionProperties"), whatIf, verbose);

                        RegistryHelper.CreateSubKey(dataProviderKey,
                            "SupportedObjects\\DataConnectionSupport", whatIf,
                            verbose);
                            RegistryHelper.JoinKeyNames("SupportedObjects",
                                "DataConnectionSupport"), whatIf, verbose);

                        RegistryHelper.CreateSubKey(dataProviderKey,
                            "SupportedObjects\\DataObjectSupport", whatIf,
                            verbose);
                            RegistryHelper.JoinKeyNames("SupportedObjects",
                                "DataObjectSupport"), whatIf, verbose);

                        RegistryHelper.CreateSubKey(dataProviderKey,
                            "SupportedObjects\\DataViewSupport", whatIf,
                            verbose);
                            RegistryHelper.JoinKeyNames("SupportedObjects",
                                "DataViewSupport"), whatIf, verbose);
                    }
                }
            }

            return true;
        }

6800
6801
6802
6803
6804
6805
6806
6807
6808


6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820



6821
6822
6823
6824
6825
6826
6827
7125
7126
7127
7128
7129
7130
7131


7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143


7144
7145
7146
7147
7148
7149
7150
7151
7152
7153







-
-
+
+










-
-
+
+
+








            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
                        "could not open registry key: {0}\\{1}",
                        rootKey, keyName);
                        "could not open registry key: {0}",
                        RegistryHelper.JoinKeyNames(rootKey, keyName));

                    return false;
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "DataProviders", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\DataProviders",
                            key);
                            "could not open registry key: {0}",
                            RegistryHelper.JoinKeyNames(key,
                                "DataProviders"));

                        return false;
                    }

                    RegistryHelper.DeleteSubKeyTree(
                        subKey, package.DataProviderId.ToString(VsIdFormat),
                        whatIf, verbose);
6941
6942
6943
6944
6945
6946
6947
6948
6949


6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961



6962
6963
6964
6965
6966
6967
6968
7267
7268
7269
7270
7271
7272
7273


7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285


7286
7287
7288
7289
7290
7291
7292
7293
7294
7295







-
-
+
+










-
-
+
+
+








            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
                        "could not open registry key: {0}\\{1}",
                        rootKey, keyName);
                        "could not open registry key: {0}",
                        RegistryHelper.JoinKeyNames(rootKey, keyName));

                    return false;
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "Packages", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\Packages",
                            key);
                            "could not open registry key: {0}",
                            RegistryHelper.JoinKeyNames(key,
                                "Packages"));

                        return false;
                    }

                    //
                    // NOTE: *WARNING* Changing any of these values will likely
                    //       require a new "package load key" (PLK) to be
6986
6987
6988
6989
6990
6991
6992
6993
6994



6995
6996
6997
6998
6999
7000
7001
7313
7314
7315
7316
7317
7318
7319


7320
7321
7322
7323
7324
7325
7326
7327
7328
7329







-
-
+
+
+







                            RegistryHelper.CreateSubKey(subKey,
                            package.PackageId.ToString(VsIdFormat), whatIf,
                            verbose))
                    {
                        if (packageKey == null)
                        {
                            error = String.Format(
                                "could not create registry key: {0}\\{1}",
                                key, package.PackageId.ToString(VsIdFormat));
                                "could not create registry key: {0}",
                                RegistryHelper.JoinKeyNames(key,
                                    package.PackageId.ToString(VsIdFormat)));

                            return false;
                        }

                        RegistryHelper.SetValue(packageKey, null,
                            String.Format("{0} Designer Package", ProjectName),
                            whatIf, verbose);
7034
7035
7036
7037
7038
7039
7040
7041
7042



7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061



7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078



7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092



7093
7094
7095
7096
7097
7098
7099
7362
7363
7364
7365
7366
7367
7368


7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388


7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406


7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421


7422
7423
7424
7425
7426
7427
7428
7429
7430
7431







-
-
+
+
+

















-
-
+
+
+















-
-
+
+
+












-
-
+
+
+







                        using (MockRegistryKey toolboxKey =
                                RegistryHelper.CreateSubKey(packageKey,
                                "Toolbox", whatIf, verbose))
                        {
                            if (toolboxKey == null)
                            {
                                error = String.Format(
                                    "could not create registry key: " +
                                    "{0}\\Toolbox", packageKey);
                                    "could not create registry key: {0}",
                                    RegistryHelper.JoinKeyNames(packageKey,
                                        "Toolbox"));

                                return false;
                            }

                            RegistryHelper.SetValue(
                                toolboxKey, "Default Items", 3, whatIf,
                                verbose);
                        }
                    }
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "Menus", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\Menus",
                            key);
                            "could not open registry key: {0}",
                            RegistryHelper.JoinKeyNames(key,
                                "Menus"));

                        return false;
                    }

                    RegistryHelper.SetValue(
                        subKey, package.PackageId.ToString(VsIdFormat),
                        ", 1000, 3", whatIf, verbose);
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "Services", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\Services",
                            key);
                            "could not open registry key: {0}",
                            RegistryHelper.JoinKeyNames(key,
                                "Services"));

                        return false;
                    }

                    using (MockRegistryKey serviceKey =
                            RegistryHelper.CreateSubKey(subKey,
                            package.ServiceId.ToString(VsIdFormat), whatIf,
                            verbose))
                    {
                        if (serviceKey == null)
                        {
                            error = String.Format(
                                "could not create registry key: {0}\\{1}",
                                key, package.ServiceId.ToString(VsIdFormat));
                                "could not create registry key: {0}",
                                RegistryHelper.JoinKeyNames(key,
                                    package.ServiceId.ToString(VsIdFormat)));

                            return false;
                        }

                        RegistryHelper.SetValue(serviceKey, null,
                            package.PackageId.ToString(VsIdFormat), whatIf,
                            verbose);
7139
7140
7141
7142
7143
7144
7145
7146
7147


7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159



7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176



7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193



7194
7195
7196
7197
7198
7199
7200
7471
7472
7473
7474
7475
7476
7477


7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489


7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507


7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525


7526
7527
7528
7529
7530
7531
7532
7533
7534
7535







-
-
+
+










-
-
+
+
+















-
-
+
+
+















-
-
+
+
+








            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
                        "could not open registry key: {0}\\{1}",
                        rootKey, keyName);
                        "could not open registry key: {0}",
                        RegistryHelper.JoinKeyNames(rootKey, keyName));

                    return false;
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "Packages", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\Packages",
                            key);
                            "could not open registry key: {0}",
                            RegistryHelper.JoinKeyNames(key,
                                "Packages"));

                        return false;
                    }

                    RegistryHelper.DeleteSubKeyTree(
                        subKey, package.PackageId.ToString(VsIdFormat),
                        whatIf, verbose);
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "Menus", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\Menus",
                            key);
                            "could not open registry key: {0}",
                            RegistryHelper.JoinKeyNames(key,
                                "Menus"));

                        return false;
                    }

                    RegistryHelper.DeleteValue(
                        subKey, package.PackageId.ToString(VsIdFormat),
                        throwOnMissing, whatIf, verbose);
                }

                using (MockRegistryKey subKey = RegistryHelper.OpenSubKey(
                        key, "Services", true, whatIf, verbose))
                {
                    if (subKey == null)
                    {
                        error = String.Format(
                            "could not open registry key: {0}\\Services",
                            key);
                            "could not open registry key: {0}",
                            RegistryHelper.JoinKeyNames(key,
                                "Services"));

                        return false;
                    }

                    RegistryHelper.DeleteSubKeyTree(
                        subKey, package.ServiceId.ToString(VsIdFormat),
                        whatIf, verbose);
7332
7333
7334
7335
7336
7337
7338

7339
7340
7341

7342
7343
7344
7345
7346
7347
7348
7349
7350

7351
7352
7353
7354

7355
7356
7357
7358
7359
7360
7361
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700







+



+









+




+







            process.OutputDataReceived += new DataReceivedEventHandler(
                VsDevEnvSetupOutputDataReceived);

            process.ErrorDataReceived += new DataReceivedEventHandler(
                VsDevEnvSetupErrorDataReceived);

            if (verbose)
            {
                TraceOps.DebugAndTrace(TracePriority.Highest,
                    debugCallback, traceCallback, ForDisplay(startInfo),
                    traceCategory);
            }

            //
            // NOTE: In "what-if" mode, do not actually start the process.
            //
            if (!whatIf)
            {
                process.Start();

                if (verbose)
                {
                    TraceOps.DebugAndTrace(TracePriority.Highest,
                        debugCallback, traceCallback, String.Format(
                        "process = {0}", ForDisplay(process)),
                        traceCategory);
                }

                process.BeginOutputReadLine();
                process.BeginErrorReadLine();
                process.WaitForExit();
            }

            return true;
7379
7380
7381
7382
7383
7384
7385

7386
7387
7388
7389
7390

7391
7392
7393
7394
7395
7396
7397
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738







+





+







            //       This should force it to refresh its list of installed
            //       packages and their associated resources (i.e. this will
            //       effectively 'remove' the package being processed since
            //       this is being done after all the other changes for the
            //       package removal have been completed).
            //
            if (verbose)
            {
                TraceOps.DebugAndTrace(TracePriority.Highest,
                    debugCallback, traceCallback, String.Format(
                    "Preparing to run Visual Studio {0} 'setup' mode to " +
                    "refresh its configuration.", ForDisplay(vsVersion)),
                    traceCategory);
            }

            return AddVsDevEnvSetup(
                vsVersion, directory, perUser, whatIf, verbose, ref error);
        }

        ///////////////////////////////////////////////////////////////////////