/// <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(); } } } }
/// <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(); } } } }