コード例 #1
0
        /// <summary>
        /// Harvest a directory.
        /// </summary>
        /// <param name="path">The path of the directory.</param>
        /// <param name="directory">The directory for this path.</param>
        /// <returns>The number of files harvested.</returns>
        private int HarvestDirectory(string path, Wix.Directory directory)
        {
            int fileCount = 0;

            // harvest the child directories
            foreach (string childDirectoryPath in Directory.GetDirectories(path))
            {
                Wix.Directory childDirectory = new Wix.Directory();

                childDirectory.FileSource = childDirectoryPath;
                childDirectory.Name       = Path.GetFileName(childDirectoryPath);

                int childFileCount = this.HarvestDirectory(childDirectoryPath, childDirectory);

                // keep the directory if it contained any files (or empty directories are being kept)
                if (0 < childFileCount || this.keepEmptyDirectories)
                {
                    directory.AddChild(childDirectory);
                }

                fileCount += childFileCount;
            }

            // harvest the files
            string[] files = Directory.GetFiles(path);
            if (0 < files.Length)
            {
                foreach (string filePath in Directory.GetFiles(path))
                {
                    Wix.Component component = new Wix.Component();

                    Wix.File file = this.fileHarvester.HarvestFile(filePath);
                    component.AddChild(file);

                    directory.AddChild(component);
                }
            }
            else if (0 == fileCount && this.keepEmptyDirectories)
            {
                Wix.Component component = new Wix.Component();
                component.KeyPath = Wix.YesNoType.yes;

                Wix.CreateFolder createFolder = new Wix.CreateFolder();
                component.AddChild(createFolder);

                directory.AddChild(component);
            }

            return(fileCount + files.Length);
        }
コード例 #2
0
ファイル: Reg2WxsResolved.cs プロジェクト: mo5h/omeo
        private static void WriteWxsFile(string sOutputWxs, List <RegistryKey> wixKeys, List <RegistryValue> wixValues)
        {
            var wix         = new Wix();
            var wixFragment = new Fragment();

            wix.AddChild(wixFragment);
            var wixDirectory = new Directory();

            wixFragment.AddChild(wixDirectory);
            wixDirectory.Id = "";
            var wixComponent = new Component();

            wixDirectory.AddChild(wixComponent);
            wixComponent.Id   = "";
            wixComponent.Guid = "*";

            foreach (RegistryKey wixKey in wixKeys)
            {
                wixComponent.AddChild(wixKey);
            }
            foreach (RegistryValue wixValue in wixValues)
            {
                wixComponent.AddChild(wixValue);
            }

            // Save to the output file
            using (var xw = new XmlTextWriter(new FileStream(sOutputWxs, FileMode.Create, FileAccess.Write, FileShare.Read), Encoding.UTF8))
            {
                xw.Formatting = Formatting.Indented;
                wix.OutputXml(xw);
            }
        }
