public void ExtractFileInMem()
        {
            void Template(string fileName)
            { // Type 1
                EngineState s         = EngineTests.CreateEngineState();
                string      srcScript = Path.Combine("%TestBench%", "EncodedFile", "ExtractFileTests.script");

                srcScript = StringEscaper.Preprocess(s, srcScript);
                Script sc = s.Project.LoadScriptRuntime(srcScript, new LoadScriptRuntimeOptions());

                byte[] extractDigest;
                using (MemoryStream ms = EncodedFile.ExtractFileInMem(sc, "FolderExample", fileName))
                {
                    ms.Position   = 0;
                    extractDigest = HashHelper.GetHash(HashHelper.HashType.SHA256, ms);
                }

                string originFile = Path.Combine("%TestBench%", "EncodedFile", fileName);

                originFile = StringEscaper.Preprocess(s, originFile);
                byte[] originDigest;
                using (FileStream fs = new FileStream(originFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    originDigest = HashHelper.GetHash(HashHelper.HashType.SHA256, fs);
                }

                // Compare Hash
                Assert.IsTrue(originDigest.SequenceEqual(extractDigest));
            }

            Template("Type1.jpg"); // Type 1
            Template("Type2.7z");  // Type 2
            Template("Type3.pdf"); // Type 3
        }
Exemple #2
0
        public void ExtractInterfaceEncoded_1()
        { // Type 1
            EngineState s     = EngineTests.CreateEngineState();
            string      pPath = Path.Combine("%TestBench%", "EncodedFile", "ExtractFileTests.script");

            pPath = StringEscaper.Preprocess(s, pPath);
            Plugin p = s.Project.LoadPluginMonkeyPatch(pPath);

            byte[] extractDigest;
            using (MemoryStream ms = EncodedFile.ExtractInterfaceEncoded(p, "PEBakeryAlphaMemory.jpg"))
            {
                extractDigest = HashHelper.CalcHash(HashType.SHA256, ms);
            }

            string originFile = Path.Combine("%TestBench%", "EncodedFile", "PEBakeryAlphaMemory.jpg");

            originFile = StringEscaper.Preprocess(s, originFile);
            byte[] originDigest;
            using (FileStream fs = new FileStream(originFile, FileMode.Open))
            {
                originDigest = HashHelper.CalcHash(HashType.SHA256, fs);
            }

            // Compare Hash
            Assert.IsTrue(originDigest.SequenceEqual(extractDigest));
        }
        public void ExtractInterfaceEncoded()
        { // Type 1
            EngineState s      = EngineTests.CreateEngineState();
            string      scPath = Path.Combine("%TestBench%", "EncodedFile", "ExtractFileTests.script");

            scPath = StringEscaper.Preprocess(s, scPath);
            Script sc = s.Project.LoadScriptRuntime(scPath, new LoadScriptRuntimeOptions());

            byte[] extractDigest;
            using (MemoryStream ms = EncodedFile.ExtractInterface(sc, "PEBakeryAlphaMemory.jpg"))
            {
                extractDigest = HashHelper.GetHash(HashHelper.HashType.SHA256, ms);
            }

            string originFile = Path.Combine("%TestBench%", "EncodedFile", "PEBakeryAlphaMemory.jpg");

            originFile = StringEscaper.Preprocess(s, originFile);
            byte[] originDigest;
            using (FileStream fs = new FileStream(originFile, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                originDigest = HashHelper.GetHash(HashHelper.HashType.SHA256, fs);
            }

            // Compare Hash
            Assert.IsTrue(originDigest.SequenceEqual(extractDigest));
        }
Exemple #4
0
        /// <summary>
        /// Render TextFile control.
        /// Return true if failed.
        /// </summary>
        /// <param name="r.Canvas">Parent r.Canvas</param>
        /// <param name="uiCmd">UICommand</param>
        /// <returns>Success = false, Failure = true</returns>
        public static void RenderTextFile(RenderInfo r, UICommand uiCmd)
        {
            Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_TextFile));
            UIInfo_TextFile info = uiCmd.Info as UIInfo_TextFile;

            TextBox textBox;

            using (MemoryStream ms = EncodedFile.ExtractInterfaceEncoded(uiCmd.Addr.Plugin, uiCmd.Text))
                using (StreamReader sr = new StreamReader(ms, FileHelper.DetectTextEncoding(ms)))
                {
                    textBox = new TextBox()
                    {
                        TextWrapping  = TextWrapping.Wrap,
                        AcceptsReturn = true,
                        IsReadOnly    = true,
                        Text          = sr.ReadToEnd(),
                        FontSize      = CalcFontPointScale(),
                    };
                }

            ScrollViewer.SetHorizontalScrollBarVisibility(textBox, ScrollBarVisibility.Auto);
            ScrollViewer.SetVerticalScrollBarVisibility(textBox, ScrollBarVisibility.Auto);
            ScrollViewer.SetCanContentScroll(textBox, true);

            SetToolTip(textBox, info.ToolTip);
            DrawToCanvas(r, textBox, uiCmd.Rect);
        }
        public void ExtractLogo_1()
        { // Type 1
            EngineState s     = EngineTests.CreateEngineState();
            string      pPath = Path.Combine("%TestBench%", "EncodedFile", "ExtractFileTests.script");

            pPath = StringEscaper.Preprocess(s, pPath);
            Script p = s.Project.LoadScriptMonkeyPatch(pPath);

            byte[] extractDigest;
            using (MemoryStream ms = EncodedFile.ExtractLogo(p, out ImageHelper.ImageType type))
            {
                Assert.IsTrue(type == ImageHelper.ImageType.Jpg);
                extractDigest = HashHelper.CalcHash(HashType.SHA256, ms);
            }

            string originFile = Path.Combine("%TestBench%", "EncodedFile", "Logo.jpg");

            originFile = StringEscaper.Preprocess(s, originFile);
            byte[] originDigest;
            using (FileStream fs = new FileStream(originFile, FileMode.Open))
            {
                originDigest = HashHelper.CalcHash(HashType.SHA256, fs);
            }

            // Compare Hash
            Assert.IsTrue(originDigest.SequenceEqual(extractDigest));
        }
        private static string SubstituteFiles(EncodedFile file, IEnumerable <KeyValuePair <string, string[]> > settings)
        {
            var matches = SubfileRegex.Matches(file.Contents).Cast <Match>();

            if (!matches.Any())
            {
                return(file.Contents);
            }

            var content = file.Contents;

            foreach (var match in matches)
            {
                var filename        = match.Groups["KEY"].Value;
                var fullSubFilePath = Path.Combine(file.Directory.FullName, filename);

                if (!File.Exists(fullSubFilePath))
                {
                    throw new Exception(string.Format("Sub-file \"{0}\" not found when substituting \"{1}\"", fullSubFilePath, file.File.FullName));
                }

                SubstituteFile(fullSubFilePath, settings);

                var subFile = Helpers.GetFileWithEncodingNoBom(fullSubFilePath);

                //TODO: Check for differing encodings

                content = SubstituteString(content, "+{" + filename + "}", subFile.Contents, '`');
            }

            return(content);
        }
        public void DeleteFolder()
        {
            EngineState s = EngineTests.CreateEngineState();
            string      originScriptPath = Path.Combine(StringEscaper.Preprocess(s, "%TestBench%"), "EncodedFile", "ExtractFileTests.script");

            // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local
            void Template(string folderName, bool result)
            {
                string destDir    = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
                string destScript = Path.Combine(destDir, "DeleteFolderTest.script");

                Directory.CreateDirectory(destDir);
                try
                {
                    File.Copy(originScriptPath, destScript, true);

                    Script sc = s.Project.LoadScriptRuntime(destScript, new LoadScriptRuntimeOptions());

                    Dictionary <string, string> fileDict = null;
                    if (result)
                    {
                        fileDict = sc.Sections[folderName].IniDict;
                    }

                    string errMsg;
                    (sc, errMsg) = EncodedFile.DeleteFolder(sc, folderName);

                    if (errMsg != null)
                    {
                        Assert.IsFalse(result);
                        return;
                    }
                    Assert.IsTrue(result);

                    Assert.IsFalse(sc.Sections.ContainsKey(folderName));
                    Assert.IsFalse(IniReadWriter.ContainsSection(destScript, folderName));

                    string[] folders = sc.Sections[EncodedFolders].Lines;
                    Assert.IsFalse(folders.Contains(folderName, StringComparer.OrdinalIgnoreCase));

                    foreach (string fileName in fileDict.Keys)
                    {
                        Assert.IsFalse(sc.Sections.ContainsKey(GetSectionName(folderName, fileName)));
                    }
                }
                finally
                {
                    if (Directory.Exists(destDir))
                    {
                        Directory.Delete(destDir, true);
                    }
                }
            }

            Template("FolderExample", true);
            Template("BannerImage", true);
            Template(AuthorEncoded, true);
            Template(InterfaceEncoded, true);
            Template("ShouldFail", false);
        }
        public void ExtractFolder()
        {
            EngineState s = EngineTests.CreateEngineState();

            void Template(string folderName)
            {
                string pbOriginScript = Path.Combine("%TestBench%", "EncodedFile", "ExtractFileTests.script");
                string originScript   = StringEscaper.Preprocess(s, pbOriginScript);

                string destDir = FileHelper.GetTempDir();

                try
                {
                    Script sc = s.Project.LoadScriptRuntime(originScript, new LoadScriptRuntimeOptions());

                    EncodedFile.ExtractFolder(sc, folderName, destDir);

                    string[] comps = IniReadWriter.ParseIniLinesIniStyle(sc.Sections[folderName].Lines).Keys.ToArray();
                    string[] dests = Directory.EnumerateFiles(destDir).Select(Path.GetFileName).ToArray();

                    Assert.IsTrue(comps.SequenceEqual(dests, StringComparer.OrdinalIgnoreCase));
                }
                finally
                {
                    if (Directory.Exists(destDir))
                    {
                        Directory.Delete(destDir, true);
                    }
                }
            }

            Template("FolderExample");
        }
        public void ExtractFile_Template(string fileName)
        { // Type 1
            EngineState s     = EngineTests.CreateEngineState();
            string      pPath = Path.Combine("%TestBench%", "EncodedFile", "ExtractFileTests.script");

            pPath = StringEscaper.Preprocess(s, pPath);
            Script p = s.Project.LoadScriptMonkeyPatch(pPath);

            byte[] extractDigest;
            using (MemoryStream ms = EncodedFile.ExtractFile(p, "FolderExample", fileName))
            {
                extractDigest = HashHelper.CalcHash(HashType.SHA256, ms);
            }

            string originFile = Path.Combine("%TestBench%", "EncodedFile", fileName);

            originFile = StringEscaper.Preprocess(s, originFile);
            byte[] originDigest;
            using (FileStream fs = new FileStream(originFile, FileMode.Open))
            {
                originDigest = HashHelper.CalcHash(HashType.SHA256, fs);
            }

            // Compare Hash
            Assert.IsTrue(originDigest.SequenceEqual(extractDigest));
        }
