From 8f154ebf482b09438877c24c740743a6c7c5cfc1 Mon Sep 17 00:00:00 2001 From: mschill Date: Thu, 21 Aug 2025 14:25:53 -0400 Subject: [PATCH] C2025-001 Replace 3rd party Ionic.zip component --- .../VEPROMS User Interface/VEPROMS_UI.csproj | 6 +- .../VEPROMS User Interface/dlgExportImport.cs | 427 +++++++++--------- 2 files changed, 223 insertions(+), 210 deletions(-) diff --git a/PROMS/VEPROMS User Interface/VEPROMS_UI.csproj b/PROMS/VEPROMS User Interface/VEPROMS_UI.csproj index 593c1005..e6a0cace 100644 --- a/PROMS/VEPROMS User Interface/VEPROMS_UI.csproj +++ b/PROMS/VEPROMS User Interface/VEPROMS_UI.csproj @@ -111,10 +111,6 @@ False ..\..\..\..\3rdPartyLibraries\DotNetBar\DotNetBar4.6Build\DevComponents.DotNetBar2.dll - - False - ..\..\..\..\3rdPartyLibraries\Ionic\Ionic.Zip.dll - ..\..\..\..\3rdPartyLibraries\RtfConverter\bin\Debug\Itenso.Rtf.Interpreter.dll @@ -133,6 +129,8 @@ + + diff --git a/PROMS/VEPROMS User Interface/dlgExportImport.cs b/PROMS/VEPROMS User Interface/dlgExportImport.cs index df2e4acb..da772d9d 100644 --- a/PROMS/VEPROMS User Interface/dlgExportImport.cs +++ b/PROMS/VEPROMS User Interface/dlgExportImport.cs @@ -7,7 +7,7 @@ using Volian.Controls.Library; using Volian.Base.Library; using System.Xml; using System.IO; -using Ionic.Zip; +using System.IO.Compression; using System.Text.RegularExpressions; using JR.Utils.GUI.Forms; using System.Linq; @@ -188,14 +188,13 @@ namespace VEPROMS if (MyFolder != null) { sfd.FileName = string.Format("{0}-{1}.expx", Database.ActiveDatabase, MyFolder.Name); - if (sfd.ShowDialog(this) == DialogResult.OK && sfd.FileName != string.Empty) - { - txtExport.Text = sfd.FileName; - if (File.Exists(txtExport.Text)) - File.Delete(txtExport.Text); - MyExpxZipFile = new ZipFile(txtExport.Text, Encoding.UTF8); - MyExpxZipFile.Save(); - } + if (sfd.ShowDialog(this) == DialogResult.OK && sfd.FileName != string.Empty) + { + txtExport.Text = sfd.FileName; + if (File.Exists(txtExport.Text)) + File.Delete(txtExport.Text); + MyExpZipFileName = txtExport.Text; + } } else if (MyProcedure != null) { @@ -211,8 +210,8 @@ namespace VEPROMS else lblExportStatus.Text = "Awaiting Export File Name:"; } - private ZipFile MyExpxZipFile = null; - private ZipFile MyImpxZipFile = null; + private string MyExpZipFileName = null; + private string MyImpZipFileName = null; private DateTime MyStart; private bool successfullExport = true; @@ -892,84 +891,94 @@ namespace VEPROMS } private bool LoadImportDataDocument() { - floatFoldout = new Dictionary(); - ZipEntry ze = MyExpxZipFile[0]; - string fn = PEIPath + @"\" + ze.FileName; - ze.Extract(PEIPath, ExtractExistingFileAction.OverwriteSilently); - XmlDocument xd = new XmlDocument(); - xd.Load(fn); - bool didImp = LoadFormats(xd, "folder/formats/format"); - if (!didImp) + using (FileStream zipToOpen = new FileStream(MyExpZipFileName, FileMode.OpenOrCreate)) { - this.Cursor = Cursors.Default; - this.btnImport.Enabled = true; // allow user to select a different export file to import - this.btnDoImport.Enabled = true; // allow user to change mind and perform the import - return false; // Return False to Indicate that the Import did not succeed - } - string name = xd.DocumentElement.Attributes.GetNamedItem("name").InnerText; - Folder ff = AddFolder(Folder.Get(MyFolder.FolderID), xd, name); - if (ff == null) - { - // C2020-032: Import Procedure set when existing name exists, allow user to import with 'Copy (#) of'. - // This is similar functionality to the import of a procedure without the overwrite part. - string msg = string.Format("The procedure set you are importing, {0}, already exists.\n\nDo you want to import {0} as a COPY of the existing set?\n\nThis will prefix the name with \"Copy (#) of\"", name); - DialogResult dr = MessageBox.Show(this, msg, "Create Copy Of Existing Procedure Set", MessageBoxButtons.OKCancel, MessageBoxIcon.Stop); - if (dr == DialogResult.OK) + using (ZipArchive MyExpxZipFile = new ZipArchive(zipToOpen, ZipArchiveMode.Update)) { - string number = ""; - int max = -1; - // get maximum number of existing copies. - foreach (FolderInfo fi in MyFolder.ChildFolders) + floatFoldout = new Dictionary(); + ZipArchiveEntry ze = MyExpxZipFile.Entries[0]; + if (!Directory.Exists(Path.Combine(PEIPath, "folder"))) + Directory.CreateDirectory(Path.Combine(PEIPath, "folder")); + string fn = Path.Combine(PEIPath, "folder", ze.Name); + ze.ExtractToFile(fn, true); + XmlDocument xd = new XmlDocument(); + xd.Load(fn); + bool didImp = LoadFormats(xd, "folder/formats/format"); + if (!didImp) { - int indx = fi.Name.IndexOf("Copy ("); - if (indx > -1) - { - int indxend = fi.Name.IndexOf(")", indx); - if (indxend > indx) - { - string tmp = fi.Name.Substring(indx + 6, indxend - (indx + 6)); - int ii = Convert.ToInt32(tmp); - if (ii > max) max = ii; - } - } + this.Cursor = Cursors.Default; + this.btnImport.Enabled = true; // allow user to select a different export file to import + this.btnDoImport.Enabled = true; // allow user to change mind and perform the import + return false; // Return False to Indicate that the Import did not succeed } - number = max > -1 ? (max + 1).ToString() : "1"; - name = string.Format("Copy ({0}) of {1}", number, name); + string name = xd.DocumentElement.Attributes.GetNamedItem("name").InnerText; + Folder ff = AddFolder(Folder.Get(MyFolder.FolderID), xd, name); + if (ff == null) + { + // C2020-032: Import Procedure set when existing name exists, allow user to import with 'Copy (#) of'. + // This is similar functionality to the import of a procedure without the overwrite part. + string msg = string.Format("The procedure set you are importing, {0}, already exists.\n\nDo you want to import {0} as a COPY of the existing set?\n\nThis will prefix the name with \"Copy (#) of\"", name); + DialogResult dr = MessageBox.Show(this, msg, "Create Copy Of Existing Procedure Set", MessageBoxButtons.OKCancel, MessageBoxIcon.Stop); + if (dr == DialogResult.OK) + { + string number = ""; + int max = -1; + // get maximum number of existing copies. + foreach (FolderInfo fi in MyFolder.ChildFolders) + { + int indx = fi.Name.IndexOf("Copy ("); + if (indx > -1) + { + int indxend = fi.Name.IndexOf(")", indx); + if (indxend > indx) + { + string tmp = fi.Name.Substring(indx + 6, indxend - (indx + 6)); + int ii = Convert.ToInt32(tmp); + if (ii > max) max = ii; + } + } + } + number = max > -1 ? (max + 1).ToString() : "1"; + name = string.Format("Copy ({0}) of {1}", number, name); - ff = AddFolder(Folder.Get(MyFolder.FolderID), xd, name); + ff = AddFolder(Folder.Get(MyFolder.FolderID), xd, name); + } + else + return false; + } + _MyNewFolder = FolderInfo.Get(ff.FolderID); + AddAnnotationTypes(xd); + DocVersionInfo dvi = AddDocVersion(ff, xd); + MyDocVersion = dvi; + xd = null; + lblImportStatus.Text = "Creating Procedures..."; + Application.DoEvents(); + ProcedureInfo pi = null; + pbImportProcedure.Value = 0; + pbImportProcedure.Maximum = MyExpxZipFile.Entries.Count - 1; + if (!Directory.Exists(Path.Combine(PEIPath, "procedures"))) + Directory.CreateDirectory(Path.Combine(PEIPath, "procedures")); + for (int i = 1; i < MyExpxZipFile.Entries.Count; i++) + { + ze = MyExpxZipFile.Entries[i]; + fn = Path.Combine(PEIPath, "procedures", ze.Name); + ze.ExtractToFile(fn, true); + xd = new XmlDocument(); + xd.Load(fn); + pi = AddProcedure(xd.DocumentElement, dvi, pi); + GC.Collect(); // need to cleanup memory after importing each procedure due to use of Regular Expressions in processing RO and Transition links + } + DirectoryInfo di = new DirectoryInfo(PEIPath); + DirectoryInfo[] dis = di.GetDirectories(); + for (int d = 0; d < dis.Length; d++) + dis[d].Delete(true); + lblImportStatus.Text = "Updating Transitions"; + AddTransitions(); + FixFloatingFoldouts(); + SaveTransitionAndItemContentIDs(); + return true; } - else - return false; } - _MyNewFolder = FolderInfo.Get(ff.FolderID); - AddAnnotationTypes(xd); - DocVersionInfo dvi = AddDocVersion(ff, xd); - MyDocVersion = dvi; - xd = null; - lblImportStatus.Text = "Creating Procedures..."; - Application.DoEvents(); - ProcedureInfo pi = null; - pbImportProcedure.Value = 0; - pbImportProcedure.Maximum = MyExpxZipFile.Entries.Count - 1; - for (int i = 1; i < MyExpxZipFile.Entries.Count; i++) - { - ze = MyExpxZipFile[i]; - fn = PEIPath + @"\" + ze.FileName; - ze.Extract(PEIPath, ExtractExistingFileAction.OverwriteSilently); - xd = new XmlDocument(); - xd.Load(fn); - pi = AddProcedure(xd.DocumentElement, dvi, pi); - GC.Collect(); // need to cleanup memory after importing each procedure due to use of Regular Expressions in processing RO and Transition links - } - DirectoryInfo di = new DirectoryInfo(PEIPath); - DirectoryInfo[] dis = di.GetDirectories(); - for (int d = 0; d < dis.Length; d++) - dis[d].Delete(true); - lblImportStatus.Text = "Updating Transitions"; - AddTransitions(); - FixFloatingFoldouts(); - SaveTransitionAndItemContentIDs(); - return true; } private void FixSectionStart(ProcedureInfo pi) { @@ -1254,85 +1263,85 @@ namespace VEPROMS // the xml files are then added (or replaced) in the .impx file. private void SaveTransitionAndItemContentIDs() { - XmlDocument xd = new XmlDocument(); - XmlElement xe = xd.CreateElement("items"); - xd.AppendChild(xe); - string fn = PEIPath + @"\items.xml"; - foreach (int key in Old2NewItem.Keys) + using (FileStream zipToOpen = new FileStream(MyImpZipFileName, FileMode.OpenOrCreate)) { - xe = xd.CreateElement("item"); - xe.Attributes.SetNamedItem(AddAttribute(xd, "old", key.ToString())); - xe.Attributes.SetNamedItem(AddAttribute(xd, "new", Old2NewItem[key].ToString())); - xd.DocumentElement.AppendChild(xe); - } - xd.Save(fn); - ZipEntry ze = MyImpxZipFile["items.xml"]; - MyImpxZipFile.RemoveEntry(ze); - MyImpxZipFile.Save(); - MyImpxZipFile.AddFile(fn, ""); - MyImpxZipFile.Save(); - File.Delete(fn); - xd = new XmlDocument(); - xe = xd.CreateElement("contents"); - xd.AppendChild(xe); - fn = PEIPath + @"\contents.xml"; - foreach (int key in Old2NewContent.Keys) - { - xe = xd.CreateElement("content"); - xe.Attributes.SetNamedItem(AddAttribute(xd, "old", key.ToString())); - xe.Attributes.SetNamedItem(AddAttribute(xd, "new", Old2NewContent[key].ToString())); - xd.DocumentElement.AppendChild(xe); - } - xd.Save(fn); - ze = MyImpxZipFile["contents.xml"]; - MyImpxZipFile.RemoveEntry(ze); - MyImpxZipFile.Save(); - MyImpxZipFile.AddFile(fn, ""); - MyImpxZipFile.Save(); - File.Delete(fn); - xd = new XmlDocument(); - xe = xd.CreateElement("transitions"); - xd.AppendChild(xe); - fn = PEIPath + @"\transitions.xml"; - if (PendingTransitions != null && PendingTransitions.DocumentElement.HasChildNodes) - { - foreach (XmlNode nd in PendingTransitions.DocumentElement.ChildNodes) + using (ZipArchive MyImpxZipFile = new ZipArchive(zipToOpen, ZipArchiveMode.Update)) { - if (nd.InnerText == "") - xd.DocumentElement.AppendChild(xd.ImportNode(nd, true)); + XmlDocument xd = new XmlDocument(); + XmlElement xe = xd.CreateElement("items"); + xd.AppendChild(xe); + string fn = PEIPath + @"\items.xml"; + foreach (int key in Old2NewItem.Keys) + { + xe = xd.CreateElement("item"); + xe.Attributes.SetNamedItem(AddAttribute(xd, "old", key.ToString())); + xe.Attributes.SetNamedItem(AddAttribute(xd, "new", Old2NewItem[key].ToString())); + xd.DocumentElement.AppendChild(xe); + } + xd.Save(fn); + ZipArchiveEntry ze = MyImpxZipFile.GetEntry("items.xml"); + ze.Delete(); + _ = MyImpxZipFile.CreateEntryFromFile(fn, Path.GetFileName(fn)); + File.Delete(fn); + xd = new XmlDocument(); + xe = xd.CreateElement("contents"); + xd.AppendChild(xe); + fn = PEIPath + @"\contents.xml"; + foreach (int key in Old2NewContent.Keys) + { + xe = xd.CreateElement("content"); + xe.Attributes.SetNamedItem(AddAttribute(xd, "old", key.ToString())); + xe.Attributes.SetNamedItem(AddAttribute(xd, "new", Old2NewContent[key].ToString())); + xd.DocumentElement.AppendChild(xe); + } + xd.Save(fn); + ze = MyImpxZipFile.GetEntry("contents.xml"); + ze.Delete(); + _ = MyImpxZipFile.CreateEntryFromFile(fn, Path.GetFileName(fn)); + File.Delete(fn); + xd = new XmlDocument(); + xe = xd.CreateElement("transitions"); + xd.AppendChild(xe); + fn = PEIPath + @"\transitions.xml"; + if (PendingTransitions != null && PendingTransitions.DocumentElement.HasChildNodes) + { + foreach (XmlNode nd in PendingTransitions.DocumentElement.ChildNodes) + { + if (nd.InnerText == "") + xd.DocumentElement.AppendChild(xd.ImportNode(nd, true)); + } + } + xd.Save(fn); + ze = MyImpxZipFile.GetEntry("transitions.xml"); + ze.Delete(); + _ = MyImpxZipFile.CreateEntryFromFile(fn, Path.GetFileName(fn)); + File.Delete(fn); } } - xd.Save(fn); - ze = MyImpxZipFile["transitions.xml"]; - MyImpxZipFile.RemoveEntry(ze); - MyImpxZipFile.Save(); - MyImpxZipFile.AddFile(fn, ""); - MyImpxZipFile.Save(); - File.Delete(fn); } // This is called only when we are importing an entire folder and there is a .impx file (a zip file) // the name of the .impx file is based on the folder name containing the export file being imported // This will read in the saved ItemIDs (old and new), ContentIDs (old andnew), library document IDs (old and new), and pending transitions - private void ReadTransitionAndItemContentIDs() + private void ReadTransitionAndItemContentIDs(ZipArchive MyImpxZipFile) { - ZipEntry ze = MyImpxZipFile["items.xml"]; - ze.Extract(PEIPath, ExtractExistingFileAction.OverwriteSilently); + ZipArchiveEntry ze = MyImpxZipFile.GetEntry("items.xml"); string fn = PEIPath + @"\items.xml"; + ze.ExtractToFile(fn, true); XmlDocument xd = new XmlDocument(); xd.Load(fn); // B2016-176, B2016-197 Transitions were no always properly resolved - don't load in the old item ids File.Delete(fn); - ze = MyImpxZipFile["contents.xml"]; - ze.Extract(PEIPath, ExtractExistingFileAction.OverwriteSilently); + ze = MyImpxZipFile.GetEntry("contents.xml"); fn = PEIPath + @"\contents.xml"; + ze.ExtractToFile(fn, true); xd = new XmlDocument(); xd.Load(fn); // B2016-176, B2016-197 Transitions were no always properly resolved - don't load in the old content ids File.Delete(fn); - ze = MyImpxZipFile["libdocs.xml"]; - ze.Extract(PEIPath, ExtractExistingFileAction.OverwriteSilently); + ze = MyImpxZipFile.GetEntry("libdocs.xml"); fn = PEIPath + @"\libdocs.xml"; + ze.ExtractToFile(fn, true); xd = new XmlDocument(); xd.Load(fn); XmlNodeList nl = xd.SelectNodes("//libdoc"); @@ -1344,9 +1353,9 @@ namespace VEPROMS Old2NewLibDoc.Add(oldid, newid); } File.Delete(fn); - ze = MyImpxZipFile["transitions.xml"]; - ze.Extract(PEIPath, ExtractExistingFileAction.OverwriteSilently); + ze = MyImpxZipFile.GetEntry("transitions.xml"); fn = PEIPath + @"\transitions.xml"; + ze.ExtractToFile(fn, true); PendingTransitions.Load(fn); File.Delete(fn); } @@ -1374,53 +1383,53 @@ namespace VEPROMS else dn = fi.Name.Substring(0, fi.Name.IndexOf(".")); txtImport.Text = ofd.FileName; - ReadOptions ro = new ReadOptions(); - ro.Encoding = Encoding.UTF8; - MyExpxZipFile = ZipFile.Read(txtImport.Text, ro); - string fn = string.Format(@"{0}\{1}.impx", PEIPath, dn); - if (File.Exists(fn)) + MyExpZipFileName = txtImport.Text; + string fn = string.Format(@"{0}\{1}.impx", PEIPath, dn); + MyImpZipFileName = fn; + if (File.Exists(fn)) { - MyImpxZipFile = ZipFile.Read(fn, ro); - ReadTransitionAndItemContentIDs(); + using (ZipArchive MyImpxZipFile = ZipFile.OpenRead(fn)) + ReadTransitionAndItemContentIDs(MyImpxZipFile); } else { - MyImpxZipFile = new ZipFile(fn, Encoding.UTF8); - //transitions - XmlElement xe = PendingTransitions.CreateElement("transitions"); - PendingTransitions.AppendChild(xe); - fn = PEIPath + @"\transitions.xml"; - PendingTransitions.Save(fn); - MyImpxZipFile.AddFile(fn, ""); - MyImpxZipFile.Save(); - File.Delete(fn); - //itemids - XmlDocument xd = new XmlDocument(); - xe = xd.CreateElement("items"); - xd.AppendChild(xe); - fn = PEIPath + @"\items.xml"; - xd.Save(fn); - MyImpxZipFile.AddFile(fn, ""); - MyImpxZipFile.Save(); - File.Delete(fn); - //contentids - xd = new XmlDocument(); - xe = xd.CreateElement("contents"); - xd.AppendChild(xe); - fn = PEIPath + @"\contents.xml"; - xd.Save(fn); - MyImpxZipFile.AddFile(fn, ""); - MyImpxZipFile.Save(); - File.Delete(fn); - //libdocids - xd = new XmlDocument(); - xe = xd.CreateElement("libdocs"); - xd.AppendChild(xe); - fn = PEIPath + @"\libdocs.xml"; - xd.Save(fn); - MyImpxZipFile.AddFile(fn, ""); - MyImpxZipFile.Save(); - File.Delete(fn); + using (FileStream zipToOpen = new FileStream(fn, FileMode.OpenOrCreate)) + { + using (ZipArchive MyImpxZipFile = new ZipArchive(zipToOpen, ZipArchiveMode.Update)) + { + //transitions + XmlElement xe = PendingTransitions.CreateElement("transitions"); + PendingTransitions.AppendChild(xe); + fn = PEIPath + @"\transitions.xml"; + PendingTransitions.Save(fn); + _ = MyImpxZipFile.CreateEntryFromFile(fn, Path.GetFileName(fn)); + File.Delete(fn); + //itemids + XmlDocument xd = new XmlDocument(); + xe = xd.CreateElement("items"); + xd.AppendChild(xe); + fn = PEIPath + @"\items.xml"; + xd.Save(fn); + _ = MyImpxZipFile.CreateEntryFromFile(fn, Path.GetFileName(fn)); + File.Delete(fn); + //contentids + xd = new XmlDocument(); + xe = xd.CreateElement("contents"); + xd.AppendChild(xe); + fn = PEIPath + @"\contents.xml"; + xd.Save(fn); + _ = MyImpxZipFile.CreateEntryFromFile(fn, Path.GetFileName(fn)); + File.Delete(fn); + //libdocids + xd = new XmlDocument(); + xe = xd.CreateElement("libdocs"); + xd.AppendChild(xe); + fn = PEIPath + @"\libdocs.xml"; + xd.Save(fn); + _ = MyImpxZipFile.CreateEntryFromFile(fn, Path.GetFileName(fn)); + File.Delete(fn); + } + } } } if (MyDocVersion != null) @@ -1595,27 +1604,31 @@ namespace VEPROMS ExportAssociation(xe, ai, "association"); string fn = PEIPath + @"\folder.xml"; xn.OwnerDocument.Save(fn); - MyExpxZipFile.AddFile(fn, "folder"); - MyExpxZipFile.Save(); - File.Delete(fn); - //here - lblExportStatus.Text = "Exporting Procedures..."; - Application.DoEvents(); - if (dvi.Procedures.Count > 0) + using (FileStream zipToOpen = new FileStream(MyExpZipFileName, FileMode.OpenOrCreate)) { - pbExportProcedure.Value = 0; - pbExportProcedure.Maximum = dvi.Procedures.Count; - lblExportProcedure.Text = pbExportProcedure.Maximum.ToString() + " Procedures"; - foreach (ItemInfo ii in dvi.Procedures) - { - XmlDocument xd = new XmlDocument(); - ExportItem(xd, ii, "procedure"); - fn = string.Format(@"{0}\proc{1}.xml", PEIPath, pbExportProcedure.Value.ToString().PadLeft(4, '0')); - xd.Save(fn); - MyExpxZipFile.AddFile(fn, "procedures"); - MyExpxZipFile.Save(); + using (ZipArchive MyExpxZipFile = new ZipArchive(zipToOpen, ZipArchiveMode.Update)) + { + _ = MyExpxZipFile.CreateEntryFromFile(fn, $"folder/{Path.GetFileName(fn)}"); File.Delete(fn); - xd = null; + //here + lblExportStatus.Text = "Exporting Procedures..."; + Application.DoEvents(); + if (dvi.Procedures.Count > 0) + { + pbExportProcedure.Value = 0; + pbExportProcedure.Maximum = dvi.Procedures.Count; + lblExportProcedure.Text = pbExportProcedure.Maximum.ToString() + " Procedures"; + foreach (ItemInfo ii in dvi.Procedures) + { + XmlDocument xd = new XmlDocument(); + ExportItem(xd, ii, "procedure"); + fn = string.Format(@"{0}\proc{1}.xml", PEIPath, pbExportProcedure.Value.ToString().PadLeft(4, '0')); + xd.Save(fn); + _ = MyExpxZipFile.CreateEntryFromFile(fn, $"procedures/{Path.GetFileName(fn)}"); + File.Delete(fn); + xd = null; + } + } } } } @@ -1839,12 +1852,14 @@ namespace VEPROMS //and handled/overridden in dlgExportEP.cs } - protected virtual void SetROLocation(ref XmlElement xindivid, ROFSTLookup.rochild roc, RODbInfo rodb, bool isMulti) + protected virtual void SetEPEnhancedDocLinks(ref XmlElement xe, ItemInfo ii) { //do nothing - this will be for Electronic procedures only //and handled/overridden in dlgExportEP.cs } - protected virtual void SetEPEnhancedDocLinks(ref XmlElement xe, ItemInfo ii) + + + protected virtual void SetROLocation(ref XmlElement xindivid, ROFSTLookup.rochild roc, RODbInfo rodb, bool isMulti) { //do nothing - this will be for Electronic procedures only //and handled/overridden in dlgExportEP.cs