コード例 #3
0
        /// <summary>
        /// Mutate the directories.
        /// </summary>
        private void MutateDirectories()
        {
            foreach (Wix.Directory directory in this.directories)
            {
                string path = directory.FileSource;

                // create a new directory element without the FileSource attribute
                if (null != path)
                {
                    Wix.Directory newDirectory = new Wix.Directory();

                    newDirectory.Id   = directory.Id;
                    newDirectory.Name = directory.Name;

                    foreach (Wix.ISchemaElement element in directory.Children)
                    {
                        newDirectory.AddChild(element);
                    }

                    ((Wix.IParentElement)directory.ParentElement).AddChild(newDirectory);
                    ((Wix.IParentElement)directory.ParentElement).RemoveChild(directory);

                    if (null != newDirectory.Id)
                    {
                        this.directoryPaths[path.ToLower(CultureInfo.InvariantCulture)] = String.Concat("[", newDirectory.Id, "]");
                    }
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Harvest a WiX document.
        /// </summary>
        /// <param name="argument">The argument for harvesting.</param>
        /// <returns>The harvested Fragment.</returns>
        public override Wix.Fragment[] Harvest(string argument)
        {
            DirectoryHarvester directoryHarvester = new DirectoryHarvester();

            directoryHarvester.Core = this.Core;
            directoryHarvester.KeepEmptyDirectories = true;

            IIsWebSiteHarvester iisWebSiteHarvester = new IIsWebSiteHarvester();

            iisWebSiteHarvester.Core = this.Core;

            IIs.WebSite webSite = iisWebSiteHarvester.HarvestWebSite(argument);

            Wix.Component component = new Wix.Component();
            component.AddChild(new Wix.CreateFolder());
            component.AddChild(webSite);

            this.Core.RootDirectory = webSite.Directory;
            Wix.Directory directory = directoryHarvester.HarvestDirectory(webSite.Directory, true);
            directory.AddChild(component);

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

            return(new Wix.Fragment[] { fragment });
        }
コード例 #5
0
        protected Directory GetChildDirectoryByName(Directory parent, string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                return(parent);
            }

            foreach (ISchemaElement element in parent.Children)
            {
                if (element is Directory)
                {
                    if (((Directory)element).Name == name)
                    {
                        return(element as Directory);
                    }
                }
            }

            // Not found so create it.

            Directory directory = CreateDirectoryByParentId(parent.Id, name);

            parent.AddChild(directory);
            return(directory);
        }
コード例 #6
0
        /// <summary>
        /// Actions under the resolver.
        /// </summary>
        protected override void ExecuteTaskResolved()
        {
            GuidCacheXml guidcachexml = GuidCacheXml.Load(new FileInfo(Bag.GetString(AttributeName.GuidCacheFile)).OpenRead());

            // Global structure of the WiX fragment file
            var wix = new Wix();
            var wixFragmentComponents = new Fragment();             // Fragment with the payload

            wix.AddChild(wixFragmentComponents);
            var wixDirectoryRef = new DirectoryRef();             // Mount into the directories tree, defined externally

            wixFragmentComponents.AddChild(wixDirectoryRef);
            wixDirectoryRef.Id = Bag.GetString(AttributeName.WixDirectoryId);
            var wixDirectory = new Directory();             // A locally created nameless directory that does not add any nested folders but defines the sources location

            wixDirectoryRef.AddChild(wixDirectory);
            wixDirectory.Id         = DirectoryId;
            wixDirectory.FileSource = Bag.GetString(AttributeName.ProductBinariesDir);
            var wixFragmentGroup = new Fragment();             // Fragment with the component-group that collects the components

            wix.AddChild(wixFragmentGroup);
            var wixComponentGroup = new ComponentGroup();             // ComponentGroup that collects the components

            wixFragmentGroup.AddChild(wixComponentGroup);
            wixComponentGroup.Id = Bag.GetString(AttributeName.WixComponentGroupId);

            // A component for the generated Registry entries
            var wixComponentRegistry = new Component();

            wixDirectory.AddChild(wixComponentRegistry);
            wixComponentRegistry.Id       = RegistryComponentIdPrefix;
            wixComponentRegistry.Guid     = guidcachexml[GuidIdXml.MsiComponent_ProductBinaries_Registry_Hkmu].ToString("B").ToUpper();
            wixComponentRegistry.DiskId   = Bag.Get <int>(AttributeName.DiskId);
            wixComponentRegistry.Location = Component.LocationType.local;
            var wixComponentRegistryRef = new ComponentRef();

            wixComponentGroup.AddChild(wixComponentRegistryRef);
            wixComponentRegistryRef.Id = wixComponentRegistry.Id;

            // Create the Registry key for the Plugins section
            CreatePluginsRegistryKey(wixComponentRegistry);

            // Load the AllAssemblies file
            AllAssembliesXml allassembliesxml = AllAssembliesXml.LoadFrom(Bag.Get <TaskItemByValue>(AttributeName.AllAssembliesXml).ItemSpec);

            // Tracks the files on the target machine, to prevent the same file from being installed both as an assembly and as a reference
            var mapTargetFiles = new Dictionary <string, string>();

            int nGeneratedComponents = ProcessAssemblies(wixDirectory, wixComponentGroup, wixComponentRegistry, allassembliesxml, mapTargetFiles, guidcachexml);

            // Save to the output file
            using (var xw = new XmlTextWriter(new FileStream(Bag.GetString(AttributeName.OutputFile), FileMode.Create, FileAccess.Write, FileShare.Read), Encoding.UTF8))
            {
                xw.Formatting = Formatting.Indented;
                wix.OutputXml(xw);
            }

            // Report (also to see the target in the build logs)
            Log.LogMessage(MessageImportance.Normal, "Generated {0} product binary components.", nGeneratedComponents);
        }
コード例 #7
0
ファイル: WixComponentLoader.cs プロジェクト: formist/LinkMe
        private void LoadGacAssembly(bool isWin64, Artifact artifact, string rootFolderPath, Directory rootDirectory)
        {
            // Create a new component for the gac assembly using the gac guid.

            string guid = artifact.GetMetadata(Constants.Catalogue.Artifact.GacGuid);

            if (string.IsNullOrEmpty(guid))
            {
                guid = System.Guid.Empty.ToString();
            }
            Component component = CreateComponent(isWin64, artifact.ProjectRelativePath, new System.Guid(guid), Wix.Xml.Id.GacPrefix);

            // Put the component into a special directory.

            Directory gacDirectory = GetDirectory(rootDirectory, "Gac");

            gacDirectory.AddChild(component);

            // Create a file, not adding the assembly application property.

            File file = CreateFile(artifact.ProjectRelativePath, FilePath.GetAbsolutePath(artifact.ProjectRelativePath, rootFolderPath), Wix.Xml.Id.GacPrefix);

            component.AddChild(file);
            file.KeyPath  = YesNoType.yes;
            file.Assembly = File.AssemblyType.net;
        }
コード例 #8
0
        /// <summary>
        /// Harvest a file.
        /// </summary>
        /// <param name="argument">The path of the file.</param>
        /// <returns>A harvested file.</returns>
        public override Wix.Fragment Harvest(string argument)
        {
            if (null == argument)
            {
                throw new ArgumentNullException("argument");
            }

            Wix.File file = this.HarvestFile(argument);

            Wix.Component component = new Wix.Component();
            component.AddChild(file);

            string directoryPath = Path.GetDirectoryName(Path.GetFullPath(argument));

            Wix.Directory directory = new Wix.Directory();
            directory.FileSource = directoryPath;
            directory.Name       = Path.GetFileName(directoryPath);
            directory.AddChild(component);

            Wix.DirectoryRef directoryRef = new Wix.DirectoryRef();
            directoryRef.Id = "TARGETDIR";
            directoryRef.AddChild(directory);

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

            return(fragment);
        }
コード例 #9
0
        /// <summary>
        /// Harvest a file.
        /// </summary>
        /// <param name="argument">The path of the file.</param>
        /// <returns>A harvested file.</returns>
        public override Wix.Fragment[] Harvest(string argument)
        {
            if (null == argument)
            {
                throw new ArgumentNullException("argument");
            }

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

            string fullPath = Path.GetFullPath(argument);

            Wix.DirectoryRef directoryRef = new Wix.DirectoryRef();
            directoryRef.Id = this.rootedDirectoryRef;

            Wix.File file = this.HarvestFile(fullPath);

            if (!this.suppressRootDirectory)
            {
                file.Source = String.Concat("SourceDir\\", Path.GetFileName(Path.GetDirectoryName(fullPath)), "\\", Path.GetFileName(fullPath));
            }

            Wix.Component component = new Wix.Component();
            component.AddChild(file);

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

            if (this.suppressRootDirectory)
            {
                directoryRef.AddChild(component);
            }
            else
            {
                string directoryPath = Path.GetDirectoryName(Path.GetFullPath(argument));
                directory.Name = Path.GetFileName(directoryPath);

                if (this.setUniqueIdentifiers)
                {
                    directory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, directoryRef.Id, directory.Name);
                }
                directory.AddChild(component);
                directoryRef.AddChild(directory);
            }

            if (this.setUniqueIdentifiers)
            {
                file.Id      = this.Core.GenerateIdentifier(FilePrefix, (this.suppressRootDirectory) ? directoryRef.Id : directory.Id, Path.GetFileName(file.Source));
                component.Id = this.Core.GenerateIdentifier(ComponentPrefix, (this.suppressRootDirectory) ? directoryRef.Id : directory.Id, file.Id);
            }

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

            return(new Wix.Fragment[] { fragment });
        }
コード例 #10
0
        /// <summary>
        /// Converts the registry key to a WiX component element.
        /// </summary>
        /// <param name="sr">The registry file stream.</param>
        /// <param name="directory">A WiX directory reference.</param>
        /// <param name="root">The root key.</param>
        /// <param name="line">The current line.</param>
        private void ConvertKey(StreamReader sr, ref Wix.Directory directory, Wix.RegistryRootType root, string line)
        {
            Wix.Component component = new Wix.Component();

            component.Id      = this.Core.GenerateIdentifier(ComponentPrefix, line);
            component.KeyPath = Wix.YesNoType.yes;

            this.ConvertValues(sr, ref component, root, line);
            directory.AddChild(component);
        }
コード例 #11
0
        /// <summary>
        /// Creates a new or uses the root directory to add the newly-created component with files being installed.
        /// </summary>
        private void ConvertFiles_AddToDirectory(FolderXml folderxml, Component wixComponent, DirectoryRef wixDirectoryRef)
        {
            if (folderxml.TargetRoot != TargetRootXml.InstallDir)
            {
                throw new InvalidOperationException(string.Format("Only the InstallDir target root is supported."));
            }

            // No relative path — nothing to create
            if (folderxml.TargetDir.Length == 0)
            {
                wixDirectoryRef.AddChild(wixComponent);
                return;
            }

            // Create the folder structure, add to the innermost
            string[]  arDirectoryChain = folderxml.TargetDir.Split('\\');
            Directory wixParentDir     = null;

            for (int a = 0; a < arDirectoryChain.Length; a++)
            {
                bool bInnermost = a == arDirectoryChain.Length - 1;                 // Whether this is the folder in which are the files itself

                // Create
                var wixDirectory = new Directory {
                    Name = arDirectoryChain[a]
                };

                // Mount self into the hierarchy
                if (wixParentDir != null)
                {
                    wixParentDir.AddChild(wixDirectory);                     // Previous dir
                }
                else
                {
                    wixDirectoryRef.AddChild(wixDirectory);                     // The very root
                }
                wixParentDir = wixDirectory;

                // Non-innermost folders get a suffix to their ID
                if (bInnermost)
                {
                    wixDirectory.Id = string.Format("{0}.{1}", DirectoryIdPrefix, folderxml.Id);
                }
                else
                {
                    wixDirectory.Id = string.Format("{0}.{1}.P{2}", DirectoryIdPrefix, folderxml.Id, arDirectoryChain.Length - 1 - a);
                }

                // Mount the component into the innermost dir
                if (bInnermost)
                {
                    wixDirectory.AddChild(wixComponent);
                }
            }
        }
コード例 #12
0
        /// <summary>
        /// Processes the files that should be taken from the “References” folder and installed “AS IS”.
        /// </summary>
        private int ProcessReferences(Directory wixDirectory, ComponentGroup wixComponentGroup, AllAssembliesXml allassembliesxml, Dictionary <string, string> mapTargetFiles)
        {
            int nGeneratedComponents = 0;

            // Replaces illegal chars with underscores
            var regexMakeId = new Regex("[^a-zA-Z0-9_.]");

            foreach (ItemGroupXml group in allassembliesxml.ItemGroup)
            {
                if (group.References == null)
                {
                    continue;
                }
                foreach (ReferenceXml referencexml in group.References)
                {
                    nGeneratedComponents++;
                    var fiReference = new FileInfo(Path.Combine(Bag.GetString(AttributeName.ProductReferencesDir), referencexml.Include));
                    if (!fiReference.Exists)
                    {
                        throw new InvalidOperationException(string.Format("The reference file “{0}” could not be found.", fiReference.FullName));
                    }

                    string sIdSuffix = regexMakeId.Replace(fiReference.Name, "_");

                    // Create the component for the assembly (one per assembly)
                    var wixComponent = new Component();
                    wixDirectory.AddChild(wixComponent);
                    wixComponent.Id       = string.Format("{0}.{1}", FileComponentIdPrefix, sIdSuffix);
                    wixComponent.Guid     = referencexml.MsiGuid;
                    wixComponent.DiskId   = Bag.Get <int>(AttributeName.DiskId);
                    wixComponent.Location = Component.LocationType.local;

                    // Register component in the group
                    var componentref = new ComponentRef();
                    wixComponentGroup.AddChild(componentref);
                    componentref.Id = wixComponent.Id;

                    // Add the reference file (and make it the key path)
                    var wixFileReference = new File();
                    wixComponent.AddChild(wixFileReference);
                    wixFileReference.Id       = string.Format("{0}.{1}", FileIdPrefix, sIdSuffix);
                    wixFileReference.Name     = fiReference.Name;
                    wixFileReference.KeyPath  = YesNoType.yes;
                    wixFileReference.Checksum = YesNoType.yes;
                    wixFileReference.Vital    = YesNoType.yes;
                    wixFileReference.ReadOnly = YesNoType.yes;

                    RegisterTargetFile(wixFileReference.Name, string.Format("The “{0}” reference.", referencexml.Include), mapTargetFiles);
                }
            }

            return(nGeneratedComponents);
        }
コード例 #13
0
ファイル: WixComponentLoader.cs プロジェクト: formist/LinkMe
        public void Load(bool isWin64, Artifact artifact, string rootFolderPath, Directory rootDirectory, Directory directory)
        {
            // Create a component for this artifact.

            string guid = artifact.GetMetadata(Constants.Catalogue.Artifact.Guid);

            if (string.IsNullOrEmpty(guid))
            {
                guid = System.Guid.Empty.ToString();
            }
            Component component = CreateComponent(isWin64, artifact.ProjectRelativePath, new System.Guid(guid));

            directory.AddChild(component);

            // Load all details into the component.

            Load(isWin64, artifact, rootFolderPath, rootDirectory, directory, component);
        }
コード例 #14
0
        protected Directory GetChildDirectory(Directory parent, string id, string name)
        {
            foreach (ISchemaElement element in parent.Children)
            {
                if (element is Directory)
                {
                    if (((Directory)element).Id == id)
                    {
                        return(element as Directory);
                    }
                }
            }

            // Not found so create it.

            Directory directory = CreateDirectory(id, name);

            parent.AddChild(directory);
            return(directory);
        }
コード例 #15
0
        /// <summary>
        /// Scrapes a directory subtree.
        /// </summary>
        /// <param name="target">Directory currently being scraped.</param>
        private static void ScrapeDirectory(Directory target)
        {
            ArrayList subItems = new ArrayList();
            foreach (string directory in IO.Directory.GetDirectories(target.FileSource))
            {
                Directory scrapedDirectory = new Directory();
                directoryId++;
                scrapedDirectory.Id = String.Format(CultureInfo.InvariantCulture, "Dir{0}", directoryId);
                scrapedDirectory.LongName = IO.Path.GetFileName(directory);
                scrapedDirectory.Name = scrapedDirectory.Id;
                scrapedDirectory.FileSource = directory;
                target.AddChild(scrapedDirectory);
                ScrapeDirectory(scrapedDirectory);
            }

            foreach (string file in IO.Directory.GetFiles(target.FileSource))
            {
                File scrapedFile = new File();
                scrapedFile.LongName = IO.Path.GetFileName(file);
                scrapedFile.Source = file;
                fileId++;
                string fileExtension = IO.Path.GetExtension(file);
                if (fileExtension.Length > 4)
                {
                    scrapedFile.Id = String.Format(CultureInfo.InvariantCulture, "Fil{0}{1}", fileId, fileExtension.Substring(0, 4));
                }
                else
                {
                    scrapedFile.Id = String.Format(CultureInfo.InvariantCulture, "Fil{0}{1}", fileId, fileExtension);
                }
                scrapedFile.Name = scrapedFile.Id;

                Component fileComponent = new Component();
                fileComponent.Id = String.Format(CultureInfo.InvariantCulture, "Comp{0}", scrapedFile.Name);
                fileComponent.DiskId = 1;
                fileComponent.Guid = Guid.NewGuid().ToString();
                fileComponent.AddChild(scrapedFile);
                target.AddChild(fileComponent);
            }
        }
コード例 #16
0
        /// <summary>
        /// Mutate the WebFilter elements.
        /// </summary>
        private void MutateWebFilters()
        {
            IdentifierGenerator identifierGenerator = null;

            if (this.setUniqueIdentifiers)
            {
                identifierGenerator = new IdentifierGenerator("WebFilter");

                // index all the existing identifiers and names
                foreach (IIs.WebFilter webFilter in this.webFilters)
                {
                    if (null != webFilter.Id)
                    {
                        identifierGenerator.IndexExistingIdentifier(webFilter.Id);
                    }
                    else
                    {
                        identifierGenerator.IndexName(webFilter.Name);
                    }
                }
            }

            foreach (IIs.WebFilter webFilter in this.webFilters)
            {
                if (this.setUniqueIdentifiers && null == webFilter.Id)
                {
                    webFilter.Id = identifierGenerator.GetIdentifier(webFilter.Name);
                }

                // harvest the file for this WebFilter
                Wix.Directory directory = this.HarvestUniqueDirectory(Path.GetDirectoryName(webFilter.Path), false);

                Wix.Component component = new Wix.Component();
                directory.AddChild(component);

                Wix.File file = this.fileHarvester.HarvestFile(webFilter.Path);
                component.AddChild(file);
            }
        }
コード例 #17
0
        /// <summary>
        /// Harvest a performance category.
        /// </summary>
        /// <param name="argument">The name of the performance category.</param>
        /// <returns>A harvested performance category.</returns>
        public override Wix.Fragment[] Harvest(string argument)
        {
            if (null == argument)
            {
                throw new ArgumentNullException("argument");
            }

            Util.PerformanceCategory perf = this.HarvestPerformanceCategory(argument);

            Wix.Component component = new Wix.Component();
            component.Id      = CompilerCore.GetIdentifierFromName(argument);
            component.KeyPath = Wix.YesNoType.yes;
            component.AddChild(perf);

            Wix.Directory directory = new Wix.Directory();
            directory.Id = "TARGETDIR";
            //directory.Name = directory.Id;
            directory.AddChild(component);

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

            return(new Wix.Fragment[] { fragment });
        }
コード例 #18
0
        /// <summary>
        /// Harvest a performance category.
        /// </summary>
        /// <param name="argument">The name of the performance category.</param>
        /// <returns>A harvested performance category.</returns>
        public override Wix.Fragment[] Harvest(string argument)
        {
            if (null == argument)
            {
                throw new ArgumentNullException("argument");
            }

            Util.PerformanceCategory perf = this.HarvestPerformanceCategory(argument);

            Wix.Component component = new Wix.Component();
            component.Id = CompilerCore.GetIdentifierFromName(argument);
            component.KeyPath = Wix.YesNoType.yes;
            component.AddChild(perf);

            Wix.Directory directory = new Wix.Directory();
            directory.Id = "TARGETDIR";
            //directory.Name = directory.Id;
            directory.AddChild(component);

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

            return new Wix.Fragment[] { fragment };
        }
コード例 #19
0
        private void MutateDirectories()
        {
            foreach (Wix.Directory directory in this.directories)
            {
                string path = directory.FileSource;

                // create a new directory element without the FileSource attribute
                if (null != path)
                {
                    Wix.Directory newDirectory = new Wix.Directory();

                    newDirectory.Id = directory.Id;
                    newDirectory.Name = directory.Name;

                    foreach (Wix.ISchemaElement element in directory.Children)
                    {
                        newDirectory.AddChild(element);
                    }

                    ((Wix.IParentElement)directory.ParentElement).AddChild(newDirectory);
                    ((Wix.IParentElement)directory.ParentElement).RemoveChild(directory);

                    if (null != newDirectory.Id)
                    {
                        this.directoryPaths[path.ToLower(CultureInfo.InvariantCulture)] = String.Concat("[", newDirectory.Id, "]");
                    }
                }
            }
        }
コード例 #20
0
        /// <summary>
        /// Mutate a Wix element.
        /// </summary>
        /// <param name="wix">The Wix element to mutate.</param>
        private void MutateWix(Wix.Wix wix)
        {
            if (TemplateType.Fragment != this.templateType)
            {
                if (null != this.rootElement || 0 != this.features.Count)
                {
                    throw new Exception("The template option cannot be used with Feature, Product, or Module elements present.");
                }

                // create a package element although it won't always be used
                Wix.Package package = new Wix.Package();
                if (TemplateType.Module == this.templateType)
                {
                    package.Id = this.GetGuid();
                }
                else
                {
                    package.Compressed = Wix.YesNoType.yes;
                }

                package.InstallerVersion = 200;

                Wix.Directory targetDir = new Wix.Directory();
                targetDir.Id = "TARGETDIR";
                targetDir.Name = "SourceDir";

                foreach (Wix.DirectoryRef directoryRef in this.directoryRefs)
                {
                    if (String.Equals(directoryRef.Id, "TARGETDIR", StringComparison.OrdinalIgnoreCase))
                    {
                        Wix.IParentElement parent = directoryRef.ParentElement as Wix.IParentElement;

                        foreach (Wix.ISchemaElement element in directoryRef.Children)
                        {
                            targetDir.AddChild(element);
                        }

                        parent.RemoveChild(directoryRef);

                        if (null != ((Wix.ISchemaElement)parent).ParentElement)
                        {
                            int i = 0;

                            foreach (Wix.ISchemaElement element in parent.Children)
                            {
                                i++;
                            }

                            if (0 == i)
                            {
                                Wix.IParentElement supParent = (Wix.IParentElement)((Wix.ISchemaElement)parent).ParentElement;
                                supParent.RemoveChild((Wix.ISchemaElement)parent);
                            }
                        }

                        break;
                    }
                }

                if (TemplateType.Module == this.templateType)
                {
                    Wix.Module module = new Wix.Module();
                    module.Id = "PUT-MODULE-NAME-HERE";
                    module.Language = "1033";
                    module.Version = "1.0.0.0";

                    package.Manufacturer = "PUT-COMPANY-NAME-HERE";
                    module.AddChild(package);
                    module.AddChild(targetDir);

                    wix.AddChild(module);
                    this.rootElement = module;
                }
                else // product
                {
                    Wix.Product product = new Wix.Product();
                    product.Id = this.GetGuid();
                    product.Language = "1033";
                    product.Manufacturer = "PUT-COMPANY-NAME-HERE";
                    product.Name = "PUT-PRODUCT-NAME-HERE";
                    product.UpgradeCode = this.GetGuid();
                    product.Version = "1.0.0.0";
                    product.AddChild(package);
                    product.AddChild(targetDir);

                    Wix.Media media = new Wix.Media();
                    media.Id = "1";
                    media.Cabinet = "product.cab";
                    media.EmbedCab = Wix.YesNoType.yes;
                    product.AddChild(media);

                    Wix.Feature feature = new Wix.Feature();
                    feature.Id = "ProductFeature";
                    feature.Title = "PUT-FEATURE-TITLE-HERE";
                    feature.Level = 1;
                    product.AddChild(feature);
                    this.features.Add(feature);

                    wix.AddChild(product);
                    this.rootElement = product;
                }
            }
        }
コード例 #21
0
        /// <summary>
        /// Processes those AllAssemblies.Xml entries that are our own product assemblies.
        /// </summary>
        private int ProcessAssemblies(Directory wixDirectory, ComponentGroup wixComponentGroup, Component wixComponentRegistry, AllAssembliesXml allassembliesxml, Dictionary <string, string> mapTargetFiles, GuidCacheXml guidcachexml)
        {
            // Collect the assemblies
            int nGeneratedComponents = 0;

            foreach (ItemGroupXml group in allassembliesxml.ItemGroup)
            {
                if (group.AllAssemblies == null)
                {
                    continue;
                }
                foreach (AssemblyXml assemblyxml in group.AllAssemblies)
                {
                    nGeneratedComponents++;
                    FileInfo fiAssembly = FindAssemblyFile(assemblyxml);
                    string   sExtension = fiAssembly.Extension.TrimStart('.');                   // The extension without a dot

                    // Create the component for the assembly (one per assembly)
                    var wixComponent = new Component();
                    wixDirectory.AddChild(wixComponent);
                    wixComponent.Id       = string.Format("{0}.{1}.{2}", FileComponentIdPrefix, assemblyxml.Include, sExtension);
                    wixComponent.Guid     = assemblyxml.MsiGuid;
                    wixComponent.DiskId   = Bag.Get <int>(AttributeName.DiskId);
                    wixComponent.Location = Component.LocationType.local;

                    // Register component in the group
                    var componentref = new ComponentRef();
                    wixComponentGroup.AddChild(componentref);
                    componentref.Id = wixComponent.Id;

                    // Add the assembly file (and make it the key path)
                    var wixFileAssembly = new File();
                    wixComponent.AddChild(wixFileAssembly);
                    wixFileAssembly.Id       = string.Format("{0}.{1}.{2}", FileIdPrefix, assemblyxml.Include, sExtension);
                    wixFileAssembly.Name     = string.Format("{0}.{1}", assemblyxml.Include, sExtension);
                    wixFileAssembly.KeyPath  = YesNoType.yes;
                    wixFileAssembly.Checksum = YesNoType.yes;
                    wixFileAssembly.Vital    = YesNoType.yes;
                    wixFileAssembly.ReadOnly = YesNoType.yes;

                    RegisterTargetFile(wixFileAssembly.Name, string.Format("The {0} product assembly.", assemblyxml.Include), mapTargetFiles);

                    // Check whether it's a managed or native assembly
                    AssemblyName assemblyname = null;
                    try
                    {
                        assemblyname = AssemblyName.GetAssemblyName(fiAssembly.FullName);
                    }
                    catch (BadImageFormatException)
                    {
                    }

                    // Add COM Self-Registration data
                    if (assemblyxml.ComRegister)
                    {
                        /*
                         * foreach(ISchemaElement harvested in HarvestComSelfRegistration(wixFileAssembly, fiAssembly))
                         * wixComponent.AddChild(harvested);
                         */
                        SelfRegHarvester.Harvest(fiAssembly, assemblyname != null, wixComponent, wixFileAssembly);
                    }

                    // Ensure the managed DLL has a strong name
                    if ((assemblyname != null) && (Bag.Get <bool>(AttributeName.RequireStrongName)))
                    {
                        byte[] token = assemblyname.GetPublicKeyToken();
                        if ((token == null) || (token.Length == 0))
                        {
                            throw new InvalidOperationException(string.Format("The assembly “{0}” does not have a strong name.", assemblyxml.Include));
                        }
                    }

                    // Add PDBs
                    if (Bag.Get <bool>(AttributeName.IncludePdb))
                    {
                        HarvestSatellite(assemblyxml, assemblyxml.Include + ".pdb", wixComponent, MissingSatelliteErrorLevel.Error, "PDB file", mapTargetFiles);
                    }

                    // Add XmlDocs
                    if ((assemblyname != null) && (Bag.Get <bool>(AttributeName.IncludeXmlDoc)))
                    {
                        HarvestSatellite(assemblyxml, assemblyxml.Include + ".xml", wixComponent, MissingSatelliteErrorLevel.Error, "XmlDoc file", mapTargetFiles);
                    }

                    // Add configs
                    HarvestSatellite(assemblyxml, assemblyxml.Include + "." + sExtension + ".config", wixComponent, (assemblyxml.HasAppConfig ? MissingSatelliteErrorLevel.Error : MissingSatelliteErrorLevel.None), "application configuration file", mapTargetFiles);
                    HarvestSatellite(assemblyxml, assemblyxml.Include + "." + sExtension + ".manifest", wixComponent, (assemblyxml.HasMainfest ? MissingSatelliteErrorLevel.Error : MissingSatelliteErrorLevel.None), "assembly manifest file", mapTargetFiles);
                    HarvestSatellite(assemblyxml, assemblyxml.Include + ".XmlSerializers." + sExtension, wixComponent, (assemblyxml.HasXmlSerializers ? MissingSatelliteErrorLevel.Error : MissingSatelliteErrorLevel.None), "serialization assembly", mapTargetFiles);

                    // Add publisher policy assemblies
                    if (assemblyname != null)
                    {
                        HarvestPublisherPolicyAssemblies(assemblyxml, wixDirectory, wixComponentGroup, ref nGeneratedComponents, mapTargetFiles, guidcachexml);
                    }

                    // Register as an OmeaPlugin
                    if (assemblyname != null)
                    {
                        RegisterPlugin(assemblyxml, wixFileAssembly, wixComponentRegistry);
                    }
                }
            }
            return(nGeneratedComponents);
        }
コード例 #22
0
        private void HarvestPublisherPolicyAssemblies(AssemblyXml assemblyxml, Directory directory, ComponentGroup componentgroup, ref int nGeneratedComponents, Dictionary <string, string> mapTargetFiles, GuidCacheXml guidcachexml)
        {
            if (!Bag.Get <bool>(AttributeName.IncludePublisherPolicy))
            {
                return;
            }

            int    nWasGeneratedComponents = nGeneratedComponents;
            var    diFolder           = new DirectoryInfo(Bag.GetString(AttributeName.ProductBinariesDir));
            string sSatelliteWildcard = string.Format("Policy.*.{0}.{1}", assemblyxml.Include, "dll");             // Even an EXE assembly has a DLL policy file

            foreach (FileInfo fiPolicyAssembly in diFolder.GetFiles(sSatelliteWildcard))
            {
                // Find the companion policy config file
                var fiPolicyConfig = new FileInfo(Path.ChangeExtension(fiPolicyAssembly.FullName, ".Config"));
                if (!fiPolicyConfig.Exists)
                {
                    throw new InvalidOperationException(string.Format("Could not locate the publisher policy config file for the assembly “{0}”; expected: “{1}”.", fiPolicyAssembly.FullName, fiPolicyConfig.FullName));
                }

                // We have to create a new component for each of the DLLs we'd like to GAC as publisher policy assemblies
                nGeneratedComponents++;

                // Create the component for the assembly (one per assembly)
                var component = new Component();
                directory.AddChild(component);
                component.Id       = string.Format("{0}.{1}", FileComponentIdPrefix, fiPolicyAssembly.Name);
                component.Guid     = guidcachexml[assemblyxml.Include + " PublisherPolicy"].ToString("B").ToUpper();
                component.DiskId   = Bag.Get <int>(AttributeName.DiskId);
                component.Location = Component.LocationType.local;

                // Register component in the group
                var componentref = new ComponentRef();
                componentgroup.AddChild(componentref);
                componentref.Id = component.Id;

                // Add the assembly file (and make it the key path)
                var fileAssembly = new File();
                component.AddChild(fileAssembly);
                fileAssembly.Id       = string.Format("{0}.{1}", FileIdPrefix, fiPolicyAssembly.Name);
                fileAssembly.Name     = fiPolicyAssembly.Name;
                fileAssembly.KeyPath  = YesNoType.yes;
                fileAssembly.Checksum = YesNoType.yes;
                fileAssembly.Vital    = YesNoType.no;
                fileAssembly.Assembly = File.AssemblyType.net;
                fileAssembly.ReadOnly = YesNoType.yes;

                RegisterTargetFile(fileAssembly.Name, string.Format("Publisher policy assembly file for the {0} product assembly.", assemblyxml.Include), mapTargetFiles);

                // Add the policy config file
                var filePolicy = new File();
                component.AddChild(filePolicy);
                filePolicy.Id       = string.Format("{0}.{1}", FileIdPrefix, fiPolicyConfig.Name);
                filePolicy.Name     = fiPolicyConfig.Name;
                filePolicy.KeyPath  = YesNoType.no;
                filePolicy.Checksum = YesNoType.yes;
                filePolicy.Vital    = YesNoType.no;
                filePolicy.ReadOnly = YesNoType.yes;

                RegisterTargetFile(fileAssembly.Name, string.Format("Publisher policy configuration file for the {0} product assembly.", assemblyxml.Include), mapTargetFiles);
            }

            if (nWasGeneratedComponents == nGeneratedComponents)            // None were actually collected
            {
                throw new InvalidOperationException(string.Format("Could not locate the Publisher Policy assemblies for the “{0}” assembly. The expected full path is “{1}\\{2}”.", assemblyxml.Include, diFolder.FullName, sSatelliteWildcard));
            }
        }
コード例 #23
0
        /// <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="directory">The directory for this path.</param>
        /// <returns>The number of files harvested.</returns>
        private int HarvestDirectory(string path, string relativePath, Wix.Directory directory)
        {
            int fileCount = 0;

            // harvest the child directories
            foreach (string childDirectoryPath in Directory.GetDirectories(path))
            {
                Wix.Directory childDirectory = new Wix.Directory();

                childDirectory.Name       = Path.GetFileName(childDirectoryPath);
                childDirectory.FileSource = childDirectoryPath;

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

                int childFileCount = this.HarvestDirectory(childDirectoryPath, String.Concat(relativePath, childDirectory.Name, "\\"), childDirectory);

                // keep the directory if it contained any files (or empty directories are being kept)
                if (0 < childFileCount || this.keepEmptyDirectories)
                {
                    directory.AddChild(childDirectory);
                }

                fileCount += childFileCount;
            }

            // harvest the files
            string[] files = Directory.GetFiles(path);
            if (0 < files.Length)
            {
                foreach (string filePath in Directory.GetFiles(path))
                {
                    string fileName = Path.GetFileName(filePath);

                    Wix.Component component = new Wix.Component();

                    Wix.File file = this.fileHarvester.HarvestFile(filePath);
                    file.Source = String.Concat(relativePath, fileName);

                    if (this.setUniqueIdentifiers)
                    {
                        file.Id      = this.Core.GenerateIdentifier(FilePrefix, directory.Id, fileName);
                        component.Id = this.Core.GenerateIdentifier(ComponentPrefix, directory.Id, file.Id);
                    }

                    component.AddChild(file);

                    directory.AddChild(component);
                }
            }
            else if (0 == fileCount && this.keepEmptyDirectories)
            {
                Wix.Component component = new Wix.Component();
                component.KeyPath = Wix.YesNoType.yes;

                if (this.setUniqueIdentifiers)
                {
                    component.Id = this.Core.GenerateIdentifier(ComponentPrefix, directory.Id);
                }

                Wix.CreateFolder createFolder = new Wix.CreateFolder();
                component.AddChild(createFolder);

                directory.AddChild(component);
            }

            return(fileCount + files.Length);
        }
コード例 #24
0
        private void HarvestProjectOutputGroupFile(string baseDir, string projectName, string pogName, string pogFileSource, string filePath, string fileName, string link, Wix.IParentElement parentDir, string parentDirId, Wix.Component component, Wix.File file, Dictionary<string, bool> seenList)
        {
            string varFormat = VariableFormat;
            if (this.generateWixVars)
            {
                varFormat = WixVariableFormat;
            }

            if (pogName.Equals("Satellites", StringComparison.OrdinalIgnoreCase))
            {
                Wix.Directory locDirectory = new Wix.Directory();

                locDirectory.Name = Path.GetFileName(Path.GetDirectoryName(Path.GetFullPath(filePath)));
                file.Source = String.Concat(String.Format(CultureInfo.InvariantCulture, varFormat, projectName, pogFileSource), "\\", locDirectory.Name, "\\", Path.GetFileName(filePath));

                if (!seenList.ContainsKey(file.Source))
                {
                    parentDir.AddChild(locDirectory);
                    locDirectory.AddChild(component);
                    component.AddChild(file);
                    seenList.Add(file.Source, true);

                    if (this.setUniqueIdentifiers)
                    {
                        locDirectory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, parentDirId, locDirectory.Name);
                        file.Id = this.Core.GenerateIdentifier(FilePrefix, locDirectory.Id, fileName);
                        component.Id = this.Core.GenerateIdentifier(ComponentPrefix, locDirectory.Id, file.Id);
                    }
                    else
                    {
                        locDirectory.Id = HarvesterCore.GetIdentifierFromName(String.Format(DirectoryIdFormat, (parentDir is Wix.DirectoryRef) ? ((Wix.DirectoryRef)parentDir).Id : parentDirId, locDirectory.Name));
                        file.Id = HarvesterCore.GetIdentifierFromName(String.Format(CultureInfo.InvariantCulture, VSProjectHarvester.FileIdFormat, projectName, pogName, String.Concat(locDirectory.Name, ".", fileName)));
                        component.Id = HarvesterCore.GetIdentifierFromName(String.Format(CultureInfo.InvariantCulture, VSProjectHarvester.ComponentIdFormat, projectName, pogName, String.Concat(locDirectory.Name, ".", fileName)));
                    }
                }
            }
            else
            {
                file.Source = GenerateSourceFilePath(baseDir, projectName, pogFileSource, filePath, link, varFormat);

                if (!seenList.ContainsKey(file.Source))
                {
                    component.AddChild(file);
                    parentDir.AddChild(component);
                    seenList.Add(file.Source, true);

                    if (this.setUniqueIdentifiers)
                    {
                        file.Id = this.Core.GenerateIdentifier(FilePrefix, parentDirId, fileName);
                        component.Id = this.Core.GenerateIdentifier(ComponentPrefix, parentDirId, file.Id);
                    }
                    else
                    {
                        file.Id = HarvesterCore.GetIdentifierFromName(String.Format(CultureInfo.InvariantCulture, VSProjectHarvester.FileIdFormat, projectName, pogName, fileName));
                        component.Id = HarvesterCore.GetIdentifierFromName(String.Format(CultureInfo.InvariantCulture, VSProjectHarvester.ComponentIdFormat, projectName, pogName, fileName));
                    }
                }
            }
        }
