// Spludlow Software // Copyright © Samuel P. Ludlow 2020 All Rights Reserved // Distributed under the terms of the GNU General Public License version 3 // Distributed WITHOUT ANY WARRANTY; without implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE // https://www.spludlow.co.uk/LICENCE.TXT // The Spludlow logo is a registered trademark of Samuel P. Ludlow and may not be used without permission // v1.14 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Net; using System.Data; namespace Spludlow { /// /// Wrapper for 7-Zip executable /// public class Archive { private const string ProgramFilename = @"C:\Program Files\7-Zip\7z.exe"; public static string Create(string archiveFilename, string sourcePath) { return Create(archiveFilename, sourcePath, null, 0, false); } public static string Create(string archiveFilename, string sourcePath, bool noCompress) { return Create(archiveFilename, sourcePath, null, 0, noCompress); } public static string Create(string archiveFilename, string sourcePath, string password) { return Create(archiveFilename, sourcePath, password, 0, false); } public static string Create(string archiveFilename, string sourcePath, string password, bool noCompress) { return Create(archiveFilename, sourcePath, password, 0, noCompress); } public static string Create(string archiveFilename, string sourcePath, string password, int timeoutSeconds, bool noCompress) { password = Password(password); StringBuilder arguments = new StringBuilder(); arguments.Append("a -y "); if (password != null) { arguments.Append("-p\""); arguments.Append(password); arguments.Append("\" "); } if (noCompress == true) arguments.Append("-mx0 "); arguments.Append("\""); arguments.Append(archiveFilename); arguments.Append("\" "); arguments.Append("\""); arguments.Append(sourcePath); arguments.Append("\""); Spludlow.SpawnProcess.ProcessExitInfo info = Spludlow.SpawnProcess.Run(ProgramFilename, arguments.ToString(), timeoutSeconds); if (info.StandardError.Length == 0 && info.ExitCode == 0) return null; if (info.ExitCode == 1) // Warnings return info.StandardOutput; throw new ApplicationException( "Archive, Create 7Zip, ExitCode:" + info.ExitCode + Environment.NewLine + "StandardError:" + info.StandardError + Environment.NewLine + "StandardOutput:" + info.StandardOutput); } public static void Extract(string archiveFileName, string outputDirectory) { Extract(archiveFileName, outputDirectory, null, 0); } public static void Extract(string archiveFileName, string outputDirectory, string password) { Extract(archiveFileName, outputDirectory, password, 0); } public static void Extract(string archiveFileName, string outputDirectory, int timeoutSeconds) { Extract(archiveFileName, outputDirectory, null, timeoutSeconds); } public static void Extract(string archiveFileName, string outputDirectory, string password, int timeoutSeconds) { password = Password(password); string arguments = "x -y -o\"@OUT\" \"@ARC\""; if (password != null) { arguments = "x -y -p\"@PASS\" -o\"@OUT\" \"@ARC\""; arguments = arguments.Replace("@PASS", password); } arguments = arguments.Replace("@ARC", archiveFileName); arguments = arguments.Replace("@OUT", outputDirectory); Spludlow.SpawnProcess.ProcessExitInfo info = Spludlow.SpawnProcess.Run(ProgramFilename, arguments.ToString(), null, null, timeoutSeconds, false); if (info.StandardError.Length != 0 || info.ExitCode != 0) throw new ApplicationException( "Archive, Extract 7Zip, ExitCode:" + info.ExitCode + Environment.NewLine + "StandardError:" + info.StandardError + Environment.NewLine + "StandardOutput:" + info.StandardOutput); } private static string Password(string password) { if (password == null || password == "") return null; if (password.StartsWith("@") == false) return password; string key = password.Substring(1); if (key == "") key = "ZipPassword"; NetworkCredential networkCredential = Spludlow.Credentials.GetCredential(key); return networkCredential.Password; } public static DataTable List(string archiveFileName) { return List(archiveFileName, null, 0); } public static DataTable List(string archiveFileName, string password) { return List(archiveFileName, password, 0); } public static DataTable List(string archiveFileName, string password, int timeoutSeconds) { password = Password(password); string arguments = "-slt -scsUTF-8"; if (password != null) { arguments += " -p\"@PASS\""; arguments = arguments.Replace("@PASS", password); } arguments += " l \"@FILENAME\""; arguments = arguments.Replace("@FILENAME", archiveFileName); Spludlow.SpawnProcess.ProcessExitInfo info = Spludlow.SpawnProcess.Run(ProgramFilename, arguments.ToString(), null, null, timeoutSeconds, false); if (info.StandardError.Length != 0 || info.ExitCode != 0) throw new ApplicationException( "Archive, List 7Zip, ExitCode:" + info.ExitCode + Environment.NewLine + "StandardError:" + info.StandardError + Environment.NewLine + "StandardOutput:" + info.StandardOutput); DataTable table = new DataTable(); table.TableName = Path.GetFileNameWithoutExtension(archiveFileName); bool inHeader = true; Dictionary record = new Dictionary(); using (StringReader reader = new StringReader(info.StandardOutput)) { string line; while ((line = reader.ReadLine()) != null) { if (inHeader == true && line.StartsWith("----------")) { inHeader = false; continue; } if (inHeader == true) continue; if (line.Length == 0) { if (record.Count == 0) continue; foreach (string columnName in record.Keys) { if (table.Columns.Contains(columnName) == false) table.Columns.Add(columnName, typeof(string)); } DataRow row = table.NewRow(); foreach (string columnName in record.Keys) row[columnName] = record[columnName]; table.Rows.Add(row); record = new Dictionary(); continue; } int index = line.IndexOf("="); if (index == -1) { Spludlow.Log.Warning("Archive List bad line: " + archiveFileName, line); continue; } string name = line.Substring(0, index).Trim(); string data = line.Substring(index + 1).Trim(); record.Add(name, data); } } return table; } } }