Ejemplo n.º 1
0
        /// <summary>
        /// Saves an outputs cab to a path on disk.
        /// </summary>
        /// <param name="path">Path to save outputs cab to on disk.</param>
        /// <param name="binderFileManager">If provided, the binder file manager is used to bind files into the outputs cab.</param>
        /// <param name="wixVariableResolver">The Wix variable resolver.</param>
        /// <param name="tempFilesLocation">Location for temporary files.</param>
        /// <returns>Returns true if a cabinet existed or was created, false otherwise.</returns>
        public bool SaveCab(string path, BinderFileManager binderFileManager, WixVariableResolver wixVariableResolver, string tempFilesLocation)
        {
            bool hasCab = false;

            // Check if there was a cab on the wixout when it was created
            if (null != this.cabPath)
            {
                // There was already a cab on the wixout when it was loaded. Reuse that one.
                File.Copy(this.cabPath, path, true);
                if (null != this.tempFileCollection)
                {
                    this.tempFileCollection.Delete();
                }
                hasCab = true;
            }
            else
            {
                int              index    = 0;
                Hashtable        cabinets = new Hashtable();
                StringCollection fileIds  = new StringCollection();
                StringCollection files    = new StringCollection();

                if (null != tempFilesLocation)
                {
                    // resolve paths to files and create the output cabinet file
                    if (0 == this.sections.Count)
                    {
                        Output.ResolveSectionFiles(this.tables, binderFileManager, wixVariableResolver, tempFilesLocation, cabinets, fileIds, files, ref index);
                    }
                    else
                    {
                        foreach (Section section in this.sections)
                        {
                            Output.ResolveSectionFiles(section.Tables, binderFileManager, wixVariableResolver, tempFilesLocation, cabinets, fileIds, files, ref index);
                        }
                    }
                }

                // extract files that come from cabinet files
                if (0 < cabinets.Count)
                {
                    // ensure the temporary directory exists
                    Directory.CreateDirectory(tempFilesLocation);

                    foreach (DictionaryEntry cabinet in cabinets)
                    {
                        Uri    baseUri = new Uri((string)cabinet.Key);
                        string localPath;

                        if ("embeddedresource" == baseUri.Scheme)
                        {
                            int    bytesRead;
                            byte[] buffer = new byte[512];

                            string   originalLocalPath = Path.GetFullPath(baseUri.LocalPath.Substring(1));
                            string   resourceName      = baseUri.Fragment.Substring(1);
                            Assembly assembly          = Assembly.LoadFile(originalLocalPath);

                            localPath = String.Concat(cabinet.Value, ".cab");

                            using (FileStream fs = File.OpenWrite(localPath))
                            {
                                using (Stream resourceStream = assembly.GetManifestResourceStream(resourceName))
                                {
                                    while (0 < (bytesRead = resourceStream.Read(buffer, 0, buffer.Length)))
                                    {
                                        fs.Write(buffer, 0, bytesRead);
                                    }
                                }
                            }
                        }
                        else // normal file
                        {
                            localPath = baseUri.LocalPath;
                        }

                        // extract the cabinet's files into a temporary directory
                        Directory.CreateDirectory((string)cabinet.Value);

                        using (WixExtractCab extractCab = new WixExtractCab())
                        {
                            extractCab.Extract(localPath, (string)cabinet.Value);
                        }
                    }
                }

                // create the cabinet file
                if (0 < fileIds.Count)
                {
                    using (WixCreateCab cab = new WixCreateCab(Path.GetFileName(path), Path.GetDirectoryName(path), fileIds.Count, 0, 0, CompressionLevel.Mszip))
                    {
                        for (int i = 0; i < fileIds.Count; i++)
                        {
                            cab.AddFile(files[i], fileIds[i]);
                        }
                        cab.Complete();
                    }

                    // append the output xml to the end of the newly created cabinet file
                    hasCab = true;
                }
            }

            return(hasCab);
        }