From 1c9b0fa64a01e2397fb1d106d8ba42044a61ddc9 Mon Sep 17 00:00:00 2001 From: rxwx Date: Thu, 8 Sep 2022 21:35:34 +0100 Subject: [PATCH 1/2] Add support for packing asar files (sync only). Also adds various options to the test harness to match the functionality provided by the npm package. Note this commit also bumps the .NET version to 4.5.1. --- sync/Test/App.config | 6 +- sync/Test/Program.cs | 89 ++++++++--- sync/Test/Test.csproj | 3 +- sync/asardotnet/AsarArchive.cs | 76 ++++++--- sync/asardotnet/AsarExceptions.cs | 34 +++-- sync/asardotnet/AsarExtractor.cs | 177 ++++++++++++--------- sync/asardotnet/AsarPacker.cs | 246 ++++++++++++++++++++++++++++++ sync/asardotnet/Utilities.cs | 24 +-- sync/asardotnet/asardotnet.csproj | 4 +- 9 files changed, 514 insertions(+), 145 deletions(-) create mode 100644 sync/asardotnet/AsarPacker.cs diff --git a/sync/Test/App.config b/sync/Test/App.config index 8e15646..d0feca6 100644 --- a/sync/Test/App.config +++ b/sync/Test/App.config @@ -1,6 +1,6 @@ - + - + - \ No newline at end of file + diff --git a/sync/Test/Program.cs b/sync/Test/Program.cs index 29c3388..296e7f3 100644 --- a/sync/Test/Program.cs +++ b/sync/Test/Program.cs @@ -1,32 +1,81 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; using asardotnet; -using Newtonsoft.Json.Linq; -namespace Test { - class Program { - static void Main(string[] args) { - - AsarArchive asarArhive = new AsarArchive("D:\\Downloads\\app.asar"); - AsarExtractor extractor = new AsarExtractor(); - - extractor.ExtractAll(asarArhive, "G:\\Asardotnet\\out\\"); - - // extractor.Extract(asarArhive, "app/index.js", "G:\\Asardotnet\\out\\index.js"); +namespace asardotnet +{ + class Program + { + static void PrintUsage() + { + Console.WriteLine("\n Usage: Test.exe [command] [options]"); + Console.WriteLine("\n Commands:"); + Console.WriteLine("\n pack|p \n create asar archive"); + Console.WriteLine("\n list|l \n list files of asar archive"); + Console.WriteLine("\n extract-file|ef \n extract one file from asar archive"); + Console.WriteLine("\n extract|e \n extract asar archive"); + Console.WriteLine("\n"); + } - // AsarExtractor extractor = new AsarExtractor(); - // extractor.Extract(asarArhive, "NotificationWindow.js", ""); + static void Main(string[] args) + { + if (args.Length < 2) + { + PrintUsage(); + return; + } - // AsarExtractor asarExtractor = new AsarExtractor(); + AsarArchive asarArchive; + AsarExtractor extractor = new AsarExtractor(); + AsarPacker packer = new AsarPacker(); - //asarExtractor.Extract(asarArhive, "G:\\Asardotnet\\extract\\"); + switch (args[0].ToLower()) + { + case "e": + case "extract": + if (args.Length != 3 || !File.Exists(args[1])) + { - // asarExtractor.ExtractFile(asarArhive, 8528, 6479); + PrintUsage(); + return; + } + asarArchive = new AsarArchive(args[1]); + extractor.ExtractAll(asarArchive, args[2]); + return; + case "ef": + case "extract-file": + if (args.Length != 3) + { + PrintUsage(); + return; + } + asarArchive = new AsarArchive(args[1]); + extractor.Extract(asarArchive, args[1], args[2]); + break; + case "l": + case "list": + if (!File.Exists(args[1])) + { + PrintUsage(); + return; + } + asarArchive = new AsarArchive(args[1]); + extractor.ListAll(asarArchive); + return; + case "p": + case "pack": + if (args.Length != 3) + { + PrintUsage(); + break; + } + packer.Pack(args[1], args[2]); + return; + default: + break; + } } } -} +} \ No newline at end of file diff --git a/sync/Test/Test.csproj b/sync/Test/Test.csproj index f5722ef..2be0b0d 100644 --- a/sync/Test/Test.csproj +++ b/sync/Test/Test.csproj @@ -9,8 +9,9 @@ Properties Test Test - v4.5 + v4.5.1 512 + AnyCPU diff --git a/sync/asardotnet/AsarArchive.cs b/sync/asardotnet/AsarArchive.cs index 461afca..a81c977 100644 --- a/sync/asardotnet/AsarArchive.cs +++ b/sync/asardotnet/AsarArchive.cs @@ -26,40 +26,52 @@ * */ using System; -using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using Newtonsoft.Json.Linq; -namespace asardotnet { - public class AsarArchive { +namespace asardotnet +{ + public class AsarArchive + { private const int SIZE_UINT = 4; private readonly int _baseOffset; + public int GetBaseOffset() { return _baseOffset; } private readonly byte[] _bytes; + public byte[] GetBytes() { return _bytes; } - private readonly String _filePath; - public String GetFilePath() { return _filePath; } + private readonly string _filePath; + + public string GetFilePath() { return _filePath; } private Header _header; + public Header GetHeader() { return _header; } - public struct Header { + public struct Header + { private readonly byte[] _headerInfo; + public byte[] GetHeaderInfo() { return _headerInfo; } + private readonly int _headerLength; + public int GetHeaderLenth() { return _headerLength; } private readonly byte[] _headerData; + public byte[] GetHeaderData() { return _headerData; } + private readonly JObject _headerJson; + public JObject GetHeaderJson() { return _headerJson; } - public Header(byte[] hinfo, int length, byte[] data, JObject hjson) { + public Header(byte[] hinfo, int length, byte[] data, JObject hjson) + { _headerInfo = hinfo; _headerLength = length; _headerData = data; @@ -67,22 +79,34 @@ public Header(byte[] hinfo, int length, byte[] data, JObject hjson) { } } - public AsarArchive(String filePath) { - if(!File.Exists(filePath)) + public AsarArchive() + { + + } + + public AsarArchive(string filePath) + { + if (!File.Exists(filePath)) throw new AsarExceptions(AsarException.ASAR_FILE_CANT_FIND); _filePath = filePath; - try { + try + { _bytes = File.ReadAllBytes(filePath); - } catch(Exception ex) { + } + catch (Exception ex) + { throw new AsarExceptions(AsarException.ASAR_FILE_CANT_READ, ex.ToString()); } - try { + try + { _header = ReadAsarHeader(ref _bytes); _baseOffset = _header.GetHeaderLenth(); - } catch(Exception _ex) { + } + catch (Exception _ex) + { throw _ex; } } @@ -91,29 +115,33 @@ public AsarArchive(String filePath) { * Exceptions should never be thrown as long as the file * was created with nodejs asar algorithm */ - private static Header ReadAsarHeader(ref byte[] bytes) { - int SIZE_LONG = 2 * SIZE_UINT; - int SIZE_INFO = 2 * SIZE_LONG; + private static Header ReadAsarHeader(ref byte[] bytes) + { + int SIZE_LONG = 2 * SIZE_UINT; // 8 + int SIZE_INFO = 2 * SIZE_LONG; // 16 // Header Info - byte[] headerInfo = bytes.Take(SIZE_INFO).ToArray(); + byte[] headerInfo = bytes.Take(SIZE_INFO).ToArray(); // 16 - if(headerInfo.Length < SIZE_INFO) + if (headerInfo.Length < SIZE_INFO) // 16 throw new AsarExceptions(AsarException.ASAR_INVALID_FILE_SIZE); - byte[] asarFileDescriptor = headerInfo.Take(SIZE_LONG).ToArray(); - byte[] asarPayloadSize = asarFileDescriptor.Take(SIZE_UINT).ToArray(); + byte[] asarFileDescriptor = headerInfo.Take(SIZE_LONG).ToArray(); // 16 + byte[] asarPayloadSize = asarFileDescriptor.Take(SIZE_UINT).ToArray(); // 4 int payloadSize = BitConverter.ToInt32(asarPayloadSize, 0); - int payloadOffset = asarFileDescriptor.Length - payloadSize; + int payloadOffset = asarFileDescriptor.Length - payloadSize; // 16 - 4 = 12 - if(payloadSize != SIZE_UINT && payloadSize != SIZE_LONG) + // payload size should be 4 + if (payloadSize != SIZE_UINT && payloadSize != SIZE_LONG) throw new AsarExceptions(AsarException.ASAR_INVALID_DESCRIPTOR); + // skip to byte 12 and read 4 bytes into headerLength byte[] asarHeaderLength = asarFileDescriptor.Skip(payloadOffset).Take(SIZE_UINT).ToArray(); int headerLength = BitConverter.ToInt32(asarHeaderLength, 0); + // skip 8 and take 8 byte[] asarFileHeader = headerInfo.Skip(SIZE_LONG).Take(SIZE_LONG).ToArray(); byte[] asarHeaderPayloadSize = asarFileHeader.Take(SIZE_UINT).ToArray(); @@ -126,7 +154,7 @@ private static Header ReadAsarHeader(ref byte[] bytes) { // Data Table byte[] hdata = bytes.Skip(SIZE_INFO).Take(dataTableSize).ToArray(); - if(hdata.Length != dataTableSize) + if (hdata.Length != dataTableSize) throw new AsarExceptions(AsarException.ASAR_INVALID_FILE_SIZE); int asarDataOffset = asarFileDescriptor.Length + headerLength; diff --git a/sync/asardotnet/AsarExceptions.cs b/sync/asardotnet/AsarExceptions.cs index 48b85ea..9c5d9e9 100644 --- a/sync/asardotnet/AsarExceptions.cs +++ b/sync/asardotnet/AsarExceptions.cs @@ -27,32 +27,39 @@ using System; -namespace asardotnet { - public enum AsarException { +namespace asardotnet +{ + public enum AsarException + { ASAR_FILE_CANT_FIND, ASAR_FILE_CANT_READ, ASAR_INVALID_DESCRIPTOR, ASAR_INVALID_FILE_SIZE - }; + } - public class AsarExceptions: Exception { + public class AsarExceptions : Exception + { private readonly AsarException _asarException; + private readonly string _asarMessage; public AsarExceptions(AsarException ex) : this(ex, "") { } - public AsarExceptions(AsarException ex, String customMessage) { + public AsarExceptions(AsarException ex, String customMessage) + { _asarException = ex; - if(customMessage.Length > 0) + if (customMessage.Length > 0) _asarMessage = customMessage; else _asarMessage = GetMessage(ex); } - private String GetMessage(AsarException ex) { - String result; + private string GetMessage(AsarException ex) + { + string result; - switch(ex) { + switch (ex) + { case AsarException.ASAR_FILE_CANT_FIND: result = "Error: The specified file couldn't be found."; break; @@ -73,15 +80,18 @@ private String GetMessage(AsarException ex) { return result; } - public AsarException GetExceptionCode() { + public AsarException GetExceptionCode() + { return _asarException; } - public String GetExceptionMessage() { + public string GetExceptionMessage() + { return _asarMessage; } - override public String ToString() { + override public String ToString() + { return "(Code " + GetExceptionCode() + ") " + GetExceptionMessage(); } } diff --git a/sync/asardotnet/AsarExtractor.cs b/sync/asardotnet/AsarExtractor.cs index 9ec1982..14f4500 100644 --- a/sync/asardotnet/AsarExtractor.cs +++ b/sync/asardotnet/AsarExtractor.cs @@ -28,24 +28,22 @@ using System; using System.Collections.Generic; -using System.Data.Odbc; -using System.Diagnostics; using System.IO; using System.Linq; -using System.Runtime.Remoting; -using System.Security.Cryptography; -using Newtonsoft.Json; using Newtonsoft.Json.Linq; -namespace asardotnet { - public class AsarExtractor { - - public Boolean Extract(AsarArchive archive, String filepath, String destination) { - String[] path = filepath.Split('/'); +namespace asardotnet +{ + public class AsarExtractor + { + public bool Extract(AsarArchive archive, string filepath, string destination) + { + string[] path = filepath.Split('/'); JToken token = archive.GetHeader().GetHeaderJson(); - for(int i = 0; i < path.Length; i++) { + for (int i = 0; i < path.Length; i++) + { token = token["files"][path[i]]; } @@ -59,85 +57,120 @@ public Boolean Extract(AsarArchive archive, String filepath, String destination) return false; } - private List _filesToExtract; - private bool _emptyDir = false; + private List filesToExtract; + + public Dictionary unpackedFiles = new Dictionary(); + + private readonly bool verbose = false; + + private struct AFile + { + private readonly string path; + + public string GetPath() { return path; } + + private readonly int size; + + public int GetSize() { return size; } + + private readonly int offset; + + public int GetOffset() { return offset; } - public Boolean ExtractAll(AsarArchive archive, String destination, bool emptyDir = false) { - _filesToExtract = new List(); + public AFile(string path, int size, int offset) + { + this.path = path; + this.size = size; + this.offset = offset; + } + } + + private void TokenIterator(JObject jObj, string fullPath) + { + foreach (KeyValuePair entry in jObj) + { + if (entry.Value["files"] != null) + { + var newPath = fullPath + entry.Key + Path.DirectorySeparatorChar; + var newDir = new AFile(newPath, -1, -1); + this.filesToExtract.Add(newDir); + TokenIterator((JObject)entry.Value["files"], newPath); + } + if (entry.Value["unpacked"] != null && entry.Value["size"] != null) + { + if (bool.Parse(entry.Value["unpacked"].ToString())) + { + this.unpackedFiles.Add(fullPath + entry.Key, int.Parse(entry.Value["size"].ToString())); + } + } + if (entry.Value["size"] != null && entry.Value["offset"] != null) + { + int size = int.Parse(entry.Value["size"].ToString()); + int offset = int.Parse(entry.Value["offset"].ToString()); + var aFile = new AFile(fullPath + entry.Key, size, offset); + this.filesToExtract.Add(aFile); + } + } + } - /* ENABLE FOR EMPTY FOLDERS (ONLY IF NEEDED) */ - _emptyDir = emptyDir; + public bool ExtractAll(AsarArchive archive, string destination) + { + filesToExtract = new List(); JObject jObject = archive.GetHeader().GetHeaderJson(); - if(jObject.HasValues) - TokenIterator(jObject.First); + + if (jObject.HasValues) + TokenIterator((JObject)jObject["files"], ""); + + Console.WriteLine($"Extracting files to: {destination} .."); byte[] bytes = archive.GetBytes(); - foreach(AFile aFile in _filesToExtract) { + foreach (AFile aFile in filesToExtract) + { + if (verbose) + Console.WriteLine($"Extracting.. {aFile.GetPath()}"); + int size = aFile.GetSize(); + int offset = archive.GetBaseOffset() + aFile.GetOffset(); - if(size > -1) { - byte[] fileBytes = new byte[size]; + if (size > -1) + { + byte[] fileBytes = new byte[size]; Buffer.BlockCopy(bytes, offset, fileBytes, 0, size); - Utilities.WriteFile(fileBytes, destination + aFile.GetPath()); - } else { - if(_emptyDir) - Utilities.CreateDirectory(destination + aFile.GetPath()); + try + { + Utilities.WriteFile(fileBytes, Path.Combine(destination, aFile.GetPath())); + } + catch (PathTooLongException) + { + Console.WriteLine($"Error unpacking {aFile.GetPath()}"); + Console.WriteLine("File name is too long. Try setting current directory to a shorter path (e.g. c:\temp)"); + return false; + } + } + else + { + Utilities.CreateDirectory(Path.Combine(destination, aFile.GetPath())); } } - return false; + return true; } - private struct AFile { - private String _path; - public String GetPath() { return _path; } - private int _size; - public int GetSize() { return _size; } - private int _offset; - public int GetOffset() { return _offset; } - - public AFile(String path, String fileName, int size, int offset) { - path = path.Replace("['", "").Replace("']", ""); - path = path.Substring(0, path.Length - fileName.Length); - path = path.Replace(".files.", "/").Replace("files.", ""); - path += fileName; - - _path = path; - _size = size; - _offset = offset; - } - } + public void ListAll(AsarArchive archive) + { + filesToExtract = new List(); - private void TokenIterator(JToken jToken) { - JProperty jProperty = jToken as JProperty; - - foreach(JProperty prop in jProperty.Value.Children()) { - int size = -1; - int offset = -1; - foreach(JProperty nextProp in prop.Value.Children()) { - if(nextProp.Name == "files") { - /* ENABLE FOR EMPTY FOLDERS (ONLY IF NEEDED) */ - if(_emptyDir) { - AFile afile = new AFile(prop.Path, "", size, offset); - _filesToExtract.Add(afile); - } - - TokenIterator(nextProp); - } else { - if(nextProp.Name == "size") - size = Int32.Parse(nextProp.Value.ToString()); - if(nextProp.Name == "offset") - offset = Int32.Parse(nextProp.Value.ToString()); - } - } + JObject jObject = archive.GetHeader().GetHeaderJson(); - if(size > -1 && offset > -1) { - AFile afile = new AFile(prop.Path, prop.Name, size, offset); - _filesToExtract.Add(afile); - } + if (jObject.HasValues) + TokenIterator((JObject)jObject["files"], ""); + + foreach (var aFile in filesToExtract) + { + Console.WriteLine(aFile.GetPath()); } } } diff --git a/sync/asardotnet/AsarPacker.cs b/sync/asardotnet/AsarPacker.cs new file mode 100644 index 0000000..44dd4cc --- /dev/null +++ b/sync/asardotnet/AsarPacker.cs @@ -0,0 +1,246 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using Newtonsoft.Json; + +namespace asardotnet +{ + public class AsarIntegrity + { + public const int blockSize = 0x400000; + + public readonly string algorithm = "SHA256"; + + public string hash; + + public string[] blocks; + + public AsarIntegrity(string filePath) + { + this.hash = GetSha256Sum(filePath); + this.blocks = GetSha256SumBlocks(filePath); + } + + private static string[] GetSha256SumBlocks(string filePath) + { + List hashes = new List(); + byte[] buffer = new byte[blockSize]; + int bytesRead; + using (FileStream fs = File.Open(filePath, FileMode.Open, FileAccess.Read)) + using (BufferedStream bs = new BufferedStream(fs)) + { + while ((bytesRead = bs.Read(buffer, 0, blockSize)) != 0) + { + byte[] chunk = new byte[bytesRead]; + Array.Copy(buffer, chunk, bytesRead); + hashes.Add(GetSha256Sum(chunk)); + } + } + return hashes.ToArray(); + } + + public static string GetSha256Sum(string filename) + { + using (SHA256 sha256 = SHA256.Create()) + using (FileStream stream = File.OpenRead(filename)) + { + return BitConverter.ToString( + sha256.ComputeHash(stream)) + .Replace("-", string.Empty).ToLower(); + } + } + + public static string GetSha256Sum(byte[] input) + { + using (SHA256 sha256 = SHA256.Create()) + { + return BitConverter.ToString(sha256.ComputeHash(input)) + .Replace("-", string.Empty).ToLower(); + } + } + } + + public class UnpackedAsarFile + { + public long size; + + public bool unpacked = true; + } + + public class AsarFile + { + public long size; + + public string offset; + + public AsarIntegrity integrity; + } + + public class AsarFileNoIntegrity + { + public long size; + + public string offset; + + } + + public class AsarDirectory + { + public Dictionary files = new Dictionary(); + } + + public class AsarPacker + { + internal bool skipIntegrity = false; + + private string rootDir; + + private long offset = 0; + + private readonly bool verbose = false; + + private Dictionary unpackedFiles = new Dictionary(); + + private AsarDirectory WalkDirectory(AsarDirectory dir, string sourceDir, MemoryStream ms) + { + foreach (var entry in Directory.GetFileSystemEntries(sourceDir, "*", SearchOption.TopDirectoryOnly)) + { + var attrs = File.GetAttributes(entry); + var fileInfo = new FileInfo(entry); + string curPath = entry.Replace(rootDir, string.Empty).Replace(@"\", "/").TrimStart('/'); + + if (!attrs.HasFlag(FileAttributes.Directory)) + { + // Entry is a file + if (verbose) + Console.WriteLine($"Adding file {Path.GetFullPath(entry)}"); + + if (!skipIntegrity) + { + // create the integrity block + AsarFile asarFile = new AsarFile + { + offset = offset.ToString(), + size = fileInfo.Length, + integrity = new AsarIntegrity(entry), + }; + dir.files.Add(Path.GetFileName(entry), asarFile); + } + else + { + AsarFileNoIntegrity asarFile = new AsarFileNoIntegrity + { + offset = offset.ToString(), + size = fileInfo.Length, + }; + dir.files.Add(Path.GetFileName(entry), asarFile); + } + + using (var fs = new FileStream(entry, FileMode.Open)) + { + fs.CopyTo(ms); + offset += fileInfo.Length; + } + } + else + { + // Entry is a directory + var dirInfo = new DirectoryInfo(entry); + + if (verbose) + Console.WriteLine($"Adding directory {dirInfo.FullName}"); + + AsarDirectory asarDir = new AsarDirectory(); + asarDir = WalkDirectory(asarDir, dirInfo.FullName, ms); + + // Insert any "unpacked" files that belong to this directory (if any) + foreach (var key in unpackedFiles.Keys) + { + var uDir = Path.GetDirectoryName(key); + + var thisDir = dirInfo.FullName.Replace(rootDir, string.Empty).TrimStart('\\'); + + if (uDir == thisDir) + { + // Mark file as unpacked and don't append data to archive + UnpackedAsarFile unpackedFile = new UnpackedAsarFile + { + size = unpackedFiles[key], + unpacked = true + }; + + if (verbose) + Console.WriteLine($"Adding unpacked file {key}"); + + asarDir.files.Add(Path.GetFileName(key), unpackedFile); + } + } + + // Add new directory branch + dir.files.Add(dirInfo.Name, asarDir); + } + } + return dir; + } + + internal static byte[] CreateSHA256(string input) + { + using (SHA256 sha256 = SHA256.Create()) + { + return sha256.ComputeHash(Encoding.UTF8.GetBytes(input)); + } + } + + public void Pack(string sourceDir, string destFile, Dictionary unpackedFiles = null, + bool skipIntegrity = true, bool created = false) + { + if (!Directory.Exists(sourceDir)) + { + Console.WriteLine("Source directory does not exist!"); + return; + } + + Console.WriteLine($"Packing {sourceDir} .."); + + if (unpackedFiles != null) + this.unpackedFiles = unpackedFiles; + + if (skipIntegrity) + this.skipIntegrity = true; + + this.rootDir = sourceDir; + + using (var ms = new MemoryStream()) + { + AsarDirectory root = new AsarDirectory(); + + // First we generate the json table of contents + root = WalkDirectory(root, sourceDir, ms); + + string json = JsonConvert.SerializeObject(root); + + // finally write the header + using (var ms2 = new MemoryStream()) + using (var bw = new BinaryWriter(ms2)) + { + byte[] padding = created ? + CreateSHA256(this.GetType().Namespace).ToArray() : + new byte[] { 0x00, 0x00, 0x00, 0x00 }; + + bw.Write(0x04); + bw.Write(json.Length + padding.Length + 8); + bw.Write(json.Length + padding.Length + 4); + bw.Write(json.Length); + bw.Write(Encoding.UTF8.GetBytes(json)); + bw.Write(padding); + bw.Write(ms.ToArray()); + File.WriteAllBytes(destFile, ms2.ToArray()); + Console.WriteLine(this.GetType().Namespace); + } + } + } + } +} diff --git a/sync/asardotnet/Utilities.cs b/sync/asardotnet/Utilities.cs index c3f80f6..125097b 100644 --- a/sync/asardotnet/Utilities.cs +++ b/sync/asardotnet/Utilities.cs @@ -26,30 +26,30 @@ * */ using System; -using System.Diagnostics; using System.IO; -using System.Security.Cryptography; -using System.Text; -namespace asardotnet { - public class Utilities { - - public static void WriteFile(byte[] bytes, String destination) { +namespace asardotnet +{ + public class Utilities + { + public static void WriteFile(byte[] bytes, string destination) + { // Debug.Print("Writing bytes to : " + destination); - String dirPath = Path.GetDirectoryName(destination); - String filename = Path.GetFileName(destination); + string dirPath = Path.GetDirectoryName(destination); + string filename = Path.GetFileName(destination); Directory.CreateDirectory(dirPath); File.WriteAllBytes(destination, bytes); } - public static void CreateDirectory(String path) { - if(!Directory.Exists(path)) { + public static void CreateDirectory(string path) + { + if (!Directory.Exists(path)) + { Directory.CreateDirectory(path); } } - } } diff --git a/sync/asardotnet/asardotnet.csproj b/sync/asardotnet/asardotnet.csproj index 88594c8..0c48709 100644 --- a/sync/asardotnet/asardotnet.csproj +++ b/sync/asardotnet/asardotnet.csproj @@ -9,8 +9,9 @@ Properties asardotnet asardotnet - v4.5 + v4.5.1 512 + true @@ -46,6 +47,7 @@ + From a125d15793d02c7b08370915f22eb15aff1976ac Mon Sep 17 00:00:00 2001 From: rxwx Date: Thu, 8 Sep 2022 21:56:37 +0100 Subject: [PATCH 2/2] Remove debugging --- sync/asardotnet/AsarPacker.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/sync/asardotnet/AsarPacker.cs b/sync/asardotnet/AsarPacker.cs index 44dd4cc..4802cb4 100644 --- a/sync/asardotnet/AsarPacker.cs +++ b/sync/asardotnet/AsarPacker.cs @@ -238,7 +238,6 @@ public void Pack(string sourceDir, string destFile, Dictionary unpa bw.Write(padding); bw.Write(ms.ToArray()); File.WriteAllBytes(destFile, ms2.ToArray()); - Console.WriteLine(this.GetType().Namespace); } } }