/// <summary>
        /// Harvest a reg file.
        /// </summary>
        /// <param name="path">The path of the file.</param>
        /// <returns>A harvested registy file.</returns>
        public Wix.Fragment HarvestRegFile(string path)
        {
            if (null == path)
            {
                throw new ArgumentNullException("path");
            }

            if (!File.Exists(path))
            {
                throw new WixException(HarvesterErrors.FileNotFound(path));
            }

            Wix.Directory directory = new Wix.Directory();
            directory.Id = "TARGETDIR";

            // Use absolute paths
            path = Path.GetFullPath(path);
            FileInfo file = new FileInfo(path);

            using (StreamReader sr = file.OpenText())
            {
                string line;
                this.currentLineNumber = 0;

                while (null != (line = this.GetNextLine(sr)))
                {
                    if (line.StartsWith(@"Windows Registry Editor Version 5.00"))
                    {
                        this.unicodeRegistry = true;
                    }
                    else if (line.StartsWith(@"REGEDIT4"))
                    {
                        this.unicodeRegistry = false;
                    }
                    else if (line.StartsWith(@"[HKEY_CLASSES_ROOT\"))
                    {
                        this.ConvertKey(sr, ref directory, Wix.RegistryRootType.HKCR, line.Substring(19, line.Length - 20));
                    }
                    else if (line.StartsWith(@"[HKEY_CURRENT_USER\"))
                    {
                        this.ConvertKey(sr, ref directory, Wix.RegistryRootType.HKCU, line.Substring(19, line.Length - 20));
                    }
                    else if (line.StartsWith(@"[HKEY_LOCAL_MACHINE\"))
                    {
                        this.ConvertKey(sr, ref directory, Wix.RegistryRootType.HKLM, line.Substring(20, line.Length - 21));
                    }
                    else if (line.StartsWith(@"[HKEY_USERS\"))
                    {
                        this.ConvertKey(sr, ref directory, Wix.RegistryRootType.HKU, line.Substring(12, line.Length - 13));
                    }
                }
            }

            Console.WriteLine("Processing complete");

            Wix.Fragment fragment = new Wix.Fragment();
            fragment.AddChild(directory);

            return(fragment);
        }
Beispiel #2
0
        /// <summary>
        /// Mutate a WiX document as a string.
        /// </summary>
        /// <param name="wix">The Wix document element as a string.</param>
        /// <returns>The mutated Wix document as a string.</returns>
        public override string Mutate(string wixString)
        {
            try
            {
                XslCompiledTransform xslt = new XslCompiledTransform();
                xslt.Load(this.transform, XsltSettings.TrustedXslt, new XmlUrlResolver());

                using (XmlTextReader xmlReader = new XmlTextReader(new StringReader(wixString)))
                {
                    using (StringWriter stringWriter = new StringWriter())
                    {
                        XmlWriterSettings xmlSettings = new XmlWriterSettings();
                        xmlSettings.Indent             = true;
                        xmlSettings.IndentChars        = "    ";
                        xmlSettings.OmitXmlDeclaration = true;

                        using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, xmlSettings))
                        {
                            xslt.Transform(xmlReader, xmlWriter);
                        }

                        wixString = stringWriter.ToString();
                    }
                }
            }
            catch (Exception ex)
            {
                this.Core.Messaging.Write(HarvesterErrors.ErrorTransformingHarvestedWiX(this.transform, ex.Message));
                return(null);
            }

            return(wixString);
        }
Beispiel #3
0
        private string GetArgumentParameter(string[] args, int index, bool allowSpaces)
        {
            string truncatedCommandSwitch = args[index];
            string commandSwitchValue     = args[index + 1];

            //increment the index to the switch value
            index++;

            if (IsValidArg(args, index) && !String.IsNullOrEmpty(commandSwitchValue.Trim()))
            {
                if (!allowSpaces && commandSwitchValue.Contains(" "))
                {
                    this.Core.Messaging.Write(HarvesterErrors.SpacesNotAllowedInArgumentValue(truncatedCommandSwitch, commandSwitchValue));
                }
                else
                {
                    return(commandSwitchValue);
                }
            }
            else
            {
                this.Core.Messaging.Write(HarvesterErrors.ArgumentRequiresValue(truncatedCommandSwitch));
            }

            return(null);
        }
        /// <summary>
        /// Harvest a directory.
        /// </summary>
        /// <param name="path">The path of the directory.</param>
        /// <param name="relativePath">The relative path that will be used when harvesting.</param>
        /// <param name="harvestChildren">The option to harvest child directories and files.</param>
        /// <returns>The harvested directory.</returns>
        public Wix.Directory HarvestDirectory(string path, string relativePath, bool harvestChildren)
        {
            if (null == path)
            {
                throw new ArgumentNullException("path");
            }

            if (File.Exists(path))
            {
                throw new WixException(ErrorMessages.ExpectedDirectoryGotFile("dir", path));
            }

            if (null == this.rootedDirectoryRef)
            {
                this.rootedDirectoryRef = "TARGETDIR";
            }

            // use absolute paths
            path = Path.GetFullPath(path);

            // Remove any trailing separator to ensure Path.GetFileName() will return the directory name.
            path = path.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);

            Wix.Directory directory = new Wix.Directory();

            directory.Name       = Path.GetFileName(path);
            directory.FileSource = path;

            if (this.setUniqueIdentifiers)
            {
                if (this.suppressRootDirectory)
                {
                    directory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, this.rootedDirectoryRef);
                }
                else
                {
                    directory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, this.rootedDirectoryRef, directory.Name);
                }
            }

            if (harvestChildren)
            {
                try
                {
                    int fileCount = this.HarvestDirectory(path, relativePath, directory);

                    // its an error to not harvest anything with the option to keep empty directories off
                    if (0 == fileCount && !this.keepEmptyDirectories)
                    {
                        throw new WixException(HarvesterErrors.EmptyDirectory(path));
                    }
                }
                catch (DirectoryNotFoundException)
                {
                    throw new WixException(HarvesterErrors.DirectoryNotFound(path));
                }
            }

            return(directory);
        }
        /// <summary>
        /// Harvest a payload.
        /// </summary>
        /// <param name="path">The path of the payload.</param>
        /// <returns>A harvested payload.</returns>
        public Wix.RemotePayload HarvestRemotePayload(string path)
        {
            if (null == path)
            {
                throw new ArgumentNullException("path");
            }

            if (!File.Exists(path))
            {
                throw new WixException(HarvesterErrors.FileNotFound(path));
            }

            Wix.RemotePayload remotePayload;

            switch (this.packageType)
            {
            case WixBundlePackageType.Exe:
                remotePayload = new Wix.ExePackagePayload();
                break;

            case WixBundlePackageType.Msu:
                remotePayload = new Wix.MsuPackagePayload();
                break;

            default:
                throw new NotImplementedException();
            }

            var payloadSymbol = new WixBundlePayloadSymbol
            {
                SourceFile = new IntermediateFieldPathValue {
                    Path = path
                },
            };

            this.payloadHarvester.HarvestStandardInformation(payloadSymbol);

            if (payloadSymbol.FileSize.HasValue)
            {
                remotePayload.Size = payloadSymbol.FileSize.Value;
            }
            remotePayload.Hash = payloadSymbol.Hash;

            if (!String.IsNullOrEmpty(payloadSymbol.Version))
            {
                remotePayload.Version = payloadSymbol.Version;
            }

            if (!String.IsNullOrEmpty(payloadSymbol.Description))
            {
                remotePayload.Description = payloadSymbol.Description;
            }

            if (!String.IsNullOrEmpty(payloadSymbol.DisplayName))
            {
                remotePayload.ProductName = payloadSymbol.DisplayName;
            }

            return(remotePayload);
        }
Beispiel #6
0
        /// <summary>
        /// Harvest a payload.
        /// </summary>
        /// <param name="path">The path of the payload.</param>
        /// <returns>A harvested payload.</returns>
        public Wix.RemotePayload HarvestRemotePayload(string path)
        {
            if (null == path)
            {
                throw new ArgumentNullException("path");
            }

            if (!File.Exists(path))
            {
                throw new WixException(HarvesterErrors.FileNotFound(path));
            }

            Wix.RemotePayload remotePayload = new Wix.RemotePayload();

            FileInfo fileInfo = new FileInfo(path);

            remotePayload.Size = (int)fileInfo.Length;
            remotePayload.Hash = this.GetFileHash(path);

            FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(path);

            if (null != versionInfo)
            {
                // Use the fixed version info block for the file since the resource text may not be a dotted quad.
                Version version = new Version(versionInfo.ProductMajorPart, versionInfo.ProductMinorPart, versionInfo.ProductBuildPart, versionInfo.ProductPrivatePart);

                remotePayload.Version     = version.ToString();
                remotePayload.Description = versionInfo.FileDescription;
                remotePayload.ProductName = versionInfo.ProductName;
            }

            return(remotePayload);
        }
Beispiel #7
0
        /// <summary>
        /// Harvest a web site.
        /// </summary>
        /// <param name="name">The name of the web site.</param>
        /// <returns>The harvested web site.</returns>
        public IIs.WebSite HarvestWebSite(string name)
        {
            try
            {
                DirectoryEntry directoryEntry = new DirectoryEntry("IIS://localhost/W3SVC");

                foreach (DirectoryEntry childEntry in directoryEntry.Children)
                {
                    if ("IIsWebServer" == childEntry.SchemaClassName)
                    {
                        if (String.Equals((string)childEntry.Properties["ServerComment"].Value, name, StringComparison.OrdinalIgnoreCase))
                        {
                            return(this.HarvestWebSite(childEntry));
                        }
                    }
                }
            }
            catch (COMException ce)
            {
                // 0x8007005 - access denied
                // If we don't have permission to harvest a website, it's likely because we're on
                // Vista or higher and aren't an Admin.
                if ((0x80070005 == unchecked ((uint)ce.ErrorCode)))
                {
                    throw new WixException(HarvesterErrors.InsufficientPermissionHarvestWebSite());
                }
                // 0x80005000 - unknown error
                else if ((0x80005000 == unchecked ((uint)ce.ErrorCode)))
                {
                    throw new WixException(HarvesterErrors.CannotHarvestWebSite());
                }
            }

            throw new WixException(HarvesterErrors.WebSiteNotFound(name));
        }
        /// <summary>
        /// Harvest a registry key.
        /// </summary>
        /// <param name="path">The path of the registry key to harvest.</param>
        /// <returns>The registry keys and values under the key.</returns>
        public Wix.RegistryValue[] HarvestRegistryKey(string path)
        {
            RegistryKey registryKey    = null;
            ArrayList   registryValues = new ArrayList();

            string[] parts = GetPathParts(path);

            try
            {
                switch (parts[0])
                {
                case "HKEY_CLASSES_ROOT":
                    registryKey = Registry.ClassesRoot;
                    break;

                case "HKEY_CURRENT_USER":
                    registryKey = Registry.CurrentUser;
                    break;

                case "HKEY_LOCAL_MACHINE":
                    registryKey = Registry.LocalMachine;
                    break;

                case "HKEY_USERS":
                    registryKey = Registry.Users;
                    break;

                default:
                    // TODO: put a better exception here
                    throw new Exception();
                }

                if (1 < parts.Length)
                {
                    registryKey = registryKey.OpenSubKey(parts[1]);

                    if (null == registryKey)
                    {
                        throw new WixException(HarvesterErrors.UnableToOpenRegistryKey(parts[1]));
                    }
                }

                this.HarvestRegistryKey(registryKey, registryValues);
            }
            finally
            {
                if (null != registryKey)
                {
                    registryKey.Close();
                }
            }

            return((Wix.RegistryValue[])registryValues.ToArray(typeof(Wix.RegistryValue)));
        }
        /// <summary>
        /// Harvest a performance category.
        /// </summary>
        /// <param name="category">The name of the performance category.</param>
        /// <returns>A harvested file.</returns>
        public Util.PerformanceCategory HarvestPerformanceCategory(string category)
        {
            if (null == category)
            {
                throw new ArgumentNullException("category");
            }

            if (PerformanceCounterCategory.Exists(category))
            {
                Util.PerformanceCategory perfCategory = new Util.PerformanceCategory();

                // Get the performance counter category and set the appropriate WiX attributes
                PerformanceCounterCategory pcc = PerformanceCounterCategory.GetCategories().Single(c => string.Equals(c.CategoryName, category));
                perfCategory.Id   = this.Core.CreateIdentifierFromFilename(pcc.CategoryName);
                perfCategory.Name = pcc.CategoryName;
                perfCategory.Help = pcc.CategoryHelp;
                if (PerformanceCounterCategoryType.MultiInstance == pcc.CategoryType)
                {
                    perfCategory.MultiInstance = Util.YesNoType.yes;
                }

                // If it's multi-instance, check if there are any instances and get counters from there; else we get
                // the counters straight up. For multi-instance, GetCounters() fails if there are any instances. If there
                // are no instances, then GetCounters(instance) can't be called since there is no instance. Instances
                // will exist for each counter even if only one of the counters was "intialized."
                string[]             instances    = pcc.GetInstanceNames();
                bool                 hasInstances = instances.Length > 0;
                PerformanceCounter[] counters     = hasInstances
                    ? pcc.GetCounters(instances.First())
                    : pcc.GetCounters();

                foreach (PerformanceCounter counter in counters)
                {
                    Util.PerformanceCounter perfCounter = new Util.PerformanceCounter();

                    // Get the performance counter and set the appropriate WiX attributes
                    perfCounter.Name = counter.CounterName;
                    perfCounter.Type = this.CounterTypeToWix(counter.CounterType);
                    perfCounter.Help = counter.CounterHelp;

                    perfCategory.AddChild(perfCounter);
                }

                return(perfCategory);
            }
            else
            {
                throw new WixException(HarvesterErrors.PerformanceCategoryNotFound(category));
            }
        }
Beispiel #10
0
        /// <summary>
        /// Harvest a file.
        /// </summary>
        /// <param name="path">The path of the file.</param>
        /// <returns>A harvested file.</returns>
        public Wix.File HarvestFile(string path)
        {
            if (null == path)
            {
                throw new ArgumentNullException("path");
            }

            if (!File.Exists(path))
            {
                throw new WixException(HarvesterErrors.FileNotFound(path));
            }

            Wix.File file = new Wix.File();

            // use absolute paths
            path = Path.GetFullPath(path);

            file.KeyPath = Wix.YesNoType.yes;

            file.Source = String.Concat("SourceDir\\", Path.GetFileName(path));

            return(file);
        }
        /// <summary>
        /// Get the WiX performance counter type.
        /// </summary>
        /// <param name="pct">The performance counter value to get.</param>
        /// <returns>The WiX performance counter type.</returns>
        private Util.PerformanceCounterTypesType CounterTypeToWix(PerformanceCounterType pct)
        {
            Util.PerformanceCounterTypesType type;

            switch (pct)
            {
            case PerformanceCounterType.AverageBase:
                type = Util.PerformanceCounterTypesType.averageBase;
                break;

            case PerformanceCounterType.AverageCount64:
                type = Util.PerformanceCounterTypesType.averageCount64;
                break;

            case PerformanceCounterType.AverageTimer32:
                type = Util.PerformanceCounterTypesType.averageTimer32;
                break;

            case PerformanceCounterType.CounterDelta32:
                type = Util.PerformanceCounterTypesType.counterDelta32;
                break;

            case PerformanceCounterType.CounterTimerInverse:
                type = Util.PerformanceCounterTypesType.counterTimerInverse;
                break;

            case PerformanceCounterType.SampleFraction:
                type = Util.PerformanceCounterTypesType.sampleFraction;
                break;

            case PerformanceCounterType.Timer100Ns:
                type = Util.PerformanceCounterTypesType.timer100Ns;
                break;

            case PerformanceCounterType.CounterTimer:
                type = Util.PerformanceCounterTypesType.counterTimer;
                break;

            case PerformanceCounterType.RawFraction:
                type = Util.PerformanceCounterTypesType.rawFraction;
                break;

            case PerformanceCounterType.Timer100NsInverse:
                type = Util.PerformanceCounterTypesType.timer100NsInverse;
                break;

            case PerformanceCounterType.CounterMultiTimer:
                type = Util.PerformanceCounterTypesType.counterMultiTimer;
                break;

            case PerformanceCounterType.CounterMultiTimer100Ns:
                type = Util.PerformanceCounterTypesType.counterMultiTimer100Ns;
                break;

            case PerformanceCounterType.CounterMultiTimerInverse:
                type = Util.PerformanceCounterTypesType.counterMultiTimerInverse;
                break;

            case PerformanceCounterType.CounterMultiTimer100NsInverse:
                type = Util.PerformanceCounterTypesType.counterMultiTimer100NsInverse;
                break;

            case PerformanceCounterType.ElapsedTime:
                type = Util.PerformanceCounterTypesType.elapsedTime;
                break;

            case PerformanceCounterType.SampleBase:
                type = Util.PerformanceCounterTypesType.sampleBase;
                break;

            case PerformanceCounterType.RawBase:
                type = Util.PerformanceCounterTypesType.rawBase;
                break;

            case PerformanceCounterType.CounterMultiBase:
                type = Util.PerformanceCounterTypesType.counterMultiBase;
                break;

            case PerformanceCounterType.RateOfCountsPerSecond64:
                type = Util.PerformanceCounterTypesType.rateOfCountsPerSecond64;
                break;

            case PerformanceCounterType.RateOfCountsPerSecond32:
                type = Util.PerformanceCounterTypesType.rateOfCountsPerSecond32;
                break;

            case PerformanceCounterType.CountPerTimeInterval64:
                type = Util.PerformanceCounterTypesType.countPerTimeInterval64;
                break;

            case PerformanceCounterType.CountPerTimeInterval32:
                type = Util.PerformanceCounterTypesType.countPerTimeInterval32;
                break;

            case PerformanceCounterType.SampleCounter:
                type = Util.PerformanceCounterTypesType.sampleCounter;
                break;

            case PerformanceCounterType.CounterDelta64:
                type = Util.PerformanceCounterTypesType.counterDelta64;
                break;

            case PerformanceCounterType.NumberOfItems64:
                type = Util.PerformanceCounterTypesType.numberOfItems64;
                break;

            case PerformanceCounterType.NumberOfItems32:
                type = Util.PerformanceCounterTypesType.numberOfItems32;
                break;

            case PerformanceCounterType.NumberOfItemsHEX64:
                type = Util.PerformanceCounterTypesType.numberOfItemsHEX64;
                break;

            case PerformanceCounterType.NumberOfItemsHEX32:
                type = Util.PerformanceCounterTypesType.numberOfItemsHEX32;
                break;

            default:
                throw new WixException(HarvesterErrors.UnsupportedPerformanceCounterType(pct.ToString()));
            }

            return(type);
        }
Beispiel #12
0
        /// <summary>
        /// Harvest a directory.
        /// </summary>
        /// <param name="path">The path of the directory.</param>
        /// <param name="harvestChildren">The option to harvest child directories and files.</param>
        /// <param name="generateType">The type to generate.</param>
        /// <returns>The harvested directory.</returns>
        private Wix.IParentElement HarvestDirectory(string path, bool harvestChildren, GenerateType generateType)
        {
            if (File.Exists(path))
            {
                throw new WixException(ErrorMessages.ExpectedDirectoryGotFile("dir", path));
            }

            if (null == this.RootedDirectoryRef)
            {
                this.RootedDirectoryRef = "TARGETDIR";
            }

            // use absolute paths
            path = Path.GetFullPath(path);

            // Remove any trailing separator to ensure Path.GetFileName() will return the directory name.
            path = path.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);

            Wix.IParentElement harvestParent;
            if (generateType == GenerateType.PayloadGroup)
            {
                harvestParent = new Wix.PayloadGroup();
            }
            else
            {
                Wix.Directory directory = new Wix.Directory();
                directory.Name       = Path.GetFileName(path);
                directory.FileSource = path;

                if (this.SetUniqueIdentifiers)
                {
                    if (this.SuppressRootDirectory)
                    {
                        directory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, this.RootedDirectoryRef);
                    }
                    else
                    {
                        directory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, this.RootedDirectoryRef, directory.Name);
                    }
                }
                harvestParent = directory;
            }

            if (harvestChildren)
            {
                try
                {
                    int fileCount = this.HarvestDirectory(path, "SourceDir\\", harvestParent, generateType);

                    if (generateType != GenerateType.PayloadGroup)
                    {
                        // its an error to not harvest anything with the option to keep empty directories off
                        if (0 == fileCount && !this.KeepEmptyDirectories)
                        {
                            throw new WixException(HarvesterErrors.EmptyDirectory(path));
                        }
                    }
                }
                catch (DirectoryNotFoundException)
                {
                    throw new WixException(HarvesterErrors.DirectoryNotFound(path));
                }
            }

            return(harvestParent);
        }