コード例 #25
0
        /// <summary>
        /// Mutate a Wix element.
        /// </summary>
        /// <param name="wix">The Wix element to mutate.</param>
        private void MutateWix(Wix.Wix wix)
        {
            if (TemplateType.Fragment != this.templateType)
            {
                if (null != this.rootElement || 0 != this.features.Count)
                {
                    throw new Exception("The template option cannot be used with Feature, Product, or Module elements present.");
                }

                // create a package element although it won't always be used
                Wix.Package package = new Wix.Package();
                if (TemplateType.Module == this.templateType)
                {
                    package.Id = this.GetGuid();
                }
                package.Compressed       = Wix.YesNoType.yes;
                package.InstallerVersion = 200;

                // create the root directory
                Wix.Directory targetDir = new Wix.Directory();
                targetDir.Id   = "TARGETDIR";
                targetDir.Name = "SourceDir";

                // add all previous root directories to the root directory
                foreach (Wix.Directory directory in this.directories)
                {
                    if (!(directory.ParentElement is Wix.Directory || directory.ParentElement is Wix.DirectoryRef))
                    {
                        ((Wix.IParentElement)directory.ParentElement).RemoveChild(directory);
                        targetDir.AddChild(directory);
                    }
                }

                // add children of DirectoryRef/@Id="TARGETROOT" elements to the root directory
                foreach (Wix.DirectoryRef directoryRef in this.directoryRefs)
                {
                    if ("TARGETDIR" == directoryRef.Id)
                    {
                        foreach (Wix.ISchemaElement element in directoryRef.Children)
                        {
                            targetDir.AddChild(element);
                        }
                        ((Wix.IParentElement)directoryRef.ParentElement).RemoveChild(directoryRef);
                    }
                }

                this.directories.Add(targetDir);

                if (TemplateType.Module == this.templateType)
                {
                    Wix.Module module = new Wix.Module();
                    module.Id       = "PUT-MODULE-NAME-HERE";
                    module.Language = "1033";
                    module.Version  = "1.0.0.0";

                    package.Manufacturer = "PUT-COMPANY-NAME-HERE";
                    module.AddChild(package);

                    // add the authoring from the fragments directly into the module
                    foreach (Wix.Fragment fragment in wix.Children)
                    {
                        foreach (Wix.ISchemaElement element in fragment.Children)
                        {
                            module.AddChild(element);
                        }
                    }

                    foreach (Wix.Fragment fragment in wix.Children)
                    {
                        wix.RemoveChild(fragment);
                    }

                    module.AddChild(targetDir);

                    wix.AddChild(module);
                    this.rootElement = module;
                }
                else // product
                {
                    Wix.Product product = new Wix.Product();
                    product.Id           = this.GetGuid();
                    product.Language     = "1033";
                    product.Manufacturer = "PUT-COMPANY-NAME-HERE";
                    product.Name         = "PUT-PRODUCT-NAME-HERE";
                    product.UpgradeCode  = this.GetGuid();
                    product.Version      = "1.0.0.0";

                    product.AddChild(package);

                    Wix.Media media = new Wix.Media();
                    media.Id       = 1;
                    media.Cabinet  = "product.cab";
                    media.EmbedCab = Wix.YesNoType.yes;
                    product.AddChild(media);

                    Wix.Feature feature = new Wix.Feature();
                    feature.Id    = "ProductFeature";
                    feature.Title = "PUT-FEATURE-TITLE-HERE";
                    feature.Level = 1;
                    product.AddChild(feature);
                    this.features.Add(feature);

                    // add the authoring from the fragments directly into the product
                    foreach (Wix.Fragment fragment in wix.Children)
                    {
                        foreach (Wix.ISchemaElement element in fragment.Children)
                        {
                            product.AddChild(element);
                        }
                    }

                    foreach (Wix.Fragment fragment in wix.Children)
                    {
                        wix.RemoveChild(fragment);
                    }

                    product.AddChild(targetDir);

                    wix.AddChild(product);
                    this.rootElement = product;
                }
            }
        }
