private void ButtonProceed4_Click(object sender, EventArgs e) { List <ZipStorer.ZipFileEntry> removeList = new List <ZipStorer.ZipFileEntry>(); foreach (object sel in listBox4.SelectedItems) { removeList.Add((ZipStorer.ZipFileEntry)sel); } ZipStorer zip = listBox4.Tag as ZipStorer; try { if (zip == null || !ZipStorer.RemoveEntries(ref zip, removeList)) { throw new Exception(); } else { MessageBox.Show("Zip file entries removed with success", "ZipStorer Demo", MessageBoxButtons.OK, MessageBoxIcon.Information); listBox4.Tag = zip; listBox4.DataSource = zip.ReadCentralDir(); } } catch { MessageBox.Show("Error while trying to remove entries from Zip file", "ZipStorer Demo", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public static void UpdateAndroidPlugin() { var pluginFolder = CombinePaths(Application.dataPath, "Plugins", "NativeFileSO", "Android"); var aarPath = CombinePaths(pluginFolder, "NativeFileSO.aar"); var manifestName = "AndroidManifest.xml"; var manifestPath = CombinePaths(pluginFolder, manifestName); ZipStorer zip = ZipStorer.Open(aarPath, FileAccess.ReadWrite); var centralDir = zip.ReadCentralDir(); var manifest = centralDir.Find(x => Path.GetFileName(x.FilenameInZip) == manifestName); zip.ExtractFile(manifest, manifestPath); UpdateManifestAssociations(manifestPath); ZipStorer.RemoveEntries(ref zip, new List <ZipStorer.ZipFileEntry>() { manifest }); zip.AddFile(ZipStorer.Compression.Deflate, manifestPath, manifest.FilenameInZip, ""); zip.Close(); File.Delete(manifestPath); Debug.Log("NativeFileSO: Finished updating the Android plugin"); }
public void Test_Common() { Assert.Throws(typeof(ArgumentNullException), () => { ZipStorer.Open("", FileAccess.Read); }); string fileName = TestStubs.GetTempFilePath("test.zip"); using (ZipStorer zip = ZipStorer.Create(fileName, "test")) { using (MemoryStream csvStream = new MemoryStream(Encoding.ASCII.GetBytes(TestStubs.CSVData))) { zip.AddStream(ZipStorer.Compression.Deflate, "csv_file.csv", csvStream, DateTime.Now, ""); } Assert.Throws(typeof(InvalidOperationException), () => { zip.ReadCentralDir(); }); ZipStorer xzip = null; Assert.Throws(typeof(ArgumentNullException), () => { xzip = ZipStorer.RemoveEntries(xzip, null); }); Assert.Throws(typeof(ArgumentNullException), () => { xzip = ZipStorer.RemoveEntries(xzip, null); }); } using (ZipStorer zip = ZipStorer.Open(fileName, FileAccess.Read)) { Assert.Throws(typeof(ArgumentNullException), () => { zip.FindFile(null); }); ZipStorer.ZipFileEntry entry = zip.FindFile("invalid"); Assert.IsNull(entry); entry = zip.FindFile("csv_file.csv"); Assert.IsNotNull(entry); using (MemoryStream csvStream = new MemoryStream()) { Assert.Throws(typeof(ArgumentNullException), () => { zip.ExtractStream(entry, null); }); zip.ExtractStream(entry, csvStream); csvStream.Seek(0, SeekOrigin.Begin); using (var reader = new StreamReader(csvStream, Encoding.ASCII)) { string text = reader.ReadToEnd(); Assert.AreEqual(TestStubs.CSVData, text); } } } }
/// <summary> /// Deploy a given list of files (can reduce the list if there are duplicated items so it returns it) /// </summary> public List <FileToDeploy> DeployFiles(List <FileToDeploy> deployToDo, Action <float> updateDeploymentPercentage = null) { int[] totalFile = { 0 }; int[] nbFilesDone = { 0 }; // make sure to transfer a given file only once at the same place (happens with .cls file since a source // can have several .r files generated if it is used in another classes) deployToDo = deployToDo .GroupBy(deploy => deploy.To) .Select(group => group.FirstOrDefault(move => Path.GetFileNameWithoutExtension(move.From ?? "").Equals(Path.GetFileNameWithoutExtension(move.Origin))) ?? group.First()) .ToList(); totalFile[0] = deployToDo.Count; // check that every target dir exist (for copy/move deployments) deployToDo .Where(deploy => deploy.DeployType == DeployType.Copy || deploy.DeployType == DeployType.Move) .GroupBy(deploy => Path.GetDirectoryName(deploy.To)) .Select(group => group.First()) .ToNonNullList() .ForEach(deploy => Utils.CreateDirectory(Path.GetDirectoryName(deploy.To))); #region for archives (zip/pl) // for archives, compute the path to the archive file (+ make sure the directory of the archive exists) deployToDo.Where(deploy => deploy.DeployType <= DeployType.Archive).ToNonNullList().ForEach(deploy => { var ext = deploy.DeployType == DeployType.Prolib ? ".pl" : ".zip"; var pos = deploy.To.LastIndexOf(ext, StringComparison.CurrentCultureIgnoreCase); if (pos >= 0) { var posEnd = pos + ext.Length; deploy.ArchivePath = deploy.To.Substring(0, posEnd); deploy.RelativePathInArchive = deploy.To.Substring(posEnd + 1); // ensure that the folder to the .archive file exists Utils.CreateDirectory(Path.GetDirectoryName(deploy.ArchivePath)); // for .zip, open the zip stream for later usage if (deploy.DeployType > DeployType.Prolib) { if (!_openedZip.ContainsKey(deploy.ArchivePath)) { try { if (!File.Exists(deploy.ArchivePath)) { _openedZip.Add(deploy.ArchivePath, ZipStorer.Create(deploy.ArchivePath, "Created with 3P @ " + DateTime.Now + "\r\n" + Config.UrlWebSite)); } else { _openedZip.Add(deploy.ArchivePath, ZipStorer.Open(deploy.ArchivePath, FileAccess.Write)); _filesToRemoveFromZip.Add(deploy.ArchivePath, new HashSet <string>()); } } catch (Exception e) { ErrorHandler.ShowErrors(e, "Couldn't create/open the .zip file"); } } // we didn't create the zip? then we need to remove this file if it exists if (_filesToRemoveFromZip.ContainsKey(deploy.ArchivePath)) { _filesToRemoveFromZip[deploy.ArchivePath].Add(deploy.RelativePathInArchive.Replace('\\', '/')); } } } }); #endregion #region for .pl deployments, we treat them before anything else // for PL, we need to MOVE each file into a temporary folder with the internal structure of the .pl file, // then move it back where it was for further deploys... var plDeployments = deployToDo .Where(deploy => deploy.DeployType == DeployType.Prolib) .ToNonNullList(); if (plDeployments.Count > 0) { // then we create a unique temporary folder for each .pl var dicPlToTempFolder = new Dictionary <string, string>(StringComparer.CurrentCultureIgnoreCase); foreach (var pathPl in plDeployments.Where(deploy => !string.IsNullOrEmpty(deploy.ArchivePath)).Select(deploy => deploy.ArchivePath).Distinct()) { // create a unique temp folder for this .pl if (!dicPlToTempFolder.ContainsKey(pathPl)) { var plDirPath = Path.GetDirectoryName(pathPl); if (plDirPath != null) { var uniqueTempFolder = Path.Combine(plDirPath, Path.GetFileName(pathPl) + "~" + Path.GetRandomFileName()); dicPlToTempFolder.Add(pathPl, uniqueTempFolder); Utils.CreateDirectory(uniqueTempFolder, FileAttributes.Hidden); } } } var prolibMessage = new StringBuilder(); // for each .pl that needs to be created... foreach (var pl in dicPlToTempFolder) { var pl1 = pl; var onePlDeployments = plDeployments .Where(deploy => !string.IsNullOrEmpty(deploy.ArchivePath) && deploy.ArchivePath.Equals(pl1.Key)) .ToNonNullList(); if (onePlDeployments.Count == 0) { continue; } // we set the temporary folder on which each file will be copied.. // Tuple : <(base) temp directory, relative path in pl, path to .pl> var dicTempFolderToPl = new Dictionary <string, Tuple <string, string, string> >(StringComparer.CurrentCultureIgnoreCase); foreach (var fileToDeploy in onePlDeployments) { if (string.IsNullOrEmpty(fileToDeploy.ArchivePath)) { continue; } if (dicPlToTempFolder.ContainsKey(fileToDeploy.ArchivePath)) { fileToDeploy.ToTemp = Path.Combine( dicPlToTempFolder[fileToDeploy.ArchivePath], fileToDeploy.To.Replace(fileToDeploy.ArchivePath, "").TrimStart('\\') ); // If not already done, remember that the *.r code in this temp folder must be integrated to this .pl file var tempSubFolder = Path.GetDirectoryName(fileToDeploy.ToTemp); if (!string.IsNullOrEmpty(tempSubFolder) && !dicTempFolderToPl.ContainsKey(tempSubFolder)) { dicTempFolderToPl.Add( tempSubFolder, new Tuple <string, string, string>( dicPlToTempFolder[fileToDeploy.ArchivePath], // path of the temp dir Path.GetDirectoryName(fileToDeploy.To.Replace(fileToDeploy.ArchivePath, "").TrimStart('\\')), // relative path in .pl fileToDeploy.ArchivePath) // path to the .pl file ); // also, create the folder Utils.CreateDirectory(tempSubFolder); } } } var prolibExe = new ProcessIo(ProEnv.ProlibPath); // for each subfolder in the .pl foreach (var plSubFolder in dicTempFolderToPl) { var onePlSubFolderDeployments = onePlDeployments .Where(deploy => plSubFolder.Key.Equals(Path.GetDirectoryName(deploy.ToTemp))) .ToNonNullList(); if (onePlSubFolderDeployments.Count == 0) { continue; } Parallel.ForEach(onePlSubFolderDeployments, deploy => { if (File.Exists(deploy.From)) { deploy.IsOk = !string.IsNullOrEmpty(deploy.ToTemp) && Utils.MoveFile(deploy.From, deploy.ToTemp); } if (deploy.IsOk) { nbFilesDone[0]++; } if (updateDeploymentPercentage != null) { updateDeploymentPercentage((float)nbFilesDone[0] / totalFile[0] * 100); } }); // now we just need to add the content of temp folders into the .pl prolibExe.StartInfo.WorkingDirectory = plSubFolder.Value.Item1; // base temp dir prolibExe.Arguments = plSubFolder.Value.Item3.ProQuoter() + " -create -nowarn -add " + Path.Combine(plSubFolder.Value.Item2, "*").ProQuoter(); if (!prolibExe.TryDoWait(true)) { prolibMessage.Append(prolibExe.ErrorOutput); } Parallel.ForEach(onePlSubFolderDeployments, deploy => { deploy.IsOk = deploy.IsOk && Utils.MoveFile(deploy.ToTemp, deploy.From); }); } // compress .pl prolibExe.StartInfo.WorkingDirectory = Path.GetDirectoryName(pl.Key) ?? ""; prolibExe.Arguments = pl.Key.ProQuoter() + " -compress -nowarn"; if (!prolibExe.TryDoWait(true)) { prolibMessage.Append(prolibExe.ErrorOutput); } // delete temp folders Utils.DeleteDirectory(pl.Value, true); } if (prolibMessage.Length > 0) { UserCommunication.Notify("Errors occured when trying to create/add files to the .pl file :<br>" + prolibMessage, MessageImg.MsgError, "Prolib output", "Errors"); } } #endregion #region for zip // remove the files that are already in the zip file or they will appear twice when we add them foreach (var kpv in _filesToRemoveFromZip) { ZipStorer zip = _openedZip[kpv.Key]; var filesToDelete = zip.ReadCentralDir().Where(zipFileEntry => kpv.Value.Contains(zipFileEntry.FilenameInZip)).ToList(); _openedZip.Remove(kpv.Key); ZipStorer.RemoveEntries(ref zip, filesToDelete); _openedZip.Add(kpv.Key, zip); } #endregion // do a deployment action for each file (parallel for MOVE and COPY) Parallel.ForEach(deployToDo.Where(deploy => deploy.DeployType >= DeployType.Copy), file => { if (DeploySingleFile(file)) { nbFilesDone[0]++; } if (updateDeploymentPercentage != null) { updateDeploymentPercentage((float)nbFilesDone[0] / totalFile[0] * 100); } }); // don't use parallel for the other types foreach (var file in deployToDo.Where(deploy => deploy.DeployType < DeployType.Copy)) { if (DeploySingleFile(file)) { nbFilesDone[0]++; } if (updateDeploymentPercentage != null) { updateDeploymentPercentage((float)nbFilesDone[0] / totalFile[0] * 100); } } #region for zip, dispose of zipStorers // also, need to dispose of the object/stream here foreach (var zipStorer in _openedZip) { zipStorer.Value.Close(); } _openedZip.Clear(); #endregion return(deployToDo); }