Beispiel #13
0
        /// <summary>
        /// Parse the command line options for this extension.
        /// </summary>
        /// <param name="type">The active harvester type.</param>
        /// <param name="args">The option arguments.</param>
        public override void ParseOptions(string type, string[] args)
        {
            bool active = false;
            IHarvesterExtension harvesterExtension = null;
            bool suppressHarvestingRegistryValues  = false;
            UtilFinalizeHarvesterMutator utilFinalizeHarvesterMutator = new UtilFinalizeHarvesterMutator();
            UtilMutator utilMutator = new UtilMutator();
            List <UtilTransformMutator> transformMutators = new List <UtilTransformMutator>();
            GenerateType generateType = GenerateType.Components;

            // select the harvester
            switch (type)
            {
            case "dir":
                harvesterExtension = new DirectoryHarvester();
                active             = true;
                break;

            case "file":
                harvesterExtension = new FileHarvester();
                active             = true;
                break;

            case "exepackagepayload":
                harvesterExtension = new PayloadHarvester(this.PayloadHarvester, WixBundlePackageType.Exe);
                active             = true;
                break;

            case "msupackagepayload":
                harvesterExtension = new PayloadHarvester(this.PayloadHarvester, WixBundlePackageType.Msu);
                active             = true;
                break;

            case "perf":
                harvesterExtension = new PerformanceCategoryHarvester();
                active             = true;
                break;

            case "reg":
                harvesterExtension = new RegFileHarvester();
                active             = true;
                break;
            }

            // set default settings
            utilMutator.CreateFragments      = true;
            utilMutator.SetUniqueIdentifiers = true;

            // parse the options
            for (int i = 0; i < args.Length; i++)
            {
                string commandSwitch = args[i];

                if (null == commandSwitch || 0 == commandSwitch.Length) // skip blank arguments
                {
                    continue;
                }

                if ('-' == commandSwitch[0] || '/' == commandSwitch[0])
                {
                    string truncatedCommandSwitch = commandSwitch.Substring(1);

                    if ("ag" == truncatedCommandSwitch)
                    {
                        utilMutator.AutogenerateGuids = true;
                    }
                    else if ("cg" == truncatedCommandSwitch)
                    {
                        utilMutator.ComponentGroupName = this.GetArgumentParameter(args, i);

                        if (this.Core.Messaging.EncounteredError)
                        {
                            return;
                        }
                    }
                    else if ("dr" == truncatedCommandSwitch)
                    {
                        string dr = this.GetArgumentParameter(args, i);

                        if (this.Core.Messaging.EncounteredError)
                        {
                            return;
                        }

                        if (harvesterExtension is DirectoryHarvester)
                        {
                            ((DirectoryHarvester)harvesterExtension).RootedDirectoryRef = dr;
                        }
                        else if (harvesterExtension is FileHarvester)
                        {
                            ((FileHarvester)harvesterExtension).RootedDirectoryRef = dr;
                        }
                    }
                    else if ("gg" == truncatedCommandSwitch)
                    {
                        utilMutator.GenerateGuids = true;
                    }
                    else if ("g1" == truncatedCommandSwitch)
                    {
                        utilMutator.GuidFormat = "D";
                    }
                    else if ("ke" == truncatedCommandSwitch)
                    {
                        if (harvesterExtension is DirectoryHarvester)
                        {
                            ((DirectoryHarvester)harvesterExtension).KeepEmptyDirectories = true;
                        }
                        else if (active)
                        {
                            // TODO: error message - not applicable to file harvester
                        }
                    }
                    else if ("scom" == truncatedCommandSwitch)
                    {
                        if (active)
                        {
                            utilFinalizeHarvesterMutator.SuppressCOMElements = true;
                        }
                        else
                        {
                            // TODO: error message - not applicable
                        }
                    }
                    else if ("svb6" == truncatedCommandSwitch)
                    {
                        if (active)
                        {
                            utilFinalizeHarvesterMutator.SuppressVB6COMElements = true;
                        }
                        else
                        {
                            // TODO: error message - not applicable
                        }
                    }
                    else if ("sfrag" == truncatedCommandSwitch)
                    {
                        utilMutator.CreateFragments = false;
                    }
                    else if ("srd" == truncatedCommandSwitch)
                    {
                        if (harvesterExtension is DirectoryHarvester)
                        {
                            ((DirectoryHarvester)harvesterExtension).SuppressRootDirectory = true;
                        }
                        else if (harvesterExtension is FileHarvester)
                        {
                            ((FileHarvester)harvesterExtension).SuppressRootDirectory = true;
                        }
                    }
                    else if ("sreg" == truncatedCommandSwitch)
                    {
                        suppressHarvestingRegistryValues = true;
                    }
                    else if ("suid" == truncatedCommandSwitch)
                    {
                        utilMutator.SetUniqueIdentifiers = false;

                        if (harvesterExtension is DirectoryHarvester)
                        {
                            ((DirectoryHarvester)harvesterExtension).SetUniqueIdentifiers = false;
                        }
                        else if (harvesterExtension is FileHarvester)
                        {
                            ((FileHarvester)harvesterExtension).SetUniqueIdentifiers = false;
                        }
                    }
                    else if (truncatedCommandSwitch.StartsWith("t:", StringComparison.Ordinal) || "t" == truncatedCommandSwitch)
                    {
                        string xslFile;
                        if (truncatedCommandSwitch.StartsWith("t:", StringComparison.Ordinal))
                        {
                            this.Core.Messaging.Write(WarningMessages.DeprecatedCommandLineSwitch("t:", "t"));
                            xslFile = truncatedCommandSwitch.Substring(2);
                        }
                        else
                        {
                            xslFile = this.GetArgumentParameter(args, i, true);
                        }

                        if (0 <= xslFile.IndexOf('\"'))
                        {
                            this.Core.Messaging.Write(ErrorMessages.PathCannotContainQuote(xslFile));
                            return;
                        }

                        try
                        {
                            xslFile = Path.GetFullPath(xslFile);
                        }
                        catch (Exception e)
                        {
                            this.Core.Messaging.Write(ErrorMessages.InvalidCommandLineFileName(xslFile, e.Message));
                            return;
                        }

                        transformMutators.Add(new UtilTransformMutator(xslFile, transformMutators.Count));
                    }
                    else if (truncatedCommandSwitch.StartsWith("template:", StringComparison.Ordinal) || "template" == truncatedCommandSwitch)
                    {
                        string template;
                        if (truncatedCommandSwitch.StartsWith("template:", StringComparison.Ordinal))
                        {
                            this.Core.Messaging.Write(WarningMessages.DeprecatedCommandLineSwitch("template:", "template"));
                            template = truncatedCommandSwitch.Substring(9);
                        }
                        else
                        {
                            template = this.GetArgumentParameter(args, i);
                        }

                        switch (template)
                        {
                        case "fragment":
                            utilMutator.TemplateType = TemplateType.Fragment;
                            break;

                        case "module":
                            utilMutator.TemplateType = TemplateType.Module;
                            break;

                        case "product":
                            utilMutator.TemplateType = TemplateType.Package;
                            break;

                        default:
                            // TODO: error
                            break;
                        }
                    }
                    else if ("var" == truncatedCommandSwitch)
                    {
                        if (active)
                        {
                            utilFinalizeHarvesterMutator.PreprocessorVariable = this.GetArgumentParameter(args, i);

                            if (this.Core.Messaging.EncounteredError)
                            {
                                return;
                            }
                        }
                    }
                    else if ("generate" == truncatedCommandSwitch)
                    {
                        if (harvesterExtension is DirectoryHarvester)
                        {
                            string genType = this.GetArgumentParameter(args, i).ToUpperInvariant();
                            switch (genType)
                            {
                            case "COMPONENTS":
                                generateType = GenerateType.Components;
                                break;

                            case "PAYLOADGROUP":
                                generateType = GenerateType.PayloadGroup;
                                break;

                            default:
                                throw new WixException(HarvesterErrors.InvalidDirectoryOutputType(genType));
                            }
                        }
                        else
                        {
                            // TODO: error message - not applicable
                        }
                    }
                }
            }

            // set the appropriate harvester extension
            if (active)
            {
                this.Core.Harvester.Extension = harvesterExtension;

                if (!suppressHarvestingRegistryValues)
                {
                    this.Core.Mutator.AddExtension(new UtilHarvesterMutator());
                }

                this.Core.Mutator.AddExtension(utilFinalizeHarvesterMutator);

                if (harvesterExtension is DirectoryHarvester directoryHarvester)
                {
                    directoryHarvester.GenerateType        = generateType;
                    this.Core.Harvester.Core.RootDirectory = this.Core.Harvester.Core.ExtensionArgument;
                }
                else if (harvesterExtension is FileHarvester)
                {
                    if (((FileHarvester)harvesterExtension).SuppressRootDirectory)
                    {
                        this.Core.Harvester.Core.RootDirectory = Path.GetDirectoryName(Path.GetFullPath(this.Core.Harvester.Core.ExtensionArgument));
                    }
                    else
                    {
                        this.Core.Harvester.Core.RootDirectory = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetFullPath(this.Core.Harvester.Core.ExtensionArgument)));

                        // GetDirectoryName() returns null for root paths such as "c:\", so make sure to support that as well
                        if (null == this.Core.Harvester.Core.RootDirectory)
                        {
                            this.Core.Harvester.Core.RootDirectory = Path.GetPathRoot(Path.GetDirectoryName(Path.GetFullPath(this.Core.Harvester.Core.ExtensionArgument)));
                        }
                    }
                }
            }

            // set the mutator
            this.Core.Mutator.AddExtension(utilMutator);

            // add the transforms
            foreach (UtilTransformMutator transformMutator in transformMutators)
            {
                this.Core.Mutator.AddExtension(transformMutator);
            }
        }
        /// <summary>
        /// Parse the command line options for this extension.
        /// </summary>
        /// <param name="type">The active harvester type.</param>
        /// <param name="args">The option arguments.</param>
        public override void ParseOptions(string type, string[] args)
        {
            if ("project" == type)
            {
                string[]     allOutputGroups  = VSProjectHarvester.GetOutputGroupNames();
                bool         suppressUniqueId = false;
                bool         generateWixVars  = false;
                bool         useToolsVersion  = false;
                GenerateType generateType     = GenerateType.Components;
                string       directoryIds     = null;
                string       msbuildBinPath   = null;
                string       projectName      = null;
                string       configuration    = null;
                string       platform         = null;
                ArrayList    outputGroups     = new ArrayList();

                for (int i = 0; i < args.Length; i++)
                {
                    if ("-configuration" == args[i])
                    {
                        configuration = args[++i];
                    }
                    else if ("-directoryid" == args[i])
                    {
                        if (!IsValidArg(args, ++i))
                        {
                            throw new WixException(HarvesterErrors.InvalidDirectoryId(args[i]));
                        }

                        directoryIds = args[i];
                    }
                    else if ("-generate" == args[i])
                    {
                        if (!IsValidArg(args, ++i))
                        {
                            throw new WixException(HarvesterErrors.InvalidProjectOutputType(args[i]));
                        }

                        string genType = args[i].ToUpperInvariant();
                        switch (genType)
                        {
                        case "CONTAINER":
                            generateType = GenerateType.Container;
                            break;

                        case "COMPONENTS":
                            generateType = GenerateType.Components;
                            break;

                        case "PACKAGEGROUP":
                            generateType = GenerateType.PackageGroup;
                            break;

                        case "PAYLOADGROUP":
                            generateType = GenerateType.PayloadGroup;
                            break;

                        default:
                            throw new WixException(HarvesterErrors.InvalidProjectOutputType(genType));
                        }
                    }
                    else if ("-msbuildbinpath" == args[i])
                    {
                        if (!IsValidArg(args, ++i))
                        {
                            throw new WixException(HarvesterErrors.ArgumentRequiresValue(args[i - 1]));
                        }

                        msbuildBinPath = args[i];
                    }
                    else if ("-platform" == args[i])
                    {
                        platform = args[++i];
                    }
                    else if ("-pog" == args[i])
                    {
                        if (!IsValidArg(args, ++i))
                        {
                            throw new WixException(HarvesterErrors.InvalidOutputGroup(args[i]));
                        }

                        string pogName = args[i];
                        bool   found   = false;
                        foreach (string availableOutputGroup in allOutputGroups)
                        {
                            if (String.Equals(pogName, availableOutputGroup, StringComparison.Ordinal))
                            {
                                outputGroups.Add(availableOutputGroup);
                                found = true;
                                break;
                            }
                        }

                        if (!found)
                        {
                            throw new WixException(HarvesterErrors.InvalidOutputGroup(pogName));
                        }
                    }
                    else if (args[i].StartsWith("-pog:", StringComparison.Ordinal))
                    {
                        this.Core.Messaging.Write(WarningMessages.DeprecatedCommandLineSwitch("pog:", "pog"));

                        string pogName = args[i].Substring(5);
                        bool   found   = false;
                        foreach (string availableOutputGroup in allOutputGroups)
                        {
                            if (String.Equals(pogName, availableOutputGroup, StringComparison.Ordinal))
                            {
                                outputGroups.Add(availableOutputGroup);
                                found = true;
                                break;
                            }
                        }

                        if (!found)
                        {
                            throw new WixException(HarvesterErrors.InvalidOutputGroup(pogName));
                        }
                    }
                    else if ("-projectname" == args[i])
                    {
                        if (!IsValidArg(args, ++i))
                        {
                            throw new WixException(HarvesterErrors.InvalidProjectName(args[i]));
                        }

                        projectName = args[i];
                    }
                    else if ("-suid" == args[i])
                    {
                        suppressUniqueId = true;
                    }
                    else if ("-usetoolsversion" == args[i])
                    {
                        useToolsVersion = true;
                    }
                    else if ("-wixvar" == args[i])
                    {
                        generateWixVars = true;
                    }
                }

                if (outputGroups.Count == 0)
                {
                    throw new WixException(HarvesterErrors.NoOutputGroupSpecified());
                }

                VSProjectHarvester harvester = new VSProjectHarvester(
                    (string[])outputGroups.ToArray(typeof(string)));

                harvester.SetUniqueIdentifiers = !suppressUniqueId;
                harvester.GenerateWixVars      = generateWixVars;
                harvester.GenerateType         = generateType;
                harvester.DirectoryIds         = directoryIds;
                harvester.MsbuildBinPath       = msbuildBinPath;
                harvester.ProjectName          = projectName;
                harvester.Configuration        = configuration;
                harvester.Platform             = platform;
                harvester.UseToolsVersion      = String.IsNullOrEmpty(msbuildBinPath) || useToolsVersion;

                this.Core.Harvester.Extension = harvester;
            }
        }