Exemple #10
0
        public static List <LogInfo> ExtractAllFiles(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>();

            Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_ExtractAllFiles));
            CodeInfo_ExtractAllFiles info = cmd.Info as CodeInfo_ExtractAllFiles;

            string pluginFile = StringEscaper.Preprocess(s, info.PluginFile);
            string dirName    = StringEscaper.Preprocess(s, info.DirName);
            string destDir    = StringEscaper.Preprocess(s, info.DestDir);

            Plugin p = Engine.GetPluginInstance(s, cmd, s.CurrentPlugin.FullPath, pluginFile, out bool inCurrentPlugin);

            if (StringEscaper.PathSecurityCheck(destDir, out string errorMsg) == false)
            {
                logs.Add(new LogInfo(LogState.Error, errorMsg));
                return(logs);
            }

            List <string> dirs         = p.Sections["EncodedFolders"].Lines;
            bool          dirNameValid = dirs.Any(d => d.Equals(dirName, StringComparison.OrdinalIgnoreCase));

            if (dirNameValid == false)
            {
                throw new ExecuteException($"Directory [{dirName}] not exists in [{pluginFile}]");
            }

            if (!Directory.Exists(destDir))
            {
                if (File.Exists(destDir))
                {
                    logs.Add(new LogInfo(LogState.Error, $"File [{destDir}] is not a directory"));
                    return(logs);
                }
                else
                {
                    logs.Add(new LogInfo(LogState.Error, $"Directory [{destDir}] does not exist"));
                    return(logs);
                }
            }

            List <string> lines = p.Sections[dirName].Lines;
            Dictionary <string, string> fileDict = Ini.ParseIniLinesIniStyle(lines);

            foreach (string file in fileDict.Keys)
            {
                using (MemoryStream ms = EncodedFile.ExtractFile(p, dirName, file))
                    using (FileStream fs = new FileStream(Path.Combine(destDir, file), FileMode.Create, FileAccess.Write))
                    {
                        ms.Position = 0;
                        ms.CopyTo(fs);
                    }
            }

            logs.Add(new LogInfo(LogState.Success, $"Encoded folder [{dirName}] extracted to [{destDir}]"));

            return(logs);
        }
