public void AttachFile_Template(string fileName) { EngineState s = EngineTests.CreateEngineState(); string dirPath = StringEscaper.Preprocess(s, Path.Combine("%TestBench%", "EncodedFile")); string blankPath = Path.Combine(dirPath, "EncodeFileTests_Blank.script"); string pPath = Path.Combine(dirPath, "EncodeFileTests.script"); File.Copy(blankPath, pPath, true); Plugin p = s.Project.LoadPluginMonkeyPatch(pPath); string originFile = Path.Combine(dirPath, fileName); p = EncodedFile.AttachFile(p, "FolderExample", fileName, originFile, EncodedFile.EncodeMode.Compress); try { // Check whether file was successfully encoded Assert.IsTrue(p.Sections.ContainsKey("EncodedFolders")); List <string> folders = p.Sections["EncodedFolders"].GetLines(); folders = folders.Where(x => x.Equals(string.Empty, StringComparison.Ordinal) == false).ToList(); Assert.IsTrue(folders.Count == 1); Assert.IsTrue(folders[0].Equals("FolderExample", StringComparison.Ordinal)); Assert.IsTrue(p.Sections.ContainsKey("FolderExample")); List <string> fileInfos = p.Sections["FolderExample"].GetLinesOnce(); fileInfos = fileInfos.Where(x => x.Equals(string.Empty, StringComparison.Ordinal) == false).ToList(); Assert.IsTrue(fileInfos[0].StartsWith($"{fileName}=", StringComparison.Ordinal)); Assert.IsTrue(p.Sections.ContainsKey($"EncodedFile-FolderExample-{fileName}")); List <string> encodedFile = p.Sections[$"EncodedFile-FolderExample-{fileName}"].GetLinesOnce(); encodedFile = encodedFile.Where(x => x.Equals(string.Empty, StringComparison.Ordinal) == false).ToList(); Assert.IsTrue(1 < encodedFile.Count); Assert.IsTrue(encodedFile[0].StartsWith("lines=", StringComparison.Ordinal)); // Check whether file can be successfully extracted byte[] extractDigest; using (MemoryStream ms = EncodedFile.ExtractFile(p, "FolderExample", fileName)) { extractDigest = HashHelper.CalcHash(HashType.SHA256, ms); } byte[] originDigest; using (FileStream fs = new FileStream(originFile, FileMode.Open)) { originDigest = HashHelper.CalcHash(HashType.SHA256, fs); } Assert.IsTrue(originDigest.SequenceEqual(extractDigest)); } finally { File.Delete(pPath); } }
public static List <LogInfo> Encode(EngineState s, CodeCommand cmd) { List <LogInfo> logs = new List <LogInfo>(); Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_Encode)); CodeInfo_Encode info = cmd.Info as CodeInfo_Encode; string pluginFile = StringEscaper.Preprocess(s, info.PluginFile); string dirName = StringEscaper.Preprocess(s, info.DirName); string filePath = StringEscaper.Preprocess(s, info.FilePath); Plugin p = Engine.GetPluginInstance(s, cmd, s.CurrentPlugin.FullPath, pluginFile, out bool inCurrentPlugin); // Check srcFileName contains wildcard if (filePath.IndexOfAny(new char[] { '*', '?' }) == -1) { // No Wildcard EncodedFile.AttachFile(p, dirName, Path.GetFileName(filePath), filePath); logs.Add(new LogInfo(LogState.Success, $"[{filePath}] encoded into [{p.FullPath}]", cmd)); } else { // With Wildcard // Use FileHelper.GetDirNameEx to prevent ArgumentException of Directory.GetFiles string srcDirToFind = FileHelper.GetDirNameEx(filePath); string[] files = Directory.GetFiles(srcDirToFind, Path.GetFileName(filePath)); if (0 < files.Length) { // One or more file will be copied logs.Add(new LogInfo(LogState.Success, $"[{filePath}] will be encoded into [{p.FullPath}]", cmd)); for (int i = 0; i < files.Length; i++) { EncodedFile.AttachFile(p, dirName, Path.GetFileName(files[i]), files[i]); logs.Add(new LogInfo(LogState.Success, $"[{files[i]}] encoded ({i + 1}/{files.Length})", cmd)); } logs.Add(new LogInfo(LogState.Success, $"[{files.Length}] files copied", cmd)); } else { // No file will be copied logs.Add(new LogInfo(LogState.Warning, $"Files match wildcard [{filePath}] not found", cmd)); } } return(logs); }
public static List <LogInfo> EchoFile(EngineState s, CodeCommand cmd) { List <LogInfo> logs = new List <LogInfo>(); Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_EchoFile)); CodeInfo_EchoFile info = cmd.Info as CodeInfo_EchoFile; string srcFile = StringEscaper.Preprocess(s, info.SrcFile); if (!File.Exists(srcFile)) { logs.Add(new LogInfo(LogState.Warning, $"File [{srcFile}] does not exist", cmd)); return(logs); } if (info.Encode) { // Binary Mode -> encode files into log database string tempFile = Path.GetRandomFileName(); try { // Create dummy plugin instance FileHelper.WriteTextBOM(tempFile, Encoding.UTF8); Plugin p = cmd.Addr.Project.LoadPlugin(tempFile, true, false); // Encode binary file into plugin instance string fileName = Path.GetFileName(srcFile); EncodedFile.AttachFile(p, "Folder", fileName, srcFile, EncodedFile.EncodeMode.Compress); // Remove Plugin instance p = null; // Read encoded text strings into memory string txtStr; Encoding encoding = FileHelper.DetectTextEncoding(tempFile); using (StreamReader r = new StreamReader(tempFile, encoding)) { txtStr = r.ReadToEnd(); } string logStr; if (txtStr.EndsWith("\r\n", StringComparison.Ordinal)) { logStr = $"Encoded File [{srcFile}]\r\n{txtStr}"; } else { logStr = $"Encoded File [{srcFile}]\r\n{txtStr}\r\n"; } s.MainViewModel.BuildEchoMessage = logStr; logs.Add(new LogInfo(info.Warn ? LogState.Warning : LogState.Success, logStr, cmd)); } finally { File.Delete(tempFile); } } else { // Text Mode -> Just read with StreamReader string txtStr; Encoding encoding = FileHelper.DetectTextEncoding(srcFile); using (StreamReader r = new StreamReader(srcFile, encoding)) { txtStr = r.ReadToEnd(); } string logStr; if (txtStr.EndsWith("\r\n", StringComparison.Ordinal)) { logStr = $"File [{srcFile}]\r\n{txtStr}"; } else { logStr = $"File [{srcFile}]\r\n{txtStr}\r\n"; } s.MainViewModel.BuildEchoMessage = logStr; logs.Add(new LogInfo(info.Warn ? LogState.Warning : LogState.Success, logStr, cmd)); } return(logs); }
public static List <LogInfo> Encode(EngineState s, CodeCommand cmd) { List <LogInfo> logs = new List <LogInfo>(); CodeInfo_Encode info = cmd.Info.Cast <CodeInfo_Encode>(); string scriptFile = StringEscaper.Preprocess(s, info.ScriptFile); string dirName = StringEscaper.Preprocess(s, info.DirName); string filePath = StringEscaper.Preprocess(s, info.FilePath); EncodedFile.EncodeMode mode = EncodedFile.EncodeMode.ZLib; if (info.Compression != null) { string encodeModeStr = StringEscaper.Preprocess(s, info.Compression); if (encodeModeStr.Equals("None", StringComparison.OrdinalIgnoreCase)) { mode = EncodedFile.EncodeMode.Raw; } else if (encodeModeStr.Equals("Deflate", StringComparison.OrdinalIgnoreCase)) { mode = EncodedFile.EncodeMode.ZLib; } else if (encodeModeStr.Equals("LZMA2", StringComparison.OrdinalIgnoreCase)) { mode = EncodedFile.EncodeMode.XZ; } else { return(LogInfo.LogErrorMessage(logs, $"[{encodeModeStr}] is invalid compression")); } } Script sc = Engine.GetScriptInstance(s, s.CurrentScript.RealPath, scriptFile, out _); // Check srcFileName contains wildcard if (filePath.IndexOfAny(new char[] { '*', '?' }) == -1) { // No Wildcard s.MainViewModel.SetBuildCommandProgress("Encode Progress", 1); try { object progressLock = new object(); IProgress <double> progress = new Progress <double>(x => { lock (progressLock) { s.MainViewModel.BuildCommandProgressValue = x; if (x < EncodedFile.CompReportFactor) // [Stage 1] Compress { s.MainViewModel.BuildCommandProgressText = $"Compressing \"{filePath}\"\r\n({x * 100:0.0}%)"; } else // [Stage 2] Base64 { s.MainViewModel.BuildCommandProgressText = $"Writing \"{filePath}\" to script\r\n({x * 100:0.0}%)"; } } }); EncodedFile.AttachFile(sc, dirName, Path.GetFileName(filePath), filePath, mode, progress); logs.Add(new LogInfo(LogState.Success, $"[{filePath}] was encoded into [{sc.RealPath}]", cmd)); } finally { s.MainViewModel.ResetBuildCommandProgress(); } } else { // With Wildcard // Use FileHelper.GetDirNameEx to prevent ArgumentException of Directory.GetFiles string srcDirToFind = FileHelper.GetDirNameEx(filePath); string[] files = Directory.GetFiles(srcDirToFind, Path.GetFileName(filePath)); // No file will be compressed if (files.Length == 0) { logs.Add(new LogInfo(LogState.Warning, $"Files matching wildcard [{filePath}] were not found", cmd)); return(logs); } s.MainViewModel.SetBuildCommandProgress("Encode Progress", files.Length); try { int i = 0; object progressLock = new object(); IProgress <double> progress = new Progress <double>(x => { lock (progressLock) { s.MainViewModel.BuildCommandProgressText = $"Attaching {filePath}...\r\n({(x + i) * 100:0.0}%)"; s.MainViewModel.BuildCommandProgressValue = x + i; } }); // One or more file will be copied logs.Add(new LogInfo(LogState.Success, $"[{filePath}] will be encoded into [{sc.RealPath}]", cmd)); foreach (string f in files) { EncodedFile.AttachFile(sc, dirName, Path.GetFileName(f), f, mode, progress); logs.Add(new LogInfo(LogState.Success, $"[{f}] encoded ({i + 1}/{files.Length})", cmd)); i += 1; } logs.Add(new LogInfo(LogState.Success, $"[{files.Length}] files copied", cmd)); } finally { s.MainViewModel.ResetBuildCommandProgress(); } } return(logs); }
public void AttachFile() { void Template(string fileName, EncodedFile.EncodeMode encodeMode) { EngineState s = EngineTests.CreateEngineState(); string srcDir = StringEscaper.Preprocess(s, Path.Combine("%TestBench%", "EncodedFile")); string srcScript = Path.Combine(srcDir, "Blank.script"); string destDir = FileHelper.GetTempDir(); string destScript = Path.Combine(destDir, "EncodeFileTests.script"); File.Copy(srcScript, destScript, true); try { Script sc = s.Project.LoadScriptRuntime(destScript, new LoadScriptRuntimeOptions()); string originFile = Path.Combine(srcDir, fileName); EncodedFile.AttachFile(sc, "FolderExample", fileName, originFile, encodeMode, null); // Check whether file was successfully encoded Assert.IsTrue(sc.Sections.ContainsKey("EncodedFolders")); string[] folders = sc.Sections["EncodedFolders"].Lines .Where(x => x.Length != 0) .ToArray(); Assert.IsTrue(folders.Length == 2); Assert.IsTrue(folders[0].Equals("FolderExample", StringComparison.Ordinal)); Assert.IsTrue(sc.Sections.ContainsKey("FolderExample")); string[] fileInfos = sc.Sections["FolderExample"].Lines .Where(x => x.Length != 0) .ToArray(); Assert.IsTrue(fileInfos[0].StartsWith($"{fileName}=", StringComparison.Ordinal)); Assert.IsTrue(sc.Sections.ContainsKey($"EncodedFile-FolderExample-{fileName}")); string[] encodedFile = sc.Sections[$"EncodedFile-FolderExample-{fileName}"].Lines .Where(x => x.Length != 0) .ToArray(); Assert.IsTrue(1 < encodedFile.Length); Assert.IsTrue(encodedFile[0].StartsWith("lines=", StringComparison.Ordinal)); // Check whether file can be successfully extracted byte[] extractDigest; using (MemoryStream ms = new MemoryStream()) { EncodedFile.ExtractFile(sc, "FolderExample", fileName, ms, null); ms.Position = 0; extractDigest = HashHelper.GetHash(HashHelper.HashType.SHA256, ms); } byte[] originDigest; using (FileStream fs = new FileStream(originFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { originDigest = HashHelper.GetHash(HashHelper.HashType.SHA256, fs); } Assert.IsTrue(originDigest.SequenceEqual(extractDigest)); } finally { if (Directory.Exists(destDir)) { Directory.Delete(destDir, true); } if (File.Exists(destScript)) { File.Delete(destScript); } } } Template("Type1.jpg", EncodedFile.EncodeMode.ZLib); // Type 1 Template("Type2.7z", EncodedFile.EncodeMode.Raw); // Type 2 Template("Type3.pdf", EncodedFile.EncodeMode.XZ); // Type 3 Template("PEBakeryAlphaMemory.jpg", EncodedFile.EncodeMode.ZLib); }