コード例 #26
0
ファイル: FileHarvester.cs プロジェクト: zooba/wix3
        /// <summary>
        /// Harvest a file.
        /// </summary>
        /// <param name="argument">The path of the file.</param>
        /// <returns>A harvested file.</returns>
        public override Wix.Fragment[] Harvest(string argument)
        {
            if (null == argument)
            {
                throw new ArgumentNullException("argument");
            }

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

            string fullPath = Path.GetFullPath(argument);

            Wix.DirectoryRef directoryRef = new Wix.DirectoryRef();
            directoryRef.Id = this.rootedDirectoryRef;

            Wix.File file = this.HarvestFile(fullPath);

            if (!this.suppressRootDirectory)
            {
                file.Source = String.Concat("SourceDir\\", Path.GetFileName(Path.GetDirectoryName(fullPath)), "\\", Path.GetFileName(fullPath));
            }

            Wix.Component component = new Wix.Component();
            component.AddChild(file);

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

            if (this.suppressRootDirectory)
            {
                directoryRef.AddChild(component);
            }
            else
            {
                string directoryPath = Path.GetDirectoryName(Path.GetFullPath(argument));
                directory.Name = Path.GetFileName(directoryPath);

                if (this.setUniqueIdentifiers)
                {
                    directory.Id = this.Core.GenerateIdentifier(DirectoryPrefix, directoryRef.Id, directory.Name);
                }
                directory.AddChild(component);
                directoryRef.AddChild(directory);
            }

            if (this.setUniqueIdentifiers)
            {
                file.Id = this.Core.GenerateIdentifier(FilePrefix, (this.suppressRootDirectory) ? directoryRef.Id : directory.Id, Path.GetFileName(file.Source));
                component.Id = this.Core.GenerateIdentifier(ComponentPrefix, (this.suppressRootDirectory) ? directoryRef.Id : directory.Id, file.Id);
            }

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

            return new Wix.Fragment[] { fragment };
        }
