private void RunToolsTask(ToolsTaskType toolsTaskType) { if (ToolsTaskQueue.Items.Count == 0) { Out.Log("Nothing to do - ToolsTaskQueue empty! Please select any input file first!\r\n"); return; } Dispatcher.Invoke(() => { BusyTextBlock.Text = "Working..."; MainGrid.Visibility = Visibility.Hidden; MainGridBusy.Visibility = Visibility.Visible; }); var extractedTitleKeys = new LibHac.Keyset(); var keyset = new LibHac.Keyset(); if (toolsTaskType == ToolsTaskType.ExtractRomFS) { keyset = LibHacControl.ProcessKeyset.OpenKeyset(); } try { var TitlekeysOutputFilePath = $"{OutputFolderPath}/titlekeys.txt"; var TicketOutputPath = $"{OutputFolderPath}/Tickets"; if (toolsTaskType == ToolsTaskType.ExtractTickets && !Directory.Exists(TicketOutputPath)) { Directory.CreateDirectory(TicketOutputPath); } do { var inFilePath = (string)ToolsTaskQueue.Items[0]; var inFile = Path.GetFileName(inFilePath); var ToolsTaskText = $"ToolsTask {toolsTaskType.ToString()} \"{inFile}\" in progress..."; Out.Event($"{ToolsTaskText}\r\n"); Dispatcher.Invoke(() => { BusyTextBlock.Text = $"{ToolsTaskText}\r\nThis might take quite some time.\r\n" + $"Please take a look at the console window for more information."; ToolsTaskQueue.Items.RemoveAt(0); }); // Sleep 10 ms for the BusyTextBlock be longer visible for a large amount of very short tasks like ExtractTitlekeys // It’s here so he sleeps even if the ToolsTask was skipped Thread.Sleep(10); switch (toolsTaskType) { case ToolsTaskType.ExtractTitlekeys: FileTools.File2Titlekey(inFilePath, extractedTitleKeys, Out); break; case ToolsTaskType.ExtractTickets: FileTools.File2Tickets(inFilePath, TicketOutputPath, keyset, Out); break; case ToolsTaskType.ExtractPfsHfs: var PfsHfsOutputPath = $"{OutputFolderPath}/{inFile}_Extracted"; if (!Directory.Exists(PfsHfsOutputPath)) { Directory.CreateDirectory(PfsHfsOutputPath); FileTools.ExtractPfsHfs(inFilePath, PfsHfsOutputPath, keyset, Out); } else { Out.Event($"ToolsTask {toolsTaskType.ToString()} \"{inFile}\" skipped as it already exists in the output directory\r\n"); continue; } break; case ToolsTaskType.ExtractRomFS: var RomFsOutputPath = $"{OutputFolderPath}/{inFile}_RomFS"; if (!Directory.Exists(RomFsOutputPath)) { Directory.CreateDirectory(RomFsOutputPath); FileTools.ExtractRomFS(inFilePath, RomFsOutputPath, keyset, Out); } else { Out.Event($"ToolsTask {toolsTaskType.ToString()} \"{inFile}\" skipped as it already exists in the output directory\r\n"); continue; } break; default: throw new NotImplementedException($"Unknown ToolsTaskType: {toolsTaskType}!"); } Out.Event($"ToolsTask {toolsTaskType.ToString()} \"{inFile}\" completed!\r\n"); } while (ToolsTaskQueue.Items.Count > 0); if (toolsTaskType == ToolsTaskType.ExtractTitlekeys) { Out.Log($"Writing to {TitlekeysOutputFilePath}\r\n"); using (var titlekeys = new StreamWriter(File.Open(TitlekeysOutputFilePath, FileMode.Create), Encoding.ASCII)) { foreach (var entry in extractedTitleKeys.TitleKeys) { var line = $"{Utils.BytesToString(entry.Key)},{Utils.BytesToString(entry.Value)}\r\n"; titlekeys.Write(line); Out.Log(line); } } } Out.Event($"All ToolsTasks completed!\r\n"); } catch (Exception ex) { Out.LogException(ex); } finally { Dispatcher.Invoke(() => { MainGrid.Visibility = Visibility.Visible; MainGridBusy.Visibility = Visibility.Hidden; }); } }
private void Application_Startup(object sender, StartupEventArgs e) { //var outDebug = new Output(); //var tl1 = new TaskLogic(@"T:\OUT", @"T:\", true, 262144, 18, outDebug); //tl1.VerifyCompressedFolder(@"T:\NSP\input.nsp"); //return; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { try { if (ConsoleMode.TryDisablingConsoleQuickEdit()) { Console.WriteLine("Console's QuickEdit mode disabled successfully"); } else { Console.WriteLine("Failed to disable the Console's QuickEdit mode"); } } catch (Exception) { Console.WriteLine("Unimportant exception occurred while disabling Console's QuickEdit mode"); } } if (e.Args.Length > 0) { int res = 0; var args = Parser.Default.ParseArguments <Options>(e.Args); if (e.Args.Length > 0) { args.WithParsed(opts => { var Out = new Output(opts.Log); Directory.CreateDirectory(opts.OutputFolderPath); var tl = new TaskLogic(opts.OutputFolderPath, opts.TempFolderPath, true, opts.BlockSize, opts.ZstdLevel, opts.MaxDegreeOfParallelism, Out); var inFile = opts.InputFile; if (tl.checkIfAlreadyExist(inFile)) { Environment.Exit(-1); } try { tl.cleanFolders(); var infileLowerCase = inFile.ToLower(); if (infileLowerCase.EndsWith("nsp")) { tl.CompressNSP(inFile); } else if (infileLowerCase.EndsWith("xci")) { tl.CompressXCI(inFile); } else if (infileLowerCase.EndsWith("nspz")) { tl.DecompressNSPZ(inFile); } else if (infileLowerCase.EndsWith("xciz")) { tl.DecompressXCIZ(inFile); } else { throw new InvalidDataException($"Invalid file type {inFile}"); } } catch (Exception ex) { Out.LogException(ex); res = -2; } finally { tl.cleanFolders(); } }); } Environment.Exit(res); } else { MainWindow wnd = new MainWindow(); wnd.Show(); } }