Ejemplo n.º 1
0
        /// <summary>
        /// Saves an output to a path on disk.
        /// </summary>
        /// <param name="path">Path to save output file to on disk.</param>
        /// <param name="binderExtension">If provided, the binder extension is used to bind files into the output.</param>
        /// <param name="wixVariableResolver">The Wix variable resolver.</param>
        /// <param name="tempFilesLocation">Location for temporary files.</param>
        public void Save(string path, BinderExtension binderExtension, WixVariableResolver wixVariableResolver, string tempFilesLocation)
        {
            FileMode fileMode = FileMode.Create;

            // 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();
                }
                fileMode = FileMode.Append;
            }
            else
            {
                Hashtable        cabinets = new Hashtable();
                StringCollection fileIds  = new StringCollection();
                StringCollection files    = new StringCollection();
                int index = 0;

                // resolve paths to files and create the output cabinet file
                foreach (Section section in this.sections)
                {
                    foreach (Table table in section.Tables)
                    {
                        foreach (Row row in table.Rows)
                        {
                            foreach (Field field in row.Fields)
                            {
                                ObjectField objectField = field as ObjectField;

                                if (null != objectField && null != objectField.Data)
                                {
                                    string file      = null;
                                    bool   isDefault = true;

                                    // resolve localization and wix variables
                                    objectField.Data = wixVariableResolver.ResolveVariables(null, row.SourceLineNumbers, (string)objectField.Data, false, ref isDefault);

                                    // do not save the output if errors were found while resolving object paths
                                    if (wixVariableResolver.EncounteredError)
                                    {
                                        return;
                                    }

                                    // file is compressed in a cabinet (and not modified above)
                                    if (null != objectField.CabinetFileId && isDefault)
                                    {
                                        // index cabinets that have not been previously encountered
                                        if (!cabinets.ContainsKey(objectField.BaseUri))
                                        {
                                            Uri    baseUri = new Uri(objectField.BaseUri);
                                            string localFileNameWithoutExtension = Path.GetFileNameWithoutExtension(baseUri.LocalPath);
                                            string extractedDirectoryName        = String.Format(CultureInfo.InvariantCulture, "cab_{0}_{1}", cabinets.Count, localFileNameWithoutExtension);

                                            // index the cabinet file's base URI (source location) and extracted directory
                                            cabinets.Add(objectField.BaseUri, Path.Combine(tempFilesLocation, extractedDirectoryName));
                                        }

                                        // set the path to the file once its extracted from the cabinet
                                        file = Path.Combine((string)cabinets[objectField.BaseUri], objectField.CabinetFileId);
                                    }
                                    else if (null != binderExtension)
                                    {
                                        file = binderExtension.ResolveFile((string)objectField.Data);
                                    }

                                    // add the file to the list of files to go in the cabinet
                                    if (null != file)
                                    {
                                        string cabinetFileId = (index++).ToString(CultureInfo.InvariantCulture);

                                        objectField.CabinetFileId = cabinetFileId;
                                        fileIds.Add(cabinetFileId);

                                        files.Add(file);
                                    }
                                }
                            }
                        }
                    }
                }

                // 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)
                {
                    try
                    {
                        using (WixCreateCab cab = new WixCreateCab(Path.GetFileName(path), Path.GetDirectoryName(path), 0, 0, CompressionLevel.Mszip))
                        {
                            for (int i = 0; i < fileIds.Count; i++)
                            {
                                cab.AddFile(files[i], fileIds[i]);
                            }
                        }
                    }
                    catch (FileNotFoundException e)
                    {
                        throw new WixException(WixErrors.FileNotFound(null, e.FileName));
                    }

                    // append the output xml to the end of the newly created cabinet file
                    fileMode = FileMode.Append;
                }
            }

            // Assure the location to output the xml exists
            Directory.CreateDirectory(Path.GetDirectoryName(path));

            // save the xml
            using (FileStream fs = new FileStream(path, fileMode))
            {
                XmlWriter writer = null;

                try
                {
                    writer = new XmlTextWriter(fs, System.Text.Encoding.UTF8);

                    writer.WriteStartDocument();
                    this.Persist(writer);
                    writer.WriteEndDocument();
                }
                finally
                {
                    if (null != writer)
                    {
                        writer.Close();
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Saves a library to a path on disk.
        /// </summary>
        /// <param name="path">Path to save library file to on disk.</param>
        /// <param name="binderExtension">If provided, the binder extension is used to bind files into the library.</param>
        /// <param name="wixVariableResolver">The Wix variable resolver.</param>
        public void Save(string path, BinderExtension binderExtension, WixVariableResolver wixVariableResolver)
        {
            FileMode         fileMode = FileMode.Create;
            StringCollection fileIds  = new StringCollection();
            StringCollection files    = new StringCollection();
            int index = 0;

            // resolve paths to files and create the library cabinet file
            foreach (Section section in this.sections)
            {
                foreach (Table table in section.Tables)
                {
                    foreach (Row row in table.Rows)
                    {
                        foreach (Field field in row.Fields)
                        {
                            ObjectField objectField = field as ObjectField;

                            if (null != objectField)
                            {
                                if (null != binderExtension && null != objectField.Data)
                                {
                                    string cabinetFileId = (index++).ToString(CultureInfo.InvariantCulture);

                                    objectField.CabinetFileId = cabinetFileId;
                                    fileIds.Add(cabinetFileId);

                                    // resolve wix variables
                                    string resolvedValue = wixVariableResolver.ResolveVariables(null, row.SourceLineNumbers, (string)objectField.Data, false);

                                    files.Add(binderExtension.ResolveFile(resolvedValue));
                                }
                                else // clear out a previous cabinet file id value
                                {
                                    objectField.CabinetFileId = null;
                                }
                            }
                        }
                    }
                }
            }

            // do not save the library if errors were found while resolving object paths
            if (wixVariableResolver.EncounteredError)
            {
                return;
            }

            // create the cabinet file
            if (0 < fileIds.Count)
            {
                try
                {
                    using (WixCreateCab cab = new WixCreateCab(Path.GetFileName(path), Path.GetDirectoryName(path), 0, 0, CompressionLevel.Mszip))
                    {
                        for (int i = 0; i < fileIds.Count; i++)
                        {
                            cab.AddFile(files[i], fileIds[i]);
                        }
                    }
                }
                catch (FileNotFoundException e)
                {
                    throw new WixException(WixErrors.FileNotFound(null, e.FileName));
                }

                // append the library xml to the end of the newly created cabinet file
                fileMode = FileMode.Append;
            }

            // save the xml
            using (FileStream fs = new FileStream(path, fileMode))
            {
                XmlWriter writer = null;

                try
                {
                    writer = new XmlTextWriter(fs, System.Text.Encoding.UTF8);

                    writer.WriteStartDocument();
                    this.Persist(writer);
                    writer.WriteEndDocument();
                }
                finally
                {
                    if (null != writer)
                    {
                        writer.Close();
                    }
                }
            }
        }