Exemple #11
0
        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);
            }
        }
Exemple #12
0
        public SourceFile Run(EncodedFile encoded, string outputPath)
        {
            var rleDecoder     = new RleDecoder();
            var huffmanDecoder = new HuffmanDecoder(encoded.Header.HuffmanMetadata);

            var bytes   = encoded.Content.ToArray();
            var decoded = huffmanDecoder.Decode(bytes);
            var outRle  = rleDecoder.Decode(decoded);

            return(new SourceFile(outputPath, outRle, encoded.Header.SourceExtension));
        }
 public void PrintLzma2CompressMemUsage()
 {
     foreach (LzmaCompLevel level in Enum.GetValues(typeof(LzmaCompLevel)))
     {
         for (int th = 1; th <= Environment.ProcessorCount * 2; th++)
         {
             ulong  usage    = EncodedFile.QueryLzma2CompressMemUsage(level, th);
             string usageStr = NumberHelper.ByteSizeToSIUnit((long)usage, 1);
             Console.WriteLine($"Memory usage of {level}, Threads {th} = {usageStr} ({usage})");
         }
     }
 }
Exemple #14
0
        public SourceFile Run(EncodedFile encoded, string outputPath)
        {
            var lzwDecoder     = new LZWDecompress();
            var huffmanDecoder = new HuffmanDecoder(encoded.Header.HuffmanMetadata);

            var bytes   = encoded.Content.ToArray();
            var decoded = huffmanDecoder.Decode(bytes);
            var input   = Encoding.ASCII.GetString(decoded);
            var outLzw  = lzwDecoder.Decompress(input);

            return(new SourceFile(outputPath, outLzw, encoded.Header.SourceExtension));
        }
        public void RenameFile()
        {
            EngineState s = EngineTests.CreateEngineState();
            string      originScriptPath = Path.Combine(StringEscaper.Preprocess(s, "%TestBench%"), "EncodedFile", "ExtractFileTests.script");

            // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local
            void Template(string folderName, string oldFileName, string newFileName, bool result)
            {
                string destDir    = FileHelper.GetTempDir();
                string destScript = Path.Combine(destDir, "RenameFileTest.script");

                try
                {
                    File.Copy(originScriptPath, destScript, true);

                    Script sc = s.Project.LoadScriptRuntime(destScript, new LoadScriptRuntimeOptions());

                    string errMsg;
                    (sc, errMsg) = EncodedFile.RenameFile(sc, folderName, oldFileName, newFileName);
                    if (errMsg != null)
                    {
                        Assert.IsFalse(result);
                        return;
                    }

                    Assert.IsTrue(result);

                    Assert.IsFalse(sc.Sections.ContainsKey(GetSectionName(folderName, oldFileName)));
                    Assert.IsTrue(sc.Sections.ContainsKey(GetSectionName(folderName, newFileName)));

                    Dictionary <string, string> fileDict = sc.Sections[folderName].IniDict;
                    Assert.IsFalse(fileDict.ContainsKey(oldFileName));
                    Assert.IsTrue(fileDict.ContainsKey(newFileName));
                }
                finally
                {
                    if (Directory.Exists(destDir))
                    {
                        Directory.Delete(destDir, true);
                    }
                }
            }

            Template("FolderExample", "Type1.jpg", "JPEG.jpg", true);
            Template("FolderExample", "Type2.7z", "LZMA2.7z", true);
            Template("FolderExample", "Type3.pdf", "Postscript.pdf", true);
            Template(AuthorEncoded, "Logo.jpg", "L.jpg", true);
            Template(InterfaceEncoded, "PEBakeryAlphaMemory.jpg", "P.jpg", true);

            Template("BannerImage", "Should.fail", "Should.fail.2", false);
            Template("ShouldFail", "Should.fail", "Should.fail.2", false);
        }