コード例 #27
0
        /// <summary>
        /// Builds a setup package to the specified output path.
        /// </summary>
        /// <param name="outputPath">Location to build the setup package to.</param>
        /// <param name="outputSourcePath">Optional path where the package's .wxs file will be written.</param>
        public bool Build(string outputPath, string outputSourcePath)
        {
            this.buildError = null; // clear out any previous errors

            int currentProgress = 0;
            int totalProgress   = 7;

            // calculate the upper progress
            if (outputSourcePath != null)
            {
                ++totalProgress;
            }
            if (this.previousPackagePath != null)
            {
                ++totalProgress;
            }

            this.VerifyRequiredInformation();

            if (!this.OnProgress(currentProgress++, totalProgress, "Initialized package builder..."))
            {
                return(false);
            }

            // Calculate where everything is going
            string localSetupExe  = outputPath;
            string localSetupFeed = Path.Combine(Path.GetDirectoryName(outputPath), Path.GetFileName(this.updateUrl.AbsolutePath));

            Uri urlSetupExe  = new Uri(this.updateUrl, Path.GetFileName(localSetupExe));
            Uri urlSetupFeed = new Uri(this.updateUrl, Path.GetFileName(localSetupFeed));

            Guid    previousUpgradeCode = Guid.Empty;
            Version previousVersion     = null;
            Uri     previousSetupFeed   = null;

            // if a previous package was provided, go read the key information out of it now
            if (this.previousPackagePath != null)
            {
                if (!this.OnProgress(currentProgress++, totalProgress, "Reading previous package..."))
                {
                    return(false);
                }

                this.ReadPreviousPackage(this.previousPackagePath, out previousUpgradeCode, out previousVersion, out previousSetupFeed);
            }

            //
            // if a upgrade code and/or version has not been specified use one
            // from the previous package or create new.
            //
            if (this.upgradeCode == Guid.Empty)
            {
                if (previousUpgradeCode == Guid.Empty)
                {
                    this.upgradeCode = Guid.NewGuid();
                }
                else
                {
                    this.upgradeCode = previousUpgradeCode;
                }
            }

            if (this.version == null)
            {
                if (previousVersion == null)
                {
                    FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(Path.Combine(this.applicationRoot.Content, this.applicationEntry.Content));
                    this.version = new Version(fileVersionInfo.FileVersion);
                }
                else
                {
                    this.version = previousVersion;
                }
            }

            // verify that new data is okay when compared to previous package
            if (previousUpgradeCode != Guid.Empty && previousUpgradeCode != this.upgradeCode)
            {
                this.OnMessage(ClickThroughErrors.UpgradeCodeChanged(previousUpgradeCode, this.upgradeCode));
            }
            if (previousVersion != null && previousVersion >= this.version)
            {
                this.OnMessage(ClickThroughErrors.NewVersionIsNotGreater(previousVersion, this.version));
            }

            if (this.buildError != null)
            {
                throw new InvalidOperationException(String.Format(this.buildError.ResourceManager.GetString(this.buildError.ResourceName), this.buildError.MessageArgs));
            }
            else if (!this.OnProgress(currentProgress++, totalProgress, "Processing package information..."))
            {
                return(false);
            }

            // Product information
            Application application = new Application();

            application.Product.Id           = Guid.NewGuid().ToString();
            application.Product.Language     = "1033";
            application.Product.Manufacturer = this.manufacturerName.Content;
            application.Product.Name         = this.applicationName.Content;
            application.Package.Description  = this.description.Content;
            application.Product.UpgradeCode  = this.upgradeCode.ToString();
            application.Product.Version      = this.version.ToString();

            Wix.WixVariable variable = new Wix.WixVariable();
            variable       = new Wix.WixVariable();
            variable.Id    = "ProductName";
            variable.Value = application.Product.Name;
            application.Product.AddChild(variable);

            variable       = new Wix.WixVariable();
            variable.Id    = "ProductCode";
            variable.Value = application.Product.Id;
            application.Product.AddChild(variable);

            variable       = new Wix.WixVariable();
            variable.Id    = "ProductVersion";
            variable.Value = application.Product.Version;
            application.Product.AddChild(variable);

            variable       = new Wix.WixVariable();
            variable.Id    = "ShortcutFileId";
            variable.Value = "todoFileIdHere";
            application.Product.AddChild(variable);

            // Upgrade logic
            Wix.Upgrade upgrade = new Wix.Upgrade();
            upgrade.Id = application.Product.UpgradeCode;
            application.Product.AddChild(upgrade);

            Wix.UpgradeVersion minUpgrade = new Wix.UpgradeVersion();
            minUpgrade.Minimum    = application.Product.Version;
            minUpgrade.OnlyDetect = Wix.YesNoType.yes;
            minUpgrade.Property   = "NEWERVERSIONDETECTED";
            upgrade.AddChild(minUpgrade);

            Wix.UpgradeVersion maxUpgrade = new Wix.UpgradeVersion();
            maxUpgrade.Maximum        = application.Product.Version;
            maxUpgrade.IncludeMaximum = Wix.YesNoType.no;
            maxUpgrade.Property       = "OLDERVERSIONBEINGUPGRADED";
            upgrade.AddChild(maxUpgrade);

            // Update Feed
            Wix.Property property = new Wix.Property();
            property.Id    = "ARPURLUPDATEINFO";
            property.Value = urlSetupFeed.AbsoluteUri;
            application.Product.AddChild(property);

#if false
            // Directory tree
            Wix.DirectoryRef applicationCacheRef = new Wix.DirectoryRef();
            applicationCacheRef.Id = "ApplicationsCacheFolder";
            application.Product.AddChild(applicationCacheRef);
#endif

            Wix.DirectoryRef directoryRef = new Wix.DirectoryRef();
            directoryRef.Id = "ApplicationsFolder";
            application.Product.AddChild(directoryRef);

            this.applicationRootDirectory.Name = String.Concat(application.Product.UpgradeCode, "v", application.Product.Version);
            directoryRef.AddChild(this.applicationRootDirectory);

#if false
            // System registry keys
            Wix.Component registryComponent = new Wix.Component();
            registryComponent.Id   = "SystemVersionRegistryKeyComponent";
            registryComponent.Guid = Guid.NewGuid().ToString();
            directoryRef.AddChild(registryComponent);

            Wix.Registry productRegKey = new Wix.Registry();
            productRegKey.Root   = Wix.RegistryRootType.HKCU;
            productRegKey.Key    = @"Software\WiX\ClickThrough\Applications\[UpgradeCode]";
            productRegKey.Action = Wix.Registry.ActionType.createKeyAndRemoveKeyOnUninstall;
            registryComponent.AddChild(productRegKey);

            Wix.Registry versionRegKey = new Wix.Registry();
            versionRegKey.Name  = "Version";
            versionRegKey.Type  = Wix.Registry.TypeType.@string;
            versionRegKey.Value = "[ProductVersion]";
            productRegKey.AddChild(versionRegKey);

            Wix.Registry sourceRegKey = new Wix.Registry();
            sourceRegKey.Name  = "UpdateInfoSource";
            sourceRegKey.Type  = Wix.Registry.TypeType.@string;
            sourceRegKey.Value = "[ARPURLUPDATEINFO]";
            productRegKey.AddChild(sourceRegKey);

            // Shortcut
            Wix.DirectoryRef programMenuRef = new Wix.DirectoryRef();
            programMenuRef.Id = "ProgramMenuFolder";
            Wix.Directory shortcutsDirectory = new Wix.Directory();
            shortcutsDirectory.Id       = "ThisAppShortcuts";
            shortcutsDirectory.LongName = application.Product.Name;
            shortcutsDirectory.Name     = "AppSCDir";
            programMenuRef.AddChild(shortcutsDirectory);
            application.Product.AddChild(programMenuRef);

            Wix.Component shortcutsComponent = new Wix.Component();
            shortcutsComponent.Id      = "ThisApplicationShortcutComponent";
            shortcutsComponent.Guid    = Guid.NewGuid().ToString();
            shortcutsComponent.KeyPath = Wix.YesNoType.yes;
            shortcutsDirectory.AddChild(shortcutsComponent);

            Wix.CreateFolder shortcutsCreateFolder = new Wix.CreateFolder();
            shortcutsComponent.AddChild(shortcutsCreateFolder);

            Wix.Shortcut shortcut = this.GetShortcut(this.applicationEntry.Content, rootDirectory, shortcutsDirectory);
            shortcutsComponent.AddChild(shortcut);

            // Remove cached MSI file.
            Wix.Component removeComponent = new Wix.Component();
            removeComponent.Id      = "ThisApplicationRemoveComponent";
            removeComponent.Guid    = Guid.NewGuid().ToString();
            removeComponent.KeyPath = Wix.YesNoType.yes;
            applicationCacheRef.AddChild(removeComponent);

            Wix.RemoveFile cacheRemoveFile = new Wix.RemoveFile();
            cacheRemoveFile.Id        = "ThisApplicationRemoveCachedMsi";
            cacheRemoveFile.Directory = "ApplicationsCacheFolder";
            cacheRemoveFile.Name      = "unknown.msi";
            cacheRemoveFile.LongName  = String.Concat("{", application.Product.Id.ToUpper(CultureInfo.InvariantCulture), "}v", application.Version.ToString(), ".msi");
            cacheRemoveFile.On        = Wix.RemoveFile.OnType.uninstall;
            removeComponent.AddChild(cacheRemoveFile);

            Wix.RemoveFile cacheRemoveFolder = new Wix.RemoveFile();
            cacheRemoveFolder.Id        = "ThisApplicationRemoveCacheFolder";
            cacheRemoveFolder.Directory = "ApplicationsCacheFolder";
            cacheRemoveFolder.On        = Wix.RemoveFile.OnType.uninstall;
            removeComponent.AddChild(cacheRemoveFolder);

            Wix.RemoveFile applicationRemoveFolder = new Wix.RemoveFile();
            applicationRemoveFolder.Id        = "ThisApplicationRemoveApplicationsFolder";
            applicationRemoveFolder.Directory = "ApplicationsFolder";
            applicationRemoveFolder.On        = Wix.RemoveFile.OnType.uninstall;
            removeComponent.AddChild(applicationRemoveFolder);
#endif
            // Feature tree
            Wix.FeatureRef applicationFeatureRef = new Wix.FeatureRef();
            applicationFeatureRef.Id = "ApplicationFeature";
            application.Product.AddChild(applicationFeatureRef);

#if false
            Wix.Feature applicationFeature = new Wix.Feature();
            applicationFeature.Id             = "ApplicationFeature";
            applicationFeature.Display        = "expand";
            applicationFeature.Level          = 1;
            applicationFeature.Absent         = Wix.Feature.AbsentType.disallow;
            applicationFeature.AllowAdvertise = Wix.Feature.AllowAdvertiseType.yes;
            applicationFeature.InstallDefault = Wix.Feature.InstallDefaultType.local;
            applicationFeature.TypicalDefault = Wix.Feature.TypicalDefaultType.install;
            application.Product.AddChild(applicationFeature);

            Wix.ComponentRef shortcutsComponentRef = new Wix.ComponentRef();
            shortcutsComponentRef.Id = shortcutsComponent.Id;
            applicationFeature.AddChild(shortcutsComponentRef);

            Wix.ComponentRef removeComponentRef = new Wix.ComponentRef();
            removeComponentRef.Id = removeComponent.Id;
            applicationFeature.AddChild(removeComponentRef);
#endif

            Wix.ComponentRef[] componentRefs = this.GetComponentRefs(this.applicationRootDirectory);
            foreach (Wix.ComponentRef componentRef in componentRefs)
            {
                applicationFeatureRef.AddChild(componentRef);
            }

            if (!this.OnProgress(currentProgress++, totalProgress, "Serializing package information into XML..."))
            {
                return(false);
            }

            // serialize to an xml string
            string xml;
            using (StringWriter sw = new StringWriter())
            {
                XmlTextWriter writer = null;
                try
                {
                    writer = new XmlTextWriter(sw);

                    application.WixRoot.OutputXml(writer);

                    xml = sw.ToString();
                }
                finally
                {
                    if (writer != null)
                    {
                        writer.Close();
                    }
                }
            }

            // load the xml into a document
            XmlDocument sourceDoc = new XmlDocument();
            sourceDoc.LoadXml(xml);

            if (outputSourcePath != null)
            {
                if (!this.OnProgress(currentProgress++, totalProgress, "Saving .wxs file..."))
                {
                    return(false);
                }

                sourceDoc.Save(outputSourcePath);
            }

            // generate the MSI, create the setup.exe, and generate the RSS feed.
            string outputMsi = null;
            try
            {
                outputMsi = Path.GetTempFileName();

                if (!this.OnProgress(currentProgress++, totalProgress, "Generating .msi file..."))
                {
                    return(false);
                }

                this.GenerateMsi(sourceDoc, outputMsi);
                if (this.buildError != null)
                {
                    throw new InvalidOperationException(String.Format(this.buildError.ResourceManager.GetString(this.buildError.ResourceName), this.buildError.MessageArgs));
                }

                string assemblyPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

                if (!this.OnProgress(currentProgress++, totalProgress, "Generating setup bootstrapper..."))
                {
                    return(false);
                }

                /*
                 * NativeMethods.CREATE_SETUP_PACKAGE[] createSetup = new Microsoft.Tools.WindowsInstallerXml.ClickThrough.NativeMethods.CREATE_SETUP_PACKAGE[1];
                 * createSetup[0].fPrivileged = false;
                 * createSetup[0].fCache = true;
                 * createSetup[0].wzSourcePath = outputMsi;
                 *
                 * int hr = NativeMethods.CreateSetup(Path.Combine(assemblyPath, "setup.exe"), createSetup, createSetup.Length, localSetupExe);
                 */
                int hr = NativeMethods.CreateSimpleSetup(Path.Combine(assemblyPath, "setup.exe"), outputMsi, localSetupExe);
                if (hr != 0)
                {
                    this.OnMessage(ClickThroughErrors.FailedSetupExeCreation(Path.Combine(assemblyPath, "setup.exe"), localSetupExe));
                }

                if (!this.OnProgress(currentProgress++, totalProgress, "Generating update feed..."))
                {
                    return(false);
                }
                this.GenerateRssFeed(localSetupFeed, localSetupExe, urlSetupExe, application.Product.Id, application.Product.UpgradeCode, application.Product.Version);
            }
            finally
            {
                this.OnProgress(currentProgress++, totalProgress, "Cleaning up...");
                if (outputMsi != null)
                {
                    File.Delete(outputMsi);
                }
            }

            if (this.buildError != null)
            {
                throw new InvalidOperationException(String.Format(this.buildError.ResourceManager.GetString(this.buildError.ResourceName), this.buildError.MessageArgs));
            }
            else if (!this.OnProgress(currentProgress++, totalProgress, "Package build complete."))
            {
                return(false);
            }

            return(true);
        }
