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