Exemple #16
0
        public EncodedFile Run(SourceFile source)
        {
            var rleEncoder     = new RleEncoder();
            var huffmanEncoder = new HuffmanEncoder();

            var outRle     = rleEncoder.Encode(source.Content);
            var outHuffman = huffmanEncoder.Encode(outRle);

            var header      = new FileHeader(Pipeline, huffmanEncoder.HuffmanMetadata, source.Extension);
            var encodedFile = new EncodedFile(header, outHuffman);

            return(encodedFile);
        }
Exemple #17
0
        public void WriteEncoded(EncodedFile file)
        {
            var entireFile = new HeaderParser().WriteHeader(file.Header, file.Content);

            var path = file.Path;
            var index = path.LastIndexOf('.');
            if (index > -1)
            {
                path = path.Remove(index, path.Length - index);                
            }
            path += ".rsb";

            File.WriteAllBytes(path, entireFile);
        }
        public void GetLogoInfo()
        {
            EngineState s         = EngineTests.CreateEngineState();
            string      scriptDir = Path.Combine(StringEscaper.Preprocess(s, "%TestBench%"), "EncodedFile");

            string logoScriptFile = Path.Combine(scriptDir, "Blank.script");
            Script logoScript     = s.Project.LoadScriptRuntime(logoScriptFile, new LoadScriptRuntimeOptions());

            string noLogoScriptFile = Path.Combine(scriptDir, "CompleteBlank.script");
            Script noLogoScript     = s.Project.LoadScriptRuntime(noLogoScriptFile, new LoadScriptRuntimeOptions());

            // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local
            void Template(Script testScript, bool detail, EncodedFileInfo comp)
            {
                ResultReport <EncodedFileInfo> report = EncodedFile.GetLogoInfo(testScript, detail);

                if (comp == null)
                {
                    Assert.IsFalse(report.Success);
                    Assert.IsNull(report.Result);
                }
                else
                {
                    Assert.IsTrue(report.Success);
                    Assert.IsTrue(report.Result.Equals(comp));
                }
            }

            Template(logoScript, true, new EncodedFileInfo
            {
                FolderName  = "AuthorEncoded",
                FileName    = "logo.jpg",
                RawSize     = 973,
                EncodedSize = 1298,
                EncodeMode  = EncodedFile.EncodeMode.ZLib
            });
            Template(logoScript, false, new EncodedFileInfo
            {
                FolderName  = "authorEncoded",
                FileName    = "Logo.jpg",
                RawSize     = 973,
                EncodedSize = 1298,
                EncodeMode  = null
            });

            Template(noLogoScript, true, null);
            Template(noLogoScript, false, null);
        }
        public void ContainsLogo()
        {
            void Template(string fileName, bool result)
            {
                EngineState s = EngineTests.CreateEngineState();
                string      pbOriginScript = Path.Combine("%TestBench%", "EncodedFile", fileName);
                string      originScript   = StringEscaper.Preprocess(s, pbOriginScript);

                Script sc = s.Project.LoadScriptRuntime(originScript, new LoadScriptRuntimeOptions());

                Assert.AreEqual(EncodedFile.ContainsLogo(sc), result);
            }

            Template("Blank.script", true);
            Template("CompleteBlank.script", false);
        }
