RegPkg.cs :  » Development » StyleCop » Microsoft » VisualStudio » Tools » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Development » StyleCop 
StyleCop » Microsoft » VisualStudio » Tools » RegPkg.cs
/***************************************************************************

Copyright (c) Microsoft Corporation. All rights reserved.
This code is licensed under the Visual Studio SDK license terms.
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.

***************************************************************************/
[module: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", Scope = "resource", Target = "Microsoft.VisualStudio.Tools.Resources.resources")]

namespace Microsoft.VisualStudio.Tools{

    using Microsoft.VisualStudio.Shell;
    using Microsoft.VisualStudio.Shell.Interop;
    using Microsoft.Win32;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.Design.Serialization;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.IO;
    using System.Reflection;
    using System.Text;

    /// <include file='doc\RegPkg.uex' path='docs/doc[@for="RegPkg"]/*' />
    /// <devdoc>
    /// Registers a Visual Studio package.
    /// </devdoc>
    [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Pkg")]
    public static class RegPkg {

        public enum RegistrationMode {
            None = 0x0,
            Register = 0x1,
            [SuppressMessage("Microsoft.Naming", "CA1705:LongAcronymsShouldBePascalCased")]
            VRG = 0x2,
            [SuppressMessage("Microsoft.Naming", "CA1705:LongAcronymsShouldBePascalCased")]
            REG = 0x3,
            [SuppressMessage("Microsoft.Naming", "CA1705:LongAcronymsShouldBePascalCased")]
            RGS = 0x4,
            [SuppressMessage("Microsoft.Naming", "CA1705:LongAcronymsShouldBePascalCased")]
            [SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores")]
            RGS_RGM = 0x5,
            [SuppressMessage("Microsoft.Naming", "CA1705:LongAcronymsShouldBePascalCased")]
            WIX = 0x6,
            Unregister = 0x7,
            [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
            PkgDef = 0x8
        };

        private static string RegistrationNameFromMode(RegistrationMode mode) {
            string modeName = null;
            switch (mode) {
                case RegistrationMode.None:
                case RegistrationMode.Register:
                    modeName = string.Empty;
                    break;

                case RegistrationMode.VRG:
                    modeName = "vrgfile";
                    break;

                case RegistrationMode.REG:
                    modeName = "regfile";
                    break;

                case RegistrationMode.RGS:
                case RegistrationMode.RGS_RGM:
                    modeName = "rgsfile";
                    break;

                case RegistrationMode.WIX:
                    modeName = "wixfile";
                    break;

                case RegistrationMode.PkgDef:
                    modeName = "pkgdeffile";
                    break;

                default:
                    throw new ArgumentException(Resources.UnknownMode);
            }

            return modeName;
        }

        [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
        [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes")]
        public struct ParseResult {
            [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
            public RegistrationMode mode;
            [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
            public string fileName;
            [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
            public string outputFile;
            [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
            public string registryRoot;
            [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
            public RegistrationMethod registrationMethod;
            [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
            public bool isRANU;
        }

        private static bool consoleMode;
        private static string outFile;


        /// <include file='doc\RegPkg.uex' path='docs/doc[@for="RegPkg.CreateReg"]/*' />
        /// <devdoc>
        /// Creates regfile format data for the given file name.
        /// </devdoc>
        public static string CreateReg(ParseResult args) {
            if (string.IsNullOrEmpty(args.fileName)) {
                throw new ArgumentNullException("fileName");
            }

            // Calcuate the registry root
            //
            RegistryRoot regRoot = new RegistryRoot(args.fileName, args.registryRoot, args.isRANU);

            RegFileHive hive = new RegFileHive(regRoot);
            using (RegPkgContext cxt = new RegPkgContext(hive, args.registrationMethod)) {
                ProcessAssembly(args.fileName, hive, cxt, true, RegistrationMode.REG);
                return hive.ToString();
            }
        }

        /// <include file='doc\RegPkg.uex' path='docs/doc[@for="RegPkg.CreatePkgDef"]/*' />
        /// <devdoc>
        /// Creates pkgdef format data for the given file name.
        /// </devdoc>
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
        public static string CreatePkgDef(ParseResult args) {
            if (string.IsNullOrEmpty(args.fileName)) {
                throw new ArgumentNullException("fileName");
            }

            PkgDefFileHive hive = new PkgDefFileHive();
            using (RegPkgContext cxt = new RegPkgContext(hive, args.registrationMethod)) {
                ProcessAssembly(args.fileName, hive, cxt, true, RegistrationMode.PkgDef);
                return hive.ToString();
            }
        }

        /// <include file='doc\RegPkg.uex' path='docs/doc[@for="RegPkg.CreateRgs"]/*' />
        /// <devdoc>
        /// Creates rgsfile format data for the given file name.
        /// </devdoc>
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Rgs")]
        public static string[] CreateRgs(ParseResult args) {
            if (string.IsNullOrEmpty(args.fileName)) {
                throw new ArgumentNullException("fileName");
            }

            // Calcuate the registry root
            //
            RegistryRoot regRoot = new RegistryRoot(args.fileName, args.registryRoot, args.isRANU);

            bool createRgm = (RegistrationMode.RGS_RGM == args.mode);
            RgsFileHive hive = new RgsFileHive(regRoot, createRgm);
            using (RegPkgContext cxt = new RegPkgContext(hive, args.registrationMethod)) {
                ProcessAssembly(args.fileName, hive, cxt, true, RegistrationMode.RGS);
                return hive.GetStrings();
            }
        }

        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Wix")]
        public static string CreateWix(ParseResult args) {
            if (string.IsNullOrEmpty(args.fileName)) {
                throw new ArgumentNullException("fileName");
            }

            // Create the RegistryRoot object.
            RegistryRoot regRoot = new RegistryRoot(args.fileName, args.registryRoot, args.isRANU);

            WixRegHive hive = new WixRegHive(regRoot, args.fileName);
            using (RegPkgContext cxt = new RegPkgContext(hive, args.registrationMethod)) {
                ProcessAssembly(args.fileName, hive, cxt, true, RegistrationMode.WIX);
                return hive.ToString();
            }
        }

        /// <include file='doc\RegPkg.uex' path='docs/doc[@for="RegPkg.CreateVrg"]/*' />
        /// <devdoc>
        /// Creates vrgfile format data for the given file name.
        /// </devdoc>
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Vrg")]
        public static string CreateVrg(ParseResult args) {
            if (string.IsNullOrEmpty(args.fileName)) {
                throw new ArgumentNullException("fileName");
            }

            // Calcuate the registry root
            //
            RegistryRoot regRoot = new RegistryRoot(args.fileName, args.registryRoot, args.isRANU);

            RegFileHive hive = new VrgFileHive(regRoot);
            using (RegPkgContext cxt = new RegPkgContext(hive, args.registrationMethod)) {
                ProcessAssembly(args.fileName, hive, cxt, true, RegistrationMode.VRG);
                return hive.ToString();
            }
        }

        /// <devdoc>
        ///     This method looks for the MsiTokenAttribute with the given name,
        ///     and if it finds it, returns the value.  If it doesn't find it
        ///     it will return "name", which is the default value of the token.
        /// </devdoc>
        private static string GetTokenValue(Type componentType, string name) {
            object[] attrs = componentType.GetCustomAttributes(typeof(MsiTokenAttribute), true);
            foreach(MsiTokenAttribute attr in attrs) {
                if (attr.Name.Equals(name)) {
                    return attr.Value;
                }
            }
            return name;
        }

        /// <devdoc>
        ///     Helper routine.  Returns "true" if value matches arg.
        ///     Does some smart checking based on arguments that can
        ///     have colons.
        /// </devdoc>
        private static bool IsArg(string value, string arg, bool supportColon) {
            // if "arg" has a : in it, parse that off.
            //
            if (supportColon) {
                int index = value.IndexOf(':');
                if (index != -1) {
                    value = value.Substring(0, index);
                }
            }
            return string.Compare(value, arg, StringComparison.OrdinalIgnoreCase) == 0;
        }

        /// <devdoc>
        ///     Main entry point.  Usage:
        ///
        ///     regpkg [/root:<root>] [/regfile:<regfile>] [/rgsfile:<rgsfile> [/rgm]] [/vrgfile:<vrgfile>] [/codebase | /assembly] [/unregister] AssemblyPath
        ///
        ///     Option                  Description
        ///     ------------------------------------
        ///     /root:root              The Visual Studio root to apply the registration to.  If no
        ///                             root is specified the root will be taken from the
        ///                             DefaultRegistryRootAttribute on the packages in the assembly.
        ///                             If there is more than one root listed, this is an error and
        ///                             registration will terminate. If the /pkgdef switch is used,
        ///                             then this value is ignored.
        ///     /regfile:regfile        Instead of making changes to the registry, this option will
        ///                             route changes to the provided registry file.  Cannot be used
        ///                             in conjunction with /vrgfile or /rgsfile.
        ///     /rgsfile:rgsfile        Instead of making changes to the registry, this option will
        ///                             route changes to the provided registry file.  Cannot be used
        ///                             in conjunction with /vrgfile or /regfile.
        ///     /rgm                    Only valid when used in conjunction with /rgsfile, this option
        ///                             will generate a corresponding rgm merge file.
        ///     /vrgfile:vrgfile        Instead of making changes to the registry, this option will
        ///                             create a MSI compliant vrg file.  Cannot be used in
        ///                             conjunction with /root or /regfile or /rgsfile
        ///     /wixfile:WixFile        Creates a registration script compatible with Wix's XML format.
        /// 
        ///     /codebase | /assembly   Registers objects with the CodeBase specification in the registry
        ///                             if /codebase is specified.  Registers objects with the Assembly
        ///                             specification in the registry.  Overrides the default setting of 
        ///                             the package and its objects.
        ///     /RANU                   Register the package inside the user's specific registry hive.
        ///                             This parameter can be used to develop the package with an user
        ///                             account that is not a machine's administrator.
        ///     /unregister             Removes the registration information from the registry.  
        ///                             Cannot be used with /regfile or /vrgfile
        ///     AssemblyPath            The path to the file name to register.
        ///
        /// </devdoc>
        private static int Main(string[] arguments) {

            consoleMode = true;

            try {
                ParseResult parseResult = ParseArgs(arguments);
                outFile = parseResult.outputFile;
                switch(parseResult.mode) {
                    case RegistrationMode.Register:
                        Register(parseResult);
                        break;
                    case RegistrationMode.VRG:
                        WriteFile(CreateVrg(parseResult), outFile);
                        break;
                    case RegistrationMode.REG:
                        WriteFile(CreateReg(parseResult), outFile);
                        break;
                    case RegistrationMode.PkgDef:
                        WriteFile(CreatePkgDef(parseResult), outFile);
                        break;
                    case RegistrationMode.RGS:
                        WriteFile(CreateRgs(parseResult)[0], outFile);
                        break;
                    case RegistrationMode.RGS_RGM:
                        string[] files = CreateRgs(parseResult);
                        WriteFile(files[0], outFile);
                        WriteFile(files[1], Path.ChangeExtension(outFile, ".rgm"));
                        break;
                    case RegistrationMode.WIX:
                        WriteFile(CreateWix(parseResult), outFile);
                        break;
                    case RegistrationMode.Unregister:
                        Unregister(parseResult);
                        break;
                    default:
                        WriteLine(Resources.RegPkg_Usage);
                        break;
                }
            }
            catch (Exception e) {
                ReflectionTypeLoadException typeLoadException = e as ReflectionTypeLoadException;
                if (null != typeLoadException) {
                    Console.Error.WriteLine(string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_Error, typeLoadException.Message));
                    foreach(Exception exLoader in typeLoadException.LoaderExceptions) {
                        Console.Error.WriteLine(exLoader.Message);
                    }
                }
                else {
                    while (e != null) {
                        if (e.Message != null && e.Message.Length > 0) {
                            Console.Error.WriteLine(string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_Error, e.Message));
                        }
                        e = e.InnerException;
                    }
                }
                return 1;
            }
            return 0;
        }

        /// <devdoc>
        ///     Parses arguments.  Throws an exception if there is an error in argument parsing.
        ///     Returns a MODE constant to register in a partiulcar mode, or 0 to do nothing.
        /// </devdoc>
        [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
        private static ParseResult ParseArgs(string[] arguments) {

            ParseResult result;
            result.mode = 0;
            bool createRgm = false;
            result.registryRoot = null;
            result.outputFile = null;
            result.fileName = null;
            result.isRANU = false;

            result.registrationMethod = RegistrationMethod.Default;

            for (int i = 0; i < arguments.Length; i++) {
                string arg = arguments[i];
                if (string.IsNullOrEmpty(arg)) {
                    continue;
                }
                arg = arg.Trim();
                if (string.IsNullOrEmpty(arg)) {
                    continue;
                }
                if (arg[0] == '/' || arg[0] == '-') {
                    arg = arg.Substring(1);
                }
                else {
                    if (result.fileName != null) {
                        throw new ArgumentException(Resources.RegPkg_MultipleFiles);
                    }
                    result.fileName = arg;
                    if (!File.Exists(result.fileName)) {
                        throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_FileNotExist, result.fileName));
                    }
                    continue;
                }

                if (IsArg(arg, "unregister", false)) {
                    ValidateMode(result.mode, RegistrationMode.Unregister);
                    result.mode = RegistrationMode.Unregister;
                }
                else if (IsArg(arg, "regfile", true)) {
                    ValidateMode(result.mode, RegistrationMode.REG);
                    result.mode = RegistrationMode.REG;
                    result.outputFile = ParseSubArg(arg);
                }
                else if (IsArg(arg, "pkgdeffile", true)) {
                  ValidateMode(result.mode, RegistrationMode.PkgDef);
                  result.mode = RegistrationMode.PkgDef;
                  result.outputFile = ParseSubArg(arg);
                }
                else if (IsArg(arg, "rgsfile", true)) {
                    ValidateMode(result.mode, RegistrationMode.RGS);
                    result.mode = RegistrationMode.RGS;
                    result.outputFile = ParseSubArg(arg);
                }
                else if (IsArg(arg, "vrgfile", true)) {
                    ValidateMode(result.mode, RegistrationMode.VRG);
                    result.mode = RegistrationMode.VRG;
                    result.outputFile = ParseSubArg(arg);
                }
                else if (IsArg(arg, "wixfile", true)) {
                    ValidateMode(result.mode, RegistrationMode.WIX);
                    result.mode = RegistrationMode.WIX;
                    result.outputFile = ParseSubArg(arg);
                }
                else if (IsArg(arg, "codebase", true)) {
                    if (result.registrationMethod != RegistrationMethod.Default)
                        throw new ArgumentException(Resources.RegPkg_MultipleRegistrationMethods);
                    result.registrationMethod = RegistrationMethod.CodeBase;
                }
                else if (IsArg(arg, "assembly", true)) {
                    if (result.registrationMethod != RegistrationMethod.Default)
                        throw new ArgumentException(Resources.RegPkg_MultipleRegistrationMethods);
                    result.registrationMethod = RegistrationMethod.Assembly;
                }

                else if (IsArg(arg, "root", true)) {
                    if (result.registryRoot != null) {
                        throw new ArgumentException(Resources.RegPkg_MultipleRoots);
                    }
                    result.registryRoot = ParseSubArg(arg);
                }
                else if (IsArg(arg, "rgm", false)) {
                    createRgm = true;
                }
                else if (IsArg(arg, "ranu", false)) {
                    result.isRANU = true;
                }
                else if (IsArg(arg, "?", false) || IsArg(arg, "help", false)) {
                    // abort the parse loop.  Returning a zero mode
                    // will cause main to print the usage.
                    result.mode = RegistrationMode.None;
                    return result;
                }
                else {
                    throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_InvalidParameter, arg));
                }
            }

            if (result.mode == 0 && result.fileName != null) {
                result.mode = RegistrationMode.Register;
            }

            if (createRgm) {
                if (result.mode != RegistrationMode.RGS) {
                    throw new ArgumentException(Resources.RegPkg_RgmNeedsRgs);
                }
                else {
                    result.mode = RegistrationMode.RGS_RGM;
                }
            }

            if (result.mode != 0 && result.fileName == null) {
                throw new ArgumentException(Resources.RegPkg_NoFileSpecified);
            }

            return result;
        }

        /// <devdoc>
        ///     Parses a sub argument.  Sub arguments are arguments that
        ///     come after a ":" in an argument.
        /// </devdoc>
        private static string ParseSubArg(string arg) {
            // First, check if anything lives after the : in arg
            int index = arg.IndexOf(':');
            if (index == -1) {
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_MalformedArg, arg));
            }

            string subArg = null;

            index++;
            if (index < arg.Length) {
                subArg = arg.Substring(index).Trim();
            }

            if (string.IsNullOrEmpty(subArg)) {
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_MissingSubarg, arg));
            }

            return subArg;
        }

        /// <devdoc>
        ///     This is the core registration routine.  It takes in a file and
        ///     a Hive object and creates the assembly information on the hive.
        /// </devdoc>
        [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom")]
        public static void ProcessAssembly(string fileName, Hive hive, RegPkgContext context, bool register, RegistrationMode mode) {

            // Open the assembly and grock its data.  For each interesting type
            // we need to set it into our context.
            //
            Assembly a = Assembly.LoadFrom(fileName);
            AssemblyName name = a.GetName();

            string regText = null;
            string rootText = string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_NotifyRoot, hive.Root);

            switch (mode)
            {
                case RegistrationMode.Register:
                    regText = string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_NotifyFileRegistering, name.Name, name.Version);
                    break;

                case RegistrationMode.VRG:
                    regText = string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_NotifyFileCreatingVRG, name.Name, name.Version, outFile);
                    break;

                case RegistrationMode.REG:
                    regText = string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_NotifyFileCreatingREG, name.Name, name.Version, outFile);
                    break;

                case RegistrationMode.PkgDef:
                    regText = string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_NotifyFileCreatingPkgDef, name.Name, name.Version, outFile);
                    break;

                case RegistrationMode.RGS:
                case RegistrationMode.RGS_RGM:
                    regText = string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_NotifyFileCreatingRGS, name.Name, name.Version, outFile);
                    break;

                case RegistrationMode.WIX:
                    regText = string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_NotifyFileCreatingWIX, name.Name, name.Version, outFile);
                    break;

                case RegistrationMode.Unregister:
                    regText = string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_NotifyFileUnregistering, name.Name, name.Version);
                    break;

                default:
                    throw new ArgumentException();
            }

            int maxText = rootText.Length;
            if (regText.Length > maxText)
            {
                maxText = regText.Length;
            }

            string b = new string('-', maxText);

            WriteLine(regText);
            WriteLine(rootText);
            WriteLine(b);

            // We need to sort types and attributes so that our output
            // is consistent.
            SortedList<Type,ArrayList> registrationTypes = new SortedList<Type, ArrayList>(TypeComparer.Default);

            foreach(Type t in a.GetTypes()) {

                // Seach the custom attributes of this type for something that
                // derives from RegistrationAttribute.  If we find it, register
                // it.
                //
                if (!t.IsAbstract) {
                    foreach (object attr in t.GetCustomAttributes(true)) {
                        if (attr is RegistrationAttribute) {
                            ArrayList list;
                            if (!registrationTypes.TryGetValue(t, out list)) {
                                list = new ArrayList();
                                registrationTypes.Add(t, list);
                            }

                            list.Add(attr);
                        }
                    }
                }
            }

            // Check if there is something to register. If no registration
            // attribute is provided, then raise an exception to notify the
            // user that nothing will happen.
            if (registrationTypes.Count == 0) {
                throw new ArgumentException(Resources.RegPkg_NoRegistrationData);
            }

            foreach(KeyValuePair<Type, ArrayList> kv in registrationTypes) {

                bool setType = false;
                kv.Value.Sort(RegistrationAttributeComparer.Default);

                foreach (RegistrationAttribute regAttr in kv.Value) {
                    // Setup the data in our context for this type.
                    //
                    if (!setType) {
                        setType = true;
                        context.SetType(kv.Key);
                    }

                    if (register)
                    {
                        regAttr.Register(context);
                    }
                    else
                    {
                        regAttr.Unregister(context);
                    }
                }
            }

            WriteLine(string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_Success, name.Name));
        }

        /// <include file='doc\RegPkg.uex' path='docs/doc[@for="RegPkg.Register"]/*' />
        /// <devdoc>
        /// Public API that registers the given filename under the given root.  If
        /// no root is specified this uses the default root for the assembly.
        /// </devdoc>
        public static void Register(ParseResult args) {
            if (string.IsNullOrEmpty(args.fileName)) {
                throw new ArgumentNullException("fileName");
            }

            // Calcuate the registry root
            //
            RegistryRoot regRoot = new RegistryRoot(args.fileName, args.registryRoot, args.isRANU);

            RegHive hive = new RegHive(regRoot);
            using (RegPkgContext cxt = new RegPkgContext(hive, args.registrationMethod)) {
                ProcessAssembly(args.fileName, hive, cxt, true, RegistrationMode.Register);
                hive.Close();
            }
        }

        /// <include file='doc\RegPkg.uex' path='docs/doc[@for="RegPkg.Unregister"]/*' />
        /// <devdoc>
        /// Public API that unregisters the given file name for the given root.  If
        /// no root is specified this uses the default root for the assembly.
        /// </devdoc>
        public static void Unregister(ParseResult args) {
            if (string.IsNullOrEmpty(args.fileName)) {
                throw new ArgumentNullException("fileName");
            }

            // Calcuate the registry root
            //
            RegistryRoot regRoot = new RegistryRoot(args.fileName, args.registryRoot, args.isRANU);

            RegHive hive = new RegHive(regRoot);
            using (RegPkgContext cxt = new RegPkgContext(hive, args.registrationMethod)) {
                ProcessAssembly(args.fileName, hive, cxt, false, RegistrationMode.Unregister);
                hive.Close();
            }
        }

        /// <devdoc>
        ///     Validates that the new mode is compatible with the current mode.
        /// </devdoc>
        private static void ValidateMode(RegistrationMode currentMode, RegistrationMode mode) {
            if (currentMode != RegistrationMode.None) {
                string errMessage = string.Empty;
                if (currentMode == mode) {
                    errMessage = string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_DuplicatedMode, RegistrationNameFromMode(mode));
                } else {
                    errMessage = string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_MultipleMode, RegistrationNameFromMode(currentMode), RegistrationNameFromMode(mode));
                }
                throw new ArgumentException(errMessage);
            }
        }

        /// <devdoc>
        ///     Takes a string of data and writes it to a file.
        /// </devdoc>
        private static void WriteFile(string data, string fileName) {
            using (FileStream fs = new FileStream(fileName, FileMode.Create))
            {
                using (TextWriter writer = new StreamWriter(fs))
                {
                    writer.Write(data);
                    writer.Flush();
                }
            }
        }

        /// <devdoc>
        ///     Console wrapper that outputs to the console, but only if
        ///     we were invoked through Main.
        /// </devdoc>
        private static void WriteLine(string line) {
            if (consoleMode) {
                Console.WriteLine(line);
            }
            // Always output the string to the debugger
            Debug.WriteLine(line);

        }

        /// <devdoc>
        ///     Compares registration attributes to sort them.
        /// </devdoc>
        private sealed class RegistrationAttributeComparer : IComparer {
            public static RegistrationAttributeComparer Default = new RegistrationAttributeComparer();

            public int Compare(object a, object b) {
                RegistrationAttribute ra = (RegistrationAttribute)a;
                RegistrationAttribute rb = (RegistrationAttribute)b;

                int result = string.Compare(ra.GetType().FullName, rb.GetType().FullName, StringComparison.Ordinal);
                if (result == 0 && ra.GetType() == rb.GetType()) {
                    foreach(PropertyDescriptor prop in TypeDescriptor.GetProperties(ra.GetType())) {
                        if (typeof(IComparable).IsAssignableFrom(prop.PropertyType)) {
                            IComparable valueA = prop.GetValue(ra) as IComparable;
                            IComparable valueB = prop.GetValue(rb) as IComparable;
                            if (valueA != null && valueB != null) {
                                result = valueA.CompareTo(valueB);
                                if (result != 0) {
                                    break;
                                }
                            }

                        }
                        else if (prop.PropertyType == typeof(Type)) {
                            Type valueA = prop.GetValue(ra) as Type;
                            Type valueB = prop.GetValue(rb) as Type;
                            if (valueA != null && valueB != null) {
                                result = string.Compare(valueA.FullName, valueB.FullName, StringComparison.Ordinal);
                                if (result != 0) {
                                    break;
                                }
                            }
                        }
                        else {
                            object valueA = prop.GetValue(ra);
                            object valueB = prop.GetValue(rb);
                            if (valueA != null && valueB != null) {
                                result = string.Compare(valueA.ToString(), valueB.ToString(), StringComparison.Ordinal);
                                if (result != 0) {
                                    break;
                                }
                            }
                        }
                    }

                }

                return result;
            }
        }

        /// <devdoc>
        ///     Compares types to sort them.
        /// </devdoc>
        private sealed class TypeComparer : IComparer<Type> {
            public static TypeComparer Default = new TypeComparer();
            public int Compare(Type x, Type y) {
                if (null == x) {
                    return (null == y) ? 0 : -1;
                }
                if (null == y) {
                    return 1;
                }
                return string.Compare(x.FullName, y.FullName, StringComparison.Ordinal);
            }

            [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
            [SuppressMessage("Microsoft.Performance", "CA1822:MarkMethodsAsStatic")]
            public bool Equals(Type x, Type y) {
                return x == y;
            }

            [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
            [SuppressMessage("Microsoft.Performance", "CA1822:MarkMethodsAsStatic")]
            public int GetHashCode(Type obj) {
                return obj.GetHashCode();
            }

        }

        /// <devdoc>
        ///     Hive object that is used to produce .PkgDef file data.
        /// </devdoc>
        private class PkgDefFileHive : Hive
        {
          //The regroot is not needed in this class, because it is always generated as $RootKey$,
          //  therefore we can do some optimizations to work around this.

          private StringBuilder builder;
          private ArrayList children = new ArrayList();

          public PkgDefFileHive()
          {
            builder = new StringBuilder();
          }

          public override string Root
          {
            get
            {
              return "$RootKey$";
            }
          }

          public override string RootFolder
          {
              get
              {
                  return "$RootFolder$";
              }
          }

          protected virtual void AddHeader(StringBuilder b)
          {
            b.Append("Windows Registry Editor Version 5.00\r\n\r\n");
          }

          public override RegistrationAttribute.Key CreateKey(string name)
          {
            RegFileKey key = new RegFileKey(string.Format(CultureInfo.InvariantCulture, "{0}\\{1}", Root, name));
            children.Add(key);
            return key;
          }

          public override void RemoveKey(string name)
          {
            return;
          }

          public override void RemoveKeyIfEmpty(string name)
          {
            return;
          }

          public override void RemoveValue(string name, string valuename)
          {
            return;
          }

          public override string GetComponentPath(Type componentType)
          {
            return EscapePath(base.GetComponentPath(componentType));
          }

          public override string GetCodeBase(Type componentType)
          {
            return EscapePath(base.GetCodeBase(componentType));
          }

          public override string GetInprocServerPath(Type componentType)
          {
            string toReturn = base.GetInprocServerPath(componentType);
            string osPath = System.Environment.GetFolderPath(Environment.SpecialFolder.System);
            osPath = System.IO.Path.GetDirectoryName(osPath);
            toReturn = ReplaceInsensitive(toReturn, osPath, @"%windir%");
            return EscapePath(toReturn);
          }

          public override string ToString()
          {
            AddHeader(builder);
            foreach (RegFileKey key in children)
            {
              builder.Append(key.ToString());
            }
            children.Clear();
            builder.Append("\r\n");
            return builder.ToString();
          }

          static string ReplaceInsensitive(string input, string oldValue, string newValue) {
            int index = input.IndexOf(oldValue, StringComparison.CurrentCultureIgnoreCase);
            if (index != -1) {
              string s1 = input.Substring(0, index);
              string s2 = input.Substring(index + oldValue.Length);
              return s1 + newValue + s2;
            } 
            else {
              return input;
            }
          }
        }

        /// <devdoc>
        ///     Hive object that is used to produce .REG file data.
        /// </devdoc>
        private class RegFileHive : Hive {

            private readonly string root;
            private StringBuilder builder;
            private ArrayList children = new ArrayList();

            public RegFileHive(RegistryRoot regRoot) {
                builder = new StringBuilder();
                string regKey = regRoot.IsRANU ? "HKEY_CURRENT_USER" : "HKEY_LOCAL_MACHINE";
                root = string.Format(CultureInfo.InvariantCulture, @"{0}\{1}", regKey, regRoot.RegistryRootPath);
            }

            public override string Root
            {
                get
                {
                    return root;
                }
            }

            protected virtual void AddHeader(StringBuilder b) {
                b.Append("REGEDIT4\r\n\r\n");
            }

            public override RegistrationAttribute.Key CreateKey(string name) {
                RegFileKey key = new RegFileKey(string.Format(CultureInfo.InvariantCulture, "{0}\\{1}", root, name));
                children.Add(key);
                return key;
            }

            public override void RemoveKey(string name)
            {
                return;
            }

            public override void RemoveKeyIfEmpty(string name)
            {
                return;
            }

            public override void RemoveValue(string name, string valuename)
            {
                return;
            }

            public override string GetComponentPath(Type componentType) {
                return EscapePath(base.GetComponentPath(componentType));
            }

            public override string GetCodeBase(Type componentType) {
                return EscapePath(base.GetCodeBase(componentType));
            }

            public override string GetInprocServerPath(Type componentType) {
                return EscapePath(base.GetInprocServerPath(componentType));
            }

            public override string RootFolder
            {
                get
                {
                    return Registry.GetValue(root + "\\Setup\\VS", "ProductDir", "$RootFolder$").ToString();
                }
            }

            public override string ToString() {
                AddHeader(builder);
                foreach(RegFileKey key in children) {
                    builder.Append(key.ToString());
                }
                children.Clear();
                builder.Append("\r\n");
                return builder.ToString();
            }
        }

        /// <devdoc>
        ///     Key object that is used to produce .REG file data.
        /// </devdoc>
        private sealed class RegFileKey : RegistrationKeyBase {

            public RegFileKey(string path) : base(path) {
            }

            public override void Close() {
            }

            protected override RegistrationKeyBase CreateKey(string keyPath) {
                return new RegFileKey(keyPath);
            }

            public override string CreateRegistrationScript(int marginSize) {
                StringBuilder builder = new StringBuilder();

                // Add the name of the key
                builder.Append("[");
                builder.Append(this.Path);
                builder.AppendLine("]");

                // Add the default value if it is not null
                if (null != this.DefaultValue) {
                    builder.Append("@=");
                    builder.AppendLine(FormatValue(this.DefaultValue));
                }

                // Add the other labels
                foreach (string label in Values.Keys) {
                    if (null == Values[label]) {
                        continue;
                    }
                    builder.Append("\"");
                    builder.Append(Utilities.DoubleBackSlash(label));
                    builder.Append("\"=");
                    builder.AppendLine(FormatValue(Values[label]));
                }

                // Add the sub-keys
                foreach (RegistrationKeyBase key in SubKeys.Values) {
                    builder.Append(key.CreateRegistrationScript(marginSize));
                }

                return builder.ToString();
            }

            private static string FormatValue(object value) {
                if (value.GetType().IsPrimitive) {
                    return string.Format(CultureInfo.InvariantCulture, "dword:{0:X8}", value);
                }
                return string.Format(CultureInfo.InvariantCulture, "\"{0}\"", Utilities.DoubleBackSlash(value.ToString()));
            }

            public override string ToString() {
                return CreateRegistrationScript(0);
            }

        }

        /// <devdoc>
        ///     Hive object that is used to directly write to the registry
        /// </devdoc>
        private sealed class RegHive : Hive {

            private RegistryKey root;
            private RegistryRoot regRoot;

            public RegHive(RegistryRoot regRoot) {
                this.regRoot = regRoot;
                if (regRoot.IsRANU) {
                    root = Registry.CurrentUser.CreateSubKey(regRoot.RegistryRootPath);
                } else {
                    root = Registry.LocalMachine.CreateSubKey(regRoot.RegistryRootPath);
                }
            }

            public override string Root
            {
                get
                {
                    return regRoot.RegistryRootPath;
                }
            }

            public override string RootFolder
            {
                get
                {
                    string value;
                    using (RegistryKey key = root.OpenSubKey("Setup\\VS"))
                    {
                        value = key.GetValue("ProductDir", "$RootFolder$").ToString();
                    }
                    return value;
                }
            }

            public void Close() {
                root.Close();
            }

            public override RegistrationAttribute.Key CreateKey(string name) {
                return new RegKey(root.CreateSubKey(name));
            }

            public override void RemoveKey(string name)
            {
                using (RegistryKey sub = root.OpenSubKey(name))
                {
                    if (sub != null)
                    {
                        root.DeleteSubKeyTree(name);
                    }
                }
            }

            public override void RemoveKeyIfEmpty(string name)
            {
                using (RegistryKey sub = root.OpenSubKey(name))
                {
                    if (sub == null)
                        return; // already deleted, nothing to do

                    if (sub.GetSubKeyNames().Length == 0
                        && sub.GetValueNames().Length == 0)
                    {
                        root.DeleteSubKey(name);
                    }
                }
            }

            public override void RemoveValue(string name, string valuename)
            {
                using (RegistryKey key = root.OpenSubKey(name, true))
                {
                    if (null != key)
                    {
                        key.DeleteValue(valuename, false);
                    }
                }
            }
        }

        /// <devdoc>
        ///     Key object that is used to write to the registry.
        /// </devdoc>
        private sealed class RegKey : RegistrationAttribute.Key {

            private RegistryKey key;

            internal RegKey(RegistryKey key) {
                if (key == null)
                    throw new ArgumentNullException("key");
                this.key = key;
            }

            public override void Close() {
                key.Close();
            }

            public override RegistrationAttribute.Key CreateSubkey(string name) {
                return new RegKey(key.CreateSubKey(name));
            }

            public override void SetValue(string valueName, object value) {

                // short is interpreted as a stringf by RegistryKey.
                //
                if (value is short) {
                    value = (int)(short)value;
                }
                key.SetValue(valueName, value);
            }
        }

        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Pkg")]
        [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
        public sealed class RegPkgContext : RegistrationAttribute.RegistrationContext, IDisposable {

            private Hive hive;
            private Type componentType;
            private RegistrationMethod registrationMethod;

            private TextWriter log;

            public RegPkgContext(Hive hive, RegistrationMethod registerUsing) {
                this.hive = hive;
                this.registrationMethod = registerUsing;
            }

            public void Dispose() {
                if (null != log) {
                    log.Dispose();
                    log = null;
                }
            }

            public override string ComponentPath {
                get {
                    return hive.GetComponentPath(ComponentType);
                }
            }

            public override Type ComponentType {
                get {
                    return componentType;
                }
            }

            public override string InprocServerPath {
                get {
                    return hive.GetInprocServerPath(ComponentType);
                }
            }

            public override string CodeBase {
                get {
                    return hive.GetCodeBase(ComponentType);
                }
            }

            /// <summary>
            /// The path to the directory where the target host executable is.
            /// </summary>
            public override string RootFolder{
                get {
                    return hive.RootFolder;
                }
            }

            public override RegistrationMethod RegistrationMethod {
                get {
                    return registrationMethod;
                }
            }

            public override TextWriter Log {
                get {
                    if (log == null) {
                        if (consoleMode) {
                            log = Console.Out;
                        }
                        else {
                            log = new StringWriter(CultureInfo.CurrentUICulture);
                        }
                    }

                    return log;
                }
            }

            public override RegistrationAttribute.Key CreateKey(string name) {
                return hive.CreateKey(name);
            }

            public override void RemoveKey(string name) {
                hive.RemoveKey(name);
            }

            public override void RemoveKeyIfEmpty(string name) {
                hive.RemoveKeyIfEmpty(name);
            }

            public override void RemoveValue(string keyname, string valuename) {
                hive.RemoveValue(keyname, valuename);
            }


            /// <devdoc>
            /// Escape the string if needed.
            /// Its implementation is empty because we want to move to the specific escaping
            /// to the registration key because this this the object with more context about
            /// the format of strings.
            /// </devdoc>
            public override string EscapePath(string str) {
                return str;
            }

            internal void SetType(Type t) {
                componentType = t;
            }
        }

        /// <devdoc>
        ///     Hive object that is used to produce .RGS file data.
        /// </devdoc>
        private class RgsFileHive : Hive {

            private RegistryRoot                  root;
            private Hashtable                     rgmHash;
            private ArrayList                     rgmKeys;
            private RgsFileKey                    rootKey;
            private RegistrationAttribute.Key     createKey;

            public RgsFileHive(RegistryRoot regRoot, bool createRgm) {
                root = regRoot;

                if (createRgm) {
                    rgmHash = new Hashtable();
                    rgmKeys = new ArrayList();
                }

                if (createRgm) {
                    rootKey = new RgsFileKey(root.IsRANU);
                    createKey = rootKey.CreateRegRootKey(regRoot.RegistryRootPath, this);
                }
                else {
                    rootKey = new RgsFileKey(root.IsRANU);
                    createKey = rootKey.CreateSubkey(regRoot.RegistryRootPath);
                }
            }

            public override string Root
            {
                get
                {
                    return root.RegistryRootPath;
                }
            }

            public override string RootFolder
            {
                get
                {
                    return "[RootFolder]";
                }
            }

            public override RegistrationAttribute.Key CreateKey(string name) {
                return createKey.CreateSubkey(name);
            }

            public override void RemoveKey(string name) {
                return;
            }

            public override void RemoveKeyIfEmpty(string name)
            {
                return;
            }

            public override void RemoveValue(string keyName, string valueName)
            {
                return ;
            }

            public override string GetComponentPath(Type componentType) {

                string componentPath = null;

                if (componentType != null) {
                    componentPath = string.Format(CultureInfo.InvariantCulture, "[{0}]", RegPkg.GetTokenValue(componentType, "$ComponentPath"));
                    
                    // If we have been asked to generate an RGM, create a key for this component path
                    string componentID = string.Format(CultureInfo.InvariantCulture, "{0}_Path", componentType.Name.Replace('.', '_'));
                    componentPath = CreateSubstitutionString(componentID, componentPath, false);
                }

                return componentPath;
            }

            public override string GetCodeBase(Type componentType) {
                if (null == componentType) {
                    return string.Empty;
                }
                string fileName = System.IO.Path.GetFileName(componentType.Assembly.Location);
                return string.Format(CultureInfo.InvariantCulture, "{0}{1}", GetComponentPath(componentType), fileName);
            }

            public override string GetInprocServerPath(Type componentType) {

                string inprocServerPath = null;

                if (componentType != null) {
                    inprocServerPath = string.Format(CultureInfo.InvariantCulture, "[{0}]mscoree.dll", RegPkg.GetTokenValue(componentType, "SystemFolder"));
                    inprocServerPath = CreateSubstitutionString("MSCOREE_PATH", inprocServerPath, false);
                }

                return inprocServerPath;
            }

            internal string CreateSubstitutionString(string substitution, string value, bool quote) {
                if (rgmHash != null) {
                    string existing = (string)rgmHash[substitution];
                    if (existing != null && !existing.Equals(value)) {
                        throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Resources.RegPkg_DuplicateSubstitution, substitution, existing, value));
                    }
                    if (quote) {
                        value = string.Format(CultureInfo.InvariantCulture, "\"{0}\"", value);
                    }

                    rgmHash[substitution] = value;
                    if (existing == null) {
                        rgmKeys.Add(substitution);
                    }

                    return string.Format(CultureInfo.InvariantCulture, "%{0}%", substitution);
                }
                return value;
            }

            public override string ToString() {
                return string.Empty;
            }

            public string[] GetStrings() {

                string[] retVal;

                // First, all of the children.  We can get to them simply by
                // closing the roots and returning ToString on them.
                //
                rootKey.Close();

                string registryData = rootKey.ToString();

                if (rgmKeys != null) {
                    retVal = new string[2];
                    retVal[0] = registryData;

                    StringBuilder builder = new StringBuilder();
                    foreach(object key in rgmKeys) {
                        builder.Append(string.Format(CultureInfo.InvariantCulture, "{0}={1}\r\n", key, rgmHash[key]));
                    }
                    retVal[1] = builder.ToString();
                }
                else {
                    retVal = new string[] {registryData};
                }

                return retVal;
            }
        }

        /// <devdoc>
        ///     Key object that is used to produce .REG file data.
        /// </devdoc>
        private sealed class RgsFileKey : RegistrationAttribute.Key {

            private string name;
            private string keyValue = null;
            private string beginRoot;
            private string endRoot;
            private ArrayList children = new ArrayList();
            private Hashtable nameChildren = new Hashtable();
            private ArrayList values = new ArrayList();

            internal RgsFileKey(bool userKey) {
                this.name = userKey ? "HKCU" : "HKLM";
            }

            private RgsFileKey(string name) {
                this.name = string.Format(CultureInfo.InvariantCulture, "'{0}'", name);
            }

            private RgsFileKey(string root, RgsFileHive hive) {
                hive.CreateSubstitutionString("[REGROOT]", root, true);
                beginRoot = hive.CreateSubstitutionString("REGROOTBEGIN", "*[REGROOT]", false);
                endRoot = hive.CreateSubstitutionString("REGROOTEND", "[REGROOT]*", false);
            }

            public override void Close() {
            }

            public RegistrationAttribute.Key CreateRegRootKey(string root, RgsFileHive hive) {
                RgsFileKey key = new RgsFileKey(root, hive);
                children.Add(key);
                return key;
            }

            public override RegistrationAttribute.Key CreateSubkey(string keyName) {
                if (string.IsNullOrEmpty(keyName)) {
                    throw new ArgumentNullException("keyName");
                }
                // Parse subkeys
                //
                string[] subnames = keyName.Split(new char[] { '\\' });

                RgsFileKey returnSubKey = null;

                foreach(string subname in subnames) {
                    if (returnSubKey == null) {
                        returnSubKey = (RgsFileKey)nameChildren[subname];
                        if (returnSubKey == null) {
                            returnSubKey = new RgsFileKey(subname);
                            children.Add(returnSubKey);
                            nameChildren[subname] = returnSubKey;
                        }
                    }
                    else {
                        returnSubKey = (RgsFileKey)returnSubKey.CreateSubkey(subname);
                    }
                }

                return returnSubKey;
            }

            private static string FormatValue(object value) {
                // Only support string and dword values
                if (value.GetType().IsPrimitive) {
                    return string.Format(CultureInfo.InvariantCulture, "d '{0}'", value);
                }
                else {
                    return string.Format(CultureInfo.InvariantCulture, "s '{0}'", Utilities.DoubleBackSlash(value.ToString()));
                }
            }

            public override void SetValue(string valueName, object value) {

                if (value == null) {
                    throw new ArgumentNullException("value");
                }

                if (string.IsNullOrEmpty(valueName)) {
                    keyValue = FormatValue(value);
                }
                else {
                    values.Add(string.Format(CultureInfo.InvariantCulture, "val '{0}' = {1}", valueName, FormatValue(value)));
                }
            }

            public override string ToString() {
                StringBuilder builder = new StringBuilder();
                ToString(builder, string.Empty);
                return builder.ToString();
            }

            private void ToString(StringBuilder builder, string margin) {

                string CRLF = "\r\n";

                builder.Append(margin);

                if (name != null) {
                    string keyLine = name;
                    if (keyValue != null) {
                        keyLine = string.Format(CultureInfo.InvariantCulture, "{0} = {1}", name, keyValue);
                    }

                    // The key name and opening brace
                    builder.Append(keyLine);
                    builder.Append(CRLF);
                    builder.Append(margin);
                    builder.Append("{");
                }
                else {
                    Debug.Assert(beginRoot != null, "Either name or root must be non-null");
                    builder.Append(beginRoot);
                }

                builder.Append(CRLF);

                // our own values
                string newMargin = margin + "    ";
                foreach(string value in values) {
                    builder.Append(newMargin);
                    builder.Append(value);
                    builder.Append(CRLF);
                }

                // Our children
                foreach(RgsFileKey child in children) {
                    child.ToString(builder, newMargin);
                }

                // And the closing brace / end root
                builder.Append(margin);

                if (name != null) {
                    builder.Append("}");
                }
                else {
                    Debug.Assert(endRoot != null, "Either name or root must be non-null");
                    builder.Append(endRoot);
                }

                builder.Append(CRLF);
            }
        }

        /// <devdoc>
        ///     Hive object that is used to produce .VRG file data.
        /// </devdoc>
        private sealed class VrgFileHive : RegFileHive {

            public VrgFileHive(RegistryRoot regRoot) : base(regRoot) {
            }

            protected override void AddHeader(StringBuilder b) {
                b.Append("VSREG7\r\n\r\n");
            }

            public override string GetComponentPath(Type componentType) {
                return string.Format(CultureInfo.InvariantCulture, "[{0}]", RegPkg.GetTokenValue(componentType, "$ComponentPath"));
            }

            public override string GetCodeBase(Type componentType) {
                if (null == componentType) {
                    return string.Empty;
                }
                string fileName = System.IO.Path.GetFileName(componentType.Assembly.Location);
                return string.Format(CultureInfo.InvariantCulture, "{0}{1}", GetComponentPath(componentType), fileName);
            }

            public override string GetInprocServerPath(Type componentType) {
                return string.Format(CultureInfo.InvariantCulture, "[{0}]mscoree.dll", RegPkg.GetTokenValue(componentType, "SystemFolder"));
            }
        }
    }
}

www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.