string BuildPackageInternal(IProgressStatus monitor, bool debugSymbols, string targetDirectory, string filePath) { AddinDescription conf = registry.GetAddinDescription(monitor, filePath); if (conf == null) { monitor.ReportError("Could not read add-in file: " + filePath, null); return(null); } string basePath = Path.GetDirectoryName(Path.GetFullPath(filePath)); if (targetDirectory == null) { targetDirectory = basePath; } // Generate the file name string name; if (conf.LocalId.Length == 0) { name = Path.GetFileNameWithoutExtension(filePath); } else { name = conf.LocalId; } name = Addin.GetFullId(conf.Namespace, name, conf.Version); name = name.Replace(',', '_').Replace(".__", "."); string outFilePath = Path.Combine(targetDirectory, name) + ".mpack"; ZipOutputStream s = new ZipOutputStream(File.Create(outFilePath)); s.SetLevel(5); // Generate a stripped down description of the add-in in a file, since the complete // description may be declared as assembly attributes XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = false; doc.LoadXml(conf.SaveToXml().OuterXml); CleanDescription(doc.DocumentElement); MemoryStream ms = new MemoryStream(); XmlTextWriter tw = new XmlTextWriter(ms, System.Text.Encoding.UTF8); tw.Formatting = Formatting.Indented; doc.WriteTo(tw); tw.Flush(); byte[] data = ms.ToArray(); var infoEntry = new ZipEntry("addin.info") { Size = data.Length }; s.PutNextEntry(infoEntry); s.Write(data, 0, data.Length); s.CloseEntry(); // Now add the add-in files var files = new HashSet <string> (); files.Add(Path.GetFileName(Util.NormalizePath(filePath))); foreach (string f in conf.AllFiles) { var file = Util.NormalizePath(f); files.Add(file); if (debugSymbols) { if (File.Exists(Path.ChangeExtension(file, ".pdb"))) { files.Add(Path.ChangeExtension(file, ".pdb")); } else if (File.Exists(file + ".mdb")) { files.Add(file + ".mdb"); } } } foreach (var prop in conf.Properties) { try { var file = Util.NormalizePath(prop.Value); if (File.Exists(Path.Combine(basePath, file))) { files.Add(file); } } catch { // Ignore errors } } //add satellite assemblies for assemblies in the list var satelliteFinder = new SatelliteAssemblyFinder(); foreach (var f in files.ToList()) { foreach (var satellite in satelliteFinder.FindSatellites(Path.Combine(basePath, f))) { var relativeSatellite = satellite.Substring(basePath.Length + 1); files.Add(relativeSatellite); } } monitor.Log("Creating package " + Path.GetFileName(outFilePath)); foreach (string file in files) { string fp = Path.Combine(basePath, file); using (FileStream fs = File.OpenRead(fp)) { byte[] buffer = new byte [fs.Length]; fs.Read(buffer, 0, buffer.Length); var fileName = Path.PathSeparator == '\\' ? file.Replace('\\', '/') : file; var entry = new ZipEntry(fileName) { Size = fs.Length }; s.PutNextEntry(entry); s.Write(buffer, 0, buffer.Length); s.CloseEntry(); } } s.Finish(); s.Close(); return(outFilePath); }
string BuildPackageInternal(IProgressStatus monitor, bool debugSymbols, string targetDirectory, string filePath, PackageFormat format) { AddinDescription conf = registry.GetAddinDescription(monitor, filePath); if (conf == null) { monitor.ReportError("Could not read add-in file: " + filePath, null); return(null); } string basePath = Path.GetDirectoryName(Path.GetFullPath(filePath)); if (targetDirectory == null) { targetDirectory = basePath; } // Generate the file name string name; if (conf.LocalId.Length == 0) { name = Path.GetFileNameWithoutExtension(filePath); } else { name = conf.LocalId; } name = Addin.GetFullId(conf.Namespace, name, conf.Version); name = name.Replace(',', '_').Replace(".__", "."); string outFilePath = Path.Combine(targetDirectory, name); switch (format) { case PackageFormat.Mpack: outFilePath += ".mpack"; break; case PackageFormat.Vsix: outFilePath += ".vsix"; break; default: throw new NotSupportedException(format.ToString()); } ZipOutputStream s = new ZipOutputStream(File.Create(outFilePath)); s.SetLevel(5); if (format == PackageFormat.Vsix) { XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = false; doc.LoadXml(conf.SaveToVsixXml().OuterXml); MemoryStream ms = new MemoryStream(); XmlTextWriter tw = new XmlTextWriter(ms, System.Text.Encoding.UTF8); tw.Formatting = Formatting.Indented; doc.WriteTo(tw); tw.Flush(); byte [] data = ms.ToArray(); var infoEntry = new ZipEntry("extension.vsixmanifest") { Size = data.Length }; s.PutNextEntry(infoEntry); s.Write(data, 0, data.Length); s.CloseEntry(); } // Generate a stripped down description of the add-in in a file, since the complete // description may be declared as assembly attributes if (format == PackageFormat.Mpack || format == PackageFormat.Vsix) { XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = false; doc.LoadXml(conf.SaveToXml().OuterXml); CleanDescription(doc.DocumentElement); MemoryStream ms = new MemoryStream(); XmlTextWriter tw = new XmlTextWriter(ms, System.Text.Encoding.UTF8); tw.Formatting = Formatting.Indented; doc.WriteTo(tw); tw.Flush(); byte [] data = ms.ToArray(); var infoEntry = new ZipEntry("addin.info") { Size = data.Length }; s.PutNextEntry(infoEntry); s.Write(data, 0, data.Length); s.CloseEntry(); } // Now add the add-in files var files = new HashSet <string> (); files.Add(Path.GetFileName(Util.NormalizePath(filePath))); foreach (string f in conf.AllFiles) { var file = Util.NormalizePath(f); files.Add(file); if (debugSymbols) { if (File.Exists(Path.ChangeExtension(file, ".pdb"))) { files.Add(Path.ChangeExtension(file, ".pdb")); } else if (File.Exists(file + ".mdb")) { files.Add(file + ".mdb"); } } } foreach (var prop in conf.Properties) { try { var file = Util.NormalizePath(prop.Value); if (File.Exists(Path.Combine(basePath, file))) { files.Add(file); } } catch { // Ignore errors } } //add satellite assemblies for assemblies in the list var satelliteFinder = new SatelliteAssemblyFinder(); foreach (var f in files.ToList()) { foreach (var satellite in satelliteFinder.FindSatellites(Path.Combine(basePath, f))) { var relativeSatellite = satellite.Substring(basePath.Length + 1); files.Add(relativeSatellite); } } monitor.Log("Creating package " + Path.GetFileName(outFilePath)); foreach (string file in files) { string fp = Path.Combine(basePath, file); using (FileStream fs = File.OpenRead(fp)) { byte[] buffer = new byte [fs.Length]; fs.Read(buffer, 0, buffer.Length); var fileName = Path.DirectorySeparatorChar == '\\' ? file.Replace('\\', '/') : file; var entry = new ZipEntry(fileName) { Size = fs.Length }; s.PutNextEntry(entry); s.Write(buffer, 0, buffer.Length); s.CloseEntry(); } } if (format == PackageFormat.Vsix) { files.Add("addin.info"); files.Add("extension.vsixmanifest"); XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = false; XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null); XmlElement root = doc.DocumentElement; doc.InsertBefore(xmlDeclaration, root); HashSet <string> alreadyAddedExtensions = new HashSet <string> (); var typesEl = doc.CreateElement("Types"); typesEl.SetAttribute("xmlns", "http://schemas.openxmlformats.org/package/2006/content-types"); foreach (var file in files) { var extension = Path.GetExtension(file); if (string.IsNullOrEmpty(extension)) { continue; } if (extension.StartsWith(".", StringComparison.Ordinal)) { extension = extension.Substring(1); } if (alreadyAddedExtensions.Contains(extension)) { continue; } alreadyAddedExtensions.Add(extension); var typeEl = doc.CreateElement("Default"); typeEl.SetAttribute("Extension", extension); typeEl.SetAttribute("ContentType", GetContentType(extension)); typesEl.AppendChild(typeEl); } doc.AppendChild(typesEl); MemoryStream ms = new MemoryStream(); XmlTextWriter tw = new XmlTextWriter(ms, System.Text.Encoding.UTF8); tw.Formatting = Formatting.Indented; doc.WriteTo(tw); tw.Flush(); byte [] data = ms.ToArray(); var infoEntry = new ZipEntry("[Content_Types].xml") { Size = data.Length }; s.PutNextEntry(infoEntry); s.Write(data, 0, data.Length); s.CloseEntry(); } s.Finish(); s.Close(); return(outFilePath); }