Exemple #20
0
        /*
         * WB082 Behavior
         * ExtractFile : DestDir must be Directory, create if not exists.
         * Ex) (...),README.txt,%BaseDir%\Temp\Hello
         *   -> No Hello : Create direcotry "Hello" and extract files into new directory.
         *   -> Hello is a file : Failure
         *   -> Hello is a directory : Extract files into directory.
         *
         * ExtractAllFiles
         * Ex) (...),Fonts,%BaseDir%\Temp\Hello
         *   -> No Hello : Failure
         *   -> Hello is a file : Failure
         *   -> Hello is a direcotry : Extract files into directory.
         *
         */

        public static List <LogInfo> ExtractFile(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>();

            Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_ExtractFile));
            CodeInfo_ExtractFile info = cmd.Info as CodeInfo_ExtractFile;

            string pluginFile = StringEscaper.Preprocess(s, info.PluginFile);
            string dirName    = StringEscaper.Preprocess(s, info.DirName);
            string fileName   = StringEscaper.Preprocess(s, info.FileName);
            string destDir    = StringEscaper.Preprocess(s, info.DestDir); // Should be directory name

            Plugin p = Engine.GetPluginInstance(s, cmd, s.CurrentPlugin.FullPath, pluginFile, out bool inCurrentPlugin);

            if (StringEscaper.PathSecurityCheck(destDir, out string errorMsg) == false)
            {
                logs.Add(new LogInfo(LogState.Error, errorMsg));
                return(logs);
            }

            if (!Directory.Exists(destDir)) // DestDir already exists
            {
                if (File.Exists(destDir))   // Error, cannot proceed
                {
                    logs.Add(new LogInfo(LogState.Error, $"File [{destDir}] is not a directory."));
                    return(logs);
                }
                else
                {
                    Directory.CreateDirectory(destDir);
                }
            }

            string destPath = Path.Combine(destDir, fileName);

            using (MemoryStream ms = EncodedFile.ExtractFile(p, dirName, fileName))
                using (FileStream fs = new FileStream(destPath, FileMode.Create, FileAccess.Write))
                {
                    ms.Position = 0;
                    ms.CopyTo(fs);
                }

            logs.Add(new LogInfo(LogState.Success, $"Encoded file [{fileName}] extracted to [{destDir}]"));

            return(logs);
        }
        public void ContainsFile()
        {
            void Template(string scriptPath, string folderName, string fileName, bool result)
            {
                EngineState s = EngineTests.CreateEngineState();
                string      pbOriginScript = Path.Combine("%TestBench%", "EncodedFile", scriptPath);
                string      originScript   = StringEscaper.Preprocess(s, pbOriginScript);

                Script sc = s.Project.LoadScriptRuntime(originScript, new LoadScriptRuntimeOptions());

                Assert.AreEqual(EncodedFile.ContainsFile(sc, folderName, fileName), result);
            }

            Template("ExtractFileTests.script", "FolderExample", "Type1.jpg", true);
            Template("ExtractFileTests.script", "FolderExample", "ShouldFail", false);
            Template("ExtractFileTests.script", "ShouldFail", "Type2.7z", false);
            Template("CompleteBlank.script", "ShouldFail", "ShouldFail", false);
        }