コード例 #28
0
ファイル: UtilMutator.cs プロジェクト: roni8686/wix3
        /// <summary>
        /// Mutate a Wix element.
        /// </summary>
        /// <param name="wix">The Wix element to mutate.</param>
        private void MutateWix(Wix.Wix wix)
        {
            if (TemplateType.Fragment != this.templateType)
            {
                if (null != this.rootElement || 0 != this.features.Count)
                {
                    throw new Exception("The template option cannot be used with Feature, Product, or Module elements present.");
                }

                // create a package element although it won't always be used
                Wix.Package package = new Wix.Package();
                if (TemplateType.Module == this.templateType)
                {
                    package.Id = this.GetGuid();
                }
                else
                {
                    package.Compressed = Wix.YesNoType.yes;
                }

                package.InstallerVersion = 200;

                Wix.Directory targetDir = new Wix.Directory();
                targetDir.Id   = "TARGETDIR";
                targetDir.Name = "SourceDir";

                foreach (Wix.DirectoryRef directoryRef in this.directoryRefs)
                {
                    if (String.Equals(directoryRef.Id, "TARGETDIR", StringComparison.OrdinalIgnoreCase))
                    {
                        Wix.IParentElement parent = directoryRef.ParentElement as Wix.IParentElement;

                        foreach (Wix.ISchemaElement element in directoryRef.Children)
                        {
                            targetDir.AddChild(element);
                        }

                        parent.RemoveChild(directoryRef);

                        if (null != ((Wix.ISchemaElement)parent).ParentElement)
                        {
                            int i = 0;

                            foreach (Wix.ISchemaElement element in parent.Children)
                            {
                                i++;
                            }

                            if (0 == i)
                            {
                                Wix.IParentElement supParent = (Wix.IParentElement)((Wix.ISchemaElement)parent).ParentElement;
                                supParent.RemoveChild((Wix.ISchemaElement)parent);
                            }
                        }

                        break;
                    }
                }

                if (TemplateType.Module == this.templateType)
                {
                    Wix.Module module = new Wix.Module();
                    module.Id       = "PUT-MODULE-NAME-HERE";
                    module.Language = "1033";
                    module.Version  = "1.0.0.0";

                    package.Manufacturer = "PUT-COMPANY-NAME-HERE";
                    module.AddChild(package);
                    module.AddChild(targetDir);

                    wix.AddChild(module);
                    this.rootElement = module;
                }
                else // product
                {
                    Wix.Product product = new Wix.Product();
                    product.Id           = this.GetGuid();
                    product.Language     = "1033";
                    product.Manufacturer = "PUT-COMPANY-NAME-HERE";
                    product.Name         = "PUT-PRODUCT-NAME-HERE";
                    product.UpgradeCode  = this.GetGuid();
                    product.Version      = "1.0.0.0";
                    product.AddChild(package);
                    product.AddChild(targetDir);

                    Wix.Media media = new Wix.Media();
                    media.Id       = "1";
                    media.Cabinet  = "product.cab";
                    media.EmbedCab = Wix.YesNoType.yes;
                    product.AddChild(media);

                    Wix.Feature feature = new Wix.Feature();
                    feature.Id    = "ProductFeature";
                    feature.Title = "PUT-FEATURE-TITLE-HERE";
                    feature.Level = 1;
                    product.AddChild(feature);
                    this.features.Add(feature);

                    wix.AddChild(product);
                    this.rootElement = product;
                }
            }
        }