Exemple #22
0
        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 void DeleteLogo()
        {
            EngineState s                = EngineTests.CreateEngineState();
            string      scriptDir        = Path.Combine(StringEscaper.Preprocess(s, "%TestBench%"), "EncodedFile");
            string      logoScriptPath   = Path.Combine(scriptDir, "Blank.script");
            string      noLogoScriptPath = Path.Combine(scriptDir, "CompleteBlank.script");

            // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local
            void Template(string testScriptPath, bool result)
            {
                string destDir    = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
                string destScript = Path.Combine(destDir, "DeleteLogoTest.script");

                Directory.CreateDirectory(destDir);
                try
                {
                    File.Copy(testScriptPath, destScript, true);

                    string errMsg;
                    Script sc = s.Project.LoadScriptRuntime(destScript, new LoadScriptRuntimeOptions());
                    (sc, errMsg) = EncodedFile.DeleteLogo(sc);

                    if (errMsg != null)
                    {
                        Assert.IsFalse(result);
                        return;
                    }
                    Assert.IsTrue(result);

                    Assert.IsFalse(EncodedFile.ContainsLogo(sc));
                }
                finally
                {
                    if (Directory.Exists(destDir))
                    {
                        Directory.Delete(destDir, true);
                    }
                }
            }

            Template(logoScriptPath, true);
            Template(noLogoScriptPath, false);
        }
Exemple #24
0
        public static List <LogInfo> ExtractAndRun(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>();

            Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_ExtractAndRun));
            CodeInfo_ExtractAndRun info = cmd.Info as CodeInfo_ExtractAndRun;

            string        pluginFile = StringEscaper.Preprocess(s, info.PluginFile);
            string        dirName    = StringEscaper.Preprocess(s, info.DirName);
            string        fileName   = StringEscaper.Preprocess(s, info.FileName);
            List <string> parameters = StringEscaper.Preprocess(s, info.Params);

            Plugin p = Engine.GetPluginInstance(s, cmd, s.CurrentPlugin.FullPath, pluginFile, out bool inCurrentPlugin);

            string destPath = Path.GetTempFileName();

            if (StringEscaper.PathSecurityCheck(destPath, out string errorMsg) == false)
            {
                logs.Add(new LogInfo(LogState.Error, errorMsg));
                return(logs);
            }

            using (MemoryStream ms = EncodedFile.ExtractFile(p, dirName, info.FileName))
                using (FileStream fs = new FileStream(destPath, FileMode.Create, FileAccess.Write))
                {
                    ms.Position = 0;
                    ms.CopyTo(fs);
                }

            Process proc = new Process();

            proc.StartInfo.FileName        = destPath;
            proc.StartInfo.UseShellExecute = true;
            proc.StartInfo.Verb            = "Open";
            proc.Start();

            logs.Add(new LogInfo(LogState.Success, $"Encoded file [{fileName}] extracted and executed"));

            return(logs);
        }
        public void ContainsFolder()
        {
            void Template(string folderName, bool result)
            {
                EngineState s = EngineTests.CreateEngineState();
                string      pbOriginScript = Path.Combine("%TestBench%", "EncodedFile", "Blank.script");
                string      originScript   = StringEscaper.Preprocess(s, pbOriginScript);

                string pbDestDir    = Path.Combine("%ProjectTemp%", Path.GetRandomFileName());
                string pbDestScript = Path.Combine(pbDestDir, "AddFolderTest.script");

                string destDir    = StringEscaper.Preprocess(s, pbDestDir);
                string destScript = StringEscaper.Preprocess(s, pbDestScript);

                if (!Directory.Exists(destDir))
                {
                    Directory.CreateDirectory(destDir);
                }
                try
                {
                    File.Copy(originScript, destScript, true);

                    Script sc = s.Project.LoadScriptRuntime(destScript, new LoadScriptRuntimeOptions());
                    Assert.AreEqual(EncodedFile.ContainsFolder(sc, folderName), result);
                }
                finally
                {
                    if (Directory.Exists(destDir))
                    {
                        Directory.Delete(destDir, true);
                    }
                }
            }

            Template(AuthorEncoded, true);
            Template(InterfaceEncoded, false);
            Template("Attach", true);
            Template("Process", false);
        }
Exemple #26
0
        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);
        }
Exemple #27
0
        /// <summary>
        /// Render Button control.
        /// Return true if failed.
        /// </summary>
        /// <param name="r.Canvas">Parent r.Canvas</param>
        /// <param name="uiCmd">UICommand</param>
        /// <returns>Success = false, Failure = true</returns>
        public static void RenderButton(RenderInfo r, UICommand uiCmd, Logger logger)
        {
            Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_Button));
            UIInfo_Button info = uiCmd.Info as UIInfo_Button;

            Button button = new Button()
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment   = VerticalAlignment.Center,
            };

            button.Click += (object sender, RoutedEventArgs e) =>
            {
                if (r.Plugin.Sections.ContainsKey(info.SectionName)) // Only if section exists
                {
                    SectionAddress addr = new SectionAddress(r.Plugin, r.Plugin.Sections[info.SectionName]);
                    UIRenderer.RunOneSection(addr, $"{r.Plugin.Title} - Button [{uiCmd.Key}]", info.ShowProgress);
                }
                else
                {
                    Application.Current.Dispatcher.Invoke((Action)(() =>
                    {
                        MainWindow w = Application.Current.MainWindow as MainWindow;
                        w.Logger.System_Write(new LogInfo(LogState.Error, $"Section [{info.SectionName}] does not exists"));
                    }));
                }
            };

            if (info.Picture != null && uiCmd.Addr.Plugin.Sections.ContainsKey($"EncodedFile-InterfaceEncoded-{info.Picture}"))
            { // Has Picture
                if (ImageHelper.GetImageType(info.Picture, out ImageHelper.ImageType type))
                {
                    return;
                }

                Image image = new Image()
                {
                    StretchDirection  = StretchDirection.DownOnly,
                    Stretch           = Stretch.Uniform,
                    UseLayoutRounding = true,
                };
                RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.HighQuality);

                using (MemoryStream ms = EncodedFile.ExtractInterfaceEncoded(uiCmd.Addr.Plugin, info.Picture))
                {
                    if (type == ImageHelper.ImageType.Svg)
                    {
                        ImageHelper.GetSvgSize(ms, out double width, out double height);
                        image.Source = ImageHelper.SvgToBitmapImage(ms, width, height);
                    }
                    else
                    {
                        image.Source = ImageHelper.ImageToBitmapImage(ms);
                    }
                }

                if (uiCmd.Text.Equals(string.Empty, StringComparison.Ordinal))
                { // No text, just image
                    button.Content = image;
                }
                else
                { // Button has text
                    StackPanel panel = new StackPanel()
                    {
                        HorizontalAlignment = HorizontalAlignment.Center,
                        VerticalAlignment   = VerticalAlignment.Center,
                        Orientation         = Orientation.Horizontal,
                    };

                    TextBlock text = new TextBlock()
                    {
                        Text              = uiCmd.Text,
                        FontSize          = CalcFontPointScale(),
                        Height            = double.NaN,
                        VerticalAlignment = VerticalAlignment.Center,
                        Margin            = new Thickness(CalcFontPointScale() / 2, 0, 0, 0),
                    };

                    panel.Children.Add(image);
                    panel.Children.Add(text);
                    button.Content = panel;
                }
            }
            else
            { // No picture
                button.Content  = uiCmd.Text;
                button.FontSize = CalcFontPointScale();
            }

            SetToolTip(button, info.ToolTip);
            DrawToCanvas(r, button, uiCmd.Rect);
        }
Exemple #28
0
        /// <summary>
        /// Render Image control.
        /// Return true if failed.
        /// </summary>
        /// <param name="r.Canvas">Parent r.Canvas</param>
        /// <param name="uiCmd">UICommand</param>
        /// <returns>Success = false, Failure = true</returns>
        public static void RenderImage(RenderInfo r, UICommand uiCmd)
        {
            Debug.Assert(uiCmd.Info.GetType() == typeof(UIInfo_Image));
            UIInfo_Image info = uiCmd.Info as UIInfo_Image;

            Image image = new Image()
            {
                StretchDirection  = StretchDirection.DownOnly,
                Stretch           = Stretch.Uniform,
                UseLayoutRounding = true,
            };

            RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.HighQuality);
            Button button;

            // double width, height;
            using (MemoryStream ms = EncodedFile.ExtractInterfaceEncoded(uiCmd.Addr.Plugin, uiCmd.Text))
            {
                if (ImageHelper.GetImageType(uiCmd.Text, out ImageHelper.ImageType type))
                {
                    return;
                }

                button = new Button()
                {
                    Style = (Style)r.Window.FindResource("ImageButton")
                };

                if (type == ImageHelper.ImageType.Svg)
                {
                    double width  = uiCmd.Rect.Width * r.MasterScale;
                    double height = uiCmd.Rect.Height * r.MasterScale;
                    button.Background = ImageHelper.SvgToImageBrush(ms, width, height);
                }
                else
                {
                    button.Background = ImageHelper.ImageToImageBrush(ms);
                }
            }

            bool hasUrl = false;

            if (info.URL != null && string.Equals(info.URL, string.Empty, StringComparison.Ordinal) == false)
            {
                if (Uri.TryCreate(info.URL, UriKind.Absolute, out Uri unused))
                { // Success
                    hasUrl = true;
                }
                else
                { // Failure
                    throw new InvalidUICommandException($"Invalid URL [{info.URL}]", uiCmd);
                }
            }

            if (hasUrl)
            { // Open URL
                button.Click += (object sender, RoutedEventArgs e) =>
                {
                    Process.Start(info.URL);
                };
            }
            else
            { // Open picture with external viewer
                button.Click += (object sender, RoutedEventArgs e) =>
                {
                    if (ImageHelper.GetImageType(uiCmd.Text, out ImageHelper.ImageType t))
                    {
                        return;
                    }
                    string path = System.IO.Path.ChangeExtension(System.IO.Path.GetTempFileName(), "." + t.ToString().ToLower());

                    using (MemoryStream ms = EncodedFile.ExtractInterfaceEncoded(uiCmd.Addr.Plugin, uiCmd.Text))
                        using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
                        {
                            ms.Position = 0;
                            ms.CopyTo(fs);
                        }

                    ProcessStartInfo procInfo = new ProcessStartInfo()
                    {
                        Verb            = "open",
                        FileName        = path,
                        UseShellExecute = true
                    };
                    Process.Start(procInfo);
                };
            }

            SetToolTip(button, info.ToolTip);
            DrawToCanvas(r, button, uiCmd.Rect);
        }