コード例 #29
0
ファイル: PackageBuilder.cs プロジェクト: Jeremiahf/wix3
        /// <summary>
        /// Builds a setup package to the specified output path.
        /// </summary>
        /// <param name="outputPath">Location to build the setup package to.</param>
        /// <param name="outputSourcePath">Optional path where the package's .wxs file will be written.</param>
        public bool Build(string outputPath, string outputSourcePath)
        {
            this.buildError = null; // clear out any previous errors

            int currentProgress = 0;
            int totalProgress = 7;

            // calculate the upper progress
            if (outputSourcePath != null)
            {
                ++totalProgress;
            }
            if (this.previousPackagePath != null)
            {
                ++totalProgress;
            }

            this.VerifyRequiredInformation();

            if (!this.OnProgress(currentProgress++, totalProgress, "Initialized package builder..."))
            {
                return false;
            }

            // Calculate where everything is going
            string localSetupExe = outputPath;
            string localSetupFeed = Path.Combine(Path.GetDirectoryName(outputPath), Path.GetFileName(this.updateUrl.AbsolutePath));

            Uri urlSetupExe = new Uri(this.updateUrl, Path.GetFileName(localSetupExe));
            Uri urlSetupFeed = new Uri(this.updateUrl, Path.GetFileName(localSetupFeed));

            Guid previousUpgradeCode = Guid.Empty;
            Version previousVersion = null;
            Uri previousSetupFeed = null;

            // if a previous package was provided, go read the key information out of it now
            if (this.previousPackagePath != null)
            {
                if (!this.OnProgress(currentProgress++, totalProgress, "Reading previous package..."))
                {
                    return false;
                }

                this.ReadPreviousPackage(this.previousPackagePath, out previousUpgradeCode, out previousVersion, out previousSetupFeed);
            }

            //
            // if a upgrade code and/or version has not been specified use one
            // from the previous package or create new.
            //
            if (this.upgradeCode == Guid.Empty)
            {
                if (previousUpgradeCode == Guid.Empty)
                {
                    this.upgradeCode = Guid.NewGuid();
                }
                else
                {
                    this.upgradeCode = previousUpgradeCode;
                }
            }

            if (this.version == null)
            {
                if (previousVersion == null)
                {
                    FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(Path.Combine(this.applicationRoot.Content, this.applicationEntry.Content));
                    this.version = new Version(fileVersionInfo.FileVersion);
                }
                else
                {
                    this.version = previousVersion;
                }
            }

            // verify that new data is okay when compared to previous package
            if (previousUpgradeCode != Guid.Empty && previousUpgradeCode != this.upgradeCode)
            {
                this.OnMessage(ClickThroughErrors.UpgradeCodeChanged(previousUpgradeCode, this.upgradeCode));
            }
            if (previousVersion != null && previousVersion >= this.version)
            {
                this.OnMessage(ClickThroughErrors.NewVersionIsNotGreater(previousVersion, this.version));
            }

            if (this.buildError != null)
            {
                throw new InvalidOperationException(String.Format(this.buildError.ResourceManager.GetString(this.buildError.ResourceName), this.buildError.MessageArgs));
            }
            else if (!this.OnProgress(currentProgress++, totalProgress, "Processing package information..."))
            {
                return false;
            }

            // Product information
            Application application = new Application();
            application.Product.Id = Guid.NewGuid().ToString();
            application.Product.Language = "1033";
            application.Product.Manufacturer = this.manufacturerName.Content;
            application.Product.Name = this.applicationName.Content;
            application.Package.Description = this.description.Content;
            application.Product.UpgradeCode = this.upgradeCode.ToString();
            application.Product.Version = this.version.ToString();

            Wix.WixVariable variable = new Wix.WixVariable();
            variable = new Wix.WixVariable();
            variable.Id = "ProductName";
            variable.Value = application.Product.Name;
            application.Product.AddChild(variable);

            variable = new Wix.WixVariable();
            variable.Id = "ProductCode";
            variable.Value = application.Product.Id;
            application.Product.AddChild(variable);

            variable = new Wix.WixVariable();
            variable.Id = "ProductVersion";
            variable.Value = application.Product.Version;
            application.Product.AddChild(variable);

            variable = new Wix.WixVariable();
            variable.Id = "ShortcutFileId";
            variable.Value = "todoFileIdHere";
            application.Product.AddChild(variable);

            // Upgrade logic
            Wix.Upgrade upgrade = new Wix.Upgrade();
            upgrade.Id = application.Product.UpgradeCode;
            application.Product.AddChild(upgrade);

            Wix.UpgradeVersion minUpgrade = new Wix.UpgradeVersion();
            minUpgrade.Minimum = application.Product.Version;
            minUpgrade.OnlyDetect = Wix.YesNoType.yes;
            minUpgrade.Property = "NEWERVERSIONDETECTED";
            upgrade.AddChild(minUpgrade);

            Wix.UpgradeVersion maxUpgrade = new Wix.UpgradeVersion();
            maxUpgrade.Maximum = application.Product.Version;
            maxUpgrade.IncludeMaximum = Wix.YesNoType.no;
            maxUpgrade.Property = "OLDERVERSIONBEINGUPGRADED";
            upgrade.AddChild(maxUpgrade);

            // Update Feed
            Wix.Property property = new Wix.Property();
            property.Id = "ARPURLUPDATEINFO";
            property.Value = urlSetupFeed.AbsoluteUri;
            application.Product.AddChild(property);

#if false
            // Directory tree
            Wix.DirectoryRef applicationCacheRef = new Wix.DirectoryRef();
            applicationCacheRef.Id = "ApplicationsCacheFolder";
            application.Product.AddChild(applicationCacheRef);
#endif

            Wix.DirectoryRef directoryRef = new Wix.DirectoryRef();
            directoryRef.Id = "ApplicationsFolder";
            application.Product.AddChild(directoryRef);

            this.applicationRootDirectory.Name = String.Concat(application.Product.UpgradeCode, "v", application.Product.Version);
            directoryRef.AddChild(this.applicationRootDirectory);

#if false
            // System registry keys
            Wix.Component registryComponent = new Wix.Component();
            registryComponent.Id = "SystemVersionRegistryKeyComponent";
            registryComponent.Guid = Guid.NewGuid().ToString();
            directoryRef.AddChild(registryComponent);

            Wix.Registry productRegKey = new Wix.Registry();
            productRegKey.Root = Wix.RegistryRootType.HKCU;
            productRegKey.Key = @"Software\WiX\ClickThrough\Applications\[UpgradeCode]";
            productRegKey.Action = Wix.Registry.ActionType.createKeyAndRemoveKeyOnUninstall; 
            registryComponent.AddChild(productRegKey);

            Wix.Registry versionRegKey = new Wix.Registry();
            versionRegKey.Name = "Version";
            versionRegKey.Type = Wix.Registry.TypeType.@string;
            versionRegKey.Value = "[ProductVersion]";
            productRegKey.AddChild(versionRegKey);

            Wix.Registry sourceRegKey = new Wix.Registry();
            sourceRegKey.Name = "UpdateInfoSource";
            sourceRegKey.Type = Wix.Registry.TypeType.@string;
            sourceRegKey.Value = "[ARPURLUPDATEINFO]";
            productRegKey.AddChild(sourceRegKey);

            // Shortcut
            Wix.DirectoryRef programMenuRef = new Wix.DirectoryRef();
            programMenuRef.Id = "ProgramMenuFolder";
            Wix.Directory shortcutsDirectory = new Wix.Directory();
            shortcutsDirectory.Id = "ThisAppShortcuts";
            shortcutsDirectory.LongName = application.Product.Name;
            shortcutsDirectory.Name = "AppSCDir";
            programMenuRef.AddChild(shortcutsDirectory);
            application.Product.AddChild(programMenuRef);

            Wix.Component shortcutsComponent = new Wix.Component();
            shortcutsComponent.Id = "ThisApplicationShortcutComponent";
            shortcutsComponent.Guid = Guid.NewGuid().ToString();
            shortcutsComponent.KeyPath = Wix.YesNoType.yes;
            shortcutsDirectory.AddChild(shortcutsComponent);

            Wix.CreateFolder shortcutsCreateFolder = new Wix.CreateFolder();
            shortcutsComponent.AddChild(shortcutsCreateFolder);

            Wix.Shortcut shortcut = this.GetShortcut(this.applicationEntry.Content, rootDirectory, shortcutsDirectory);
            shortcutsComponent.AddChild(shortcut);

            // Remove cached MSI file.
            Wix.Component removeComponent = new Wix.Component();
            removeComponent.Id = "ThisApplicationRemoveComponent";
            removeComponent.Guid = Guid.NewGuid().ToString();
            removeComponent.KeyPath = Wix.YesNoType.yes;
            applicationCacheRef.AddChild(removeComponent);

            Wix.RemoveFile cacheRemoveFile = new Wix.RemoveFile();
            cacheRemoveFile.Id = "ThisApplicationRemoveCachedMsi";
            cacheRemoveFile.Directory = "ApplicationsCacheFolder";
            cacheRemoveFile.Name = "unknown.msi";
            cacheRemoveFile.LongName = String.Concat("{", application.Product.Id.ToUpper(CultureInfo.InvariantCulture), "}v", application.Version.ToString(), ".msi");
            cacheRemoveFile.On = Wix.RemoveFile.OnType.uninstall;
            removeComponent.AddChild(cacheRemoveFile);

            Wix.RemoveFile cacheRemoveFolder = new Wix.RemoveFile();
            cacheRemoveFolder.Id = "ThisApplicationRemoveCacheFolder";
            cacheRemoveFolder.Directory = "ApplicationsCacheFolder";
            cacheRemoveFolder.On = Wix.RemoveFile.OnType.uninstall;
            removeComponent.AddChild(cacheRemoveFolder);

            Wix.RemoveFile applicationRemoveFolder = new Wix.RemoveFile();
            applicationRemoveFolder.Id = "ThisApplicationRemoveApplicationsFolder";
            applicationRemoveFolder.Directory = "ApplicationsFolder";
            applicationRemoveFolder.On = Wix.RemoveFile.OnType.uninstall;
            removeComponent.AddChild(applicationRemoveFolder);
#endif
            // Feature tree
            Wix.FeatureRef applicationFeatureRef = new Wix.FeatureRef();
            applicationFeatureRef.Id = "ApplicationFeature";
            application.Product.AddChild(applicationFeatureRef);

#if false
            Wix.Feature applicationFeature = new Wix.Feature();
            applicationFeature.Id = "ApplicationFeature";
            applicationFeature.Display = "expand";
            applicationFeature.Level = 1;
            applicationFeature.Absent = Wix.Feature.AbsentType.disallow;
            applicationFeature.AllowAdvertise = Wix.Feature.AllowAdvertiseType.yes;
            applicationFeature.InstallDefault = Wix.Feature.InstallDefaultType.local;
            applicationFeature.TypicalDefault = Wix.Feature.TypicalDefaultType.install;
            application.Product.AddChild(applicationFeature);

            Wix.ComponentRef shortcutsComponentRef = new Wix.ComponentRef();
            shortcutsComponentRef.Id = shortcutsComponent.Id;
            applicationFeature.AddChild(shortcutsComponentRef);

            Wix.ComponentRef removeComponentRef = new Wix.ComponentRef();
            removeComponentRef.Id = removeComponent.Id;
            applicationFeature.AddChild(removeComponentRef);
#endif

            Wix.ComponentRef[] componentRefs = this.GetComponentRefs(this.applicationRootDirectory);
            foreach (Wix.ComponentRef componentRef in componentRefs)
            {
                applicationFeatureRef.AddChild(componentRef);
            }

            if (!this.OnProgress(currentProgress++, totalProgress, "Serializing package information into XML..."))
            {
                return false;
            }

            // serialize to an xml string
            string xml;
            using (StringWriter sw = new StringWriter())
            {
                XmlTextWriter writer = null;
                try
                {
                    writer = new XmlTextWriter(sw);

                    application.WixRoot.OutputXml(writer);

                    xml = sw.ToString();
                }
                finally
                {
                    if (writer != null)
                    {
                        writer.Close();
                    }
                }
            }

            // load the xml into a document
            XmlDocument sourceDoc = new XmlDocument();
            sourceDoc.LoadXml(xml);

            if (outputSourcePath != null)
            {
                if (!this.OnProgress(currentProgress++, totalProgress, "Saving .wxs file..."))
                {
                    return false;
                }

                sourceDoc.Save(outputSourcePath);
            }

            // generate the MSI, create the setup.exe, and generate the RSS feed.
            string outputMsi = null;
            try
            {
                outputMsi = Path.GetTempFileName();

                if (!this.OnProgress(currentProgress++, totalProgress, "Generating .msi file..."))
                {
                    return false;
                }

                this.GenerateMsi(sourceDoc, outputMsi);
                if (this.buildError != null)
                {
                    throw new InvalidOperationException(String.Format(this.buildError.ResourceManager.GetString(this.buildError.ResourceName), this.buildError.MessageArgs));
                }

                string assemblyPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

                if (!this.OnProgress(currentProgress++, totalProgress, "Generating setup bootstrapper..."))
                {
                    return false;
                }

                /*
                NativeMethods.CREATE_SETUP_PACKAGE[] createSetup = new Microsoft.Tools.WindowsInstallerXml.ClickThrough.NativeMethods.CREATE_SETUP_PACKAGE[1];
                createSetup[0].fPrivileged = false;
                createSetup[0].fCache = true;
                createSetup[0].wzSourcePath = outputMsi;

                int hr = NativeMethods.CreateSetup(Path.Combine(assemblyPath, "setup.exe"), createSetup, createSetup.Length, localSetupExe);
                */
                int hr = NativeMethods.CreateSimpleSetup(Path.Combine(assemblyPath, "setup.exe"), outputMsi, localSetupExe);
                if (hr != 0)
                {
                    this.OnMessage(ClickThroughErrors.FailedSetupExeCreation(Path.Combine(assemblyPath, "setup.exe"), localSetupExe));
                }

                if (!this.OnProgress(currentProgress++, totalProgress, "Generating update feed..."))
                {
                    return false;
                }
                this.GenerateRssFeed(localSetupFeed, localSetupExe, urlSetupExe, application.Product.Id, application.Product.UpgradeCode, application.Product.Version);
            }
            finally
            {
                this.OnProgress(currentProgress++, totalProgress, "Cleaning up...");
                if (outputMsi != null)
                {
                    File.Delete(outputMsi);
                }
            }

            if (this.buildError != null)
            {
                throw new InvalidOperationException(String.Format(this.buildError.ResourceManager.GetString(this.buildError.ResourceName), this.buildError.MessageArgs));
            }
            else if (!this.OnProgress(currentProgress++, totalProgress, "Package build complete."))
            {
                return false;
            }

            return true;
        }