Exemple #29
0
        /*
         * WB082 Behavior
         * ExtractFile : DestDir must be Directory, create if not exists.
         * Ex) (...),README.txt,%BaseDir%\Temp\Hello
         *   -> No Hello : Create directory "Hello" and extract files into new directory.
         *   -> Hello is a file : Failure
         *   -> Hello is a directory : Extract files into directory.
         *
         * ExtractAllFiles
         * Ex) (...),Fonts,%BaseDir%\Temp\Hello
         *   -> No Hello : Failure
         *   -> Hello is a file : Failure
         *   -> Hello is a directory : Extract files into directory.
         *
         * PEBakery Behavior
         * ExtractFile/ExtractAllFiles : DestDir must be Directory, create if not exists.
         * Ex) (...),README.txt,%BaseDir%\Temp\Hello
         *   -> No Hello : Create directory "Hello" and extract files into new directory.
         *   -> Hello is a file : Failure
         *   -> Hello is a directory : Extract files into directory.
         */

        public static List <LogInfo> ExtractFile(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>();

            CodeInfo_ExtractFile info = cmd.Info.Cast <CodeInfo_ExtractFile>();

            string scriptFile = StringEscaper.Preprocess(s, info.ScriptFile);
            string dirName    = StringEscaper.Preprocess(s, info.DirName);
            string fileName   = StringEscaper.Preprocess(s, info.FileName);
            string destDir    = StringEscaper.Preprocess(s, info.DestDir); // Should be directory name

            Script sc = Engine.GetScriptInstance(s, s.CurrentScript.RealPath, scriptFile, out _);

            // Check if encoded file exist
            if (!EncodedFile.ContainsFile(sc, dirName, fileName))
            {
                return(LogInfo.LogErrorMessage(logs, $"Encoded file [{dirName}\\{fileName}] not found in script [{sc.RealPath}]."));
            }

            // Filter dest path
            if (!StringEscaper.PathSecurityCheck(destDir, out string errorMsg))
            {
                return(LogInfo.LogErrorMessage(logs, errorMsg));
            }

            if (!Directory.Exists(destDir)) // DestDir already exists
            {
                if (File.Exists(destDir))   // Error, cannot proceed
                {
                    return(LogInfo.LogErrorMessage(logs, $"File [{destDir}] is not a directory."));
                }

                Directory.CreateDirectory(destDir);
            }

            s.MainViewModel.SetBuildCommandProgress("ExtractFile Progress", 1);
            try
            {
                object             progressLock = new object();
                IProgress <double> progress     = new Progress <double>(x =>
                {
                    lock (progressLock)
                    {
                        s.MainViewModel.BuildCommandProgressValue = x;
                        if (x < EncodedFile.Base64ReportFactor)
                        { // [Stage 1] Base64
                            s.MainViewModel.BuildCommandProgressText = $"Reading \"{fileName}\" from script\r\n({x * 100:0.0}%)";
                        }
                        else
                        { // [Stage 2] Decompress
                            s.MainViewModel.BuildCommandProgressText = $"Decompressing \"{fileName}\"\r\n({x * 100:0.0}%)";
                        }
                    }
                });

                string destPath = Path.Combine(destDir, fileName);
                using (FileStream fs = new FileStream(destPath, FileMode.Create, FileAccess.Write))
                {
                    EncodedFile.ExtractFile(sc, dirName, fileName, fs, progress);
                }
            }
            finally
            {
                s.MainViewModel.ResetBuildCommandProgress();
            }

            logs.Add(new LogInfo(LogState.Success, $"Encoded file [{fileName}] was extracted to [{destDir}]"));

            return(logs);
        }
Exemple #30
0
        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);
        }