private void ChooseFileCommand_Execute() { var dialog = new OpenFileDialog { CheckFileExists = true, CheckPathExists = true, Filter = StringResources.XmlFiles + " (*.xml)|*.xml", Multiselect = false }; if (dialog.ShowDialog() == true) { var xDoc = new XmlDocument(); try { xDoc.Load(dialog.FileName); } catch (XmlException ex) { // todo: Localize MessBox.ShowDial(StringResources.ErrorLower, $"Can't open file '{dialog.FileName}'{Environment.NewLine}{StringResources.ErrorLower}: {ex}"); return; } var itms = Utils.CommonUtils.GetAllAttributes(xDoc.DocumentElement, Items.Select(it => it.Text)); for (int i = Items.Count; i < itms.Count; i++) { Items.Add(new CheckableSetting(itms[i])); } } }
protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); _rootDiContainer = SetupDI(); MigrateSettings(_rootDiContainer.Resolve <IAppSettings>()); var globalVariables = _rootDiContainer.Resolve <GlobalVariables>(); CheckForFiles(globalVariables); CheckPortability(globalVariables); #if !DEBUG DispatcherUnhandledException += (sender, args) => { MessBox.ShowDial("Обнаружена непредвиденная ошибка. Текст ошибки скопирован в буфер обмена. Пожалуйста, свяжитесь с разработчиком"); Clipboard.SetText("Message: " + args.Exception.Message + "\nStackTrace: " + args.Exception.StackTrace); args.Handled = true; globalVariables.ErrorClient.Notify(args.Exception); }; #endif var applicationUtils = _rootDiContainer.Resolve <ApplicationUtils>(); applicationUtils.SetLanguageFromSettings(); _rootDiContainer.Resolve <ThemeUtils>().SetThemeFromSettings(); _rootDiContainer.Resolve <MainWindow>().Show(); #if !DEBUG if (!globalVariables.IsPortable) #endif applicationUtils.CheckForUpdate(); }
private void CheckForFiles([NotNull] GlobalVariables globalVariables) { var resourcesFolder = Path.Combine(globalVariables.PathToExeFolder, "Resources"); string[] notExistingFiles; if (!LDirectory.Exists(resourcesFolder)) { notExistingFiles = new[] { resourcesFolder }; } else { notExistingFiles = NeededFiles.Select(it => Path.Combine(resourcesFolder, it)) .Where(it => !LFile.Exists(it)).ToArray(); } if (notExistingFiles.Length == 0) { return; } MessBox.ShowDial( string.Format( MainResources.NoNeededFilesError, notExistingFiles.Select(Path.GetFileName).Select(file => $"\"{file}\"").JoinStr(", ") ), MainResources.Error ); Shutdown(); }
private void DecompileFile(string file) { _globalVariables.CurrentProjectFile.Value = file; string logPath = Path.Combine(Path.GetDirectoryName(file) ?? string.Empty, $"{Path.GetFileNameWithoutExtension(file)}_log.txt"); if (!TryCreateNewLog(logPath)) { return; } if (Apk != null) { Apk.Logging -= VisLog; } Apk = new Apktools( file, GlobalVariables.PathToResources, GlobalVariables.CurrentApktoolPath ); Apk.Logging += VisLog; if (!Apk.HasJava()) { MessBox.ShowDial(StringResources.JavaNotFoundError, StringResources.ErrorLower); return; } ClearVisLog(); bool success = false; LoadingWindow.ShowWindow( beforeStarting: () => IsBusy = true, threadActions: source => success = GlobalVariables.AppSettings.OnlyResources ? Apk.Decompile(options: "-s") : Apk.Decompile(), finishActions: () => { IsBusy = false; VisLog(LogLine); VisLog(StringResources.Finished); VisLog(LogLine); if (GlobalVariables.AppSettings.ShowNotifications) { NotificationService.Instance.ShowMessage(StringResources.DecompilationFinished); } if (success) { Application.Current.Dispatcher.InvokeAction(() => LoadFolder(_globalVariables.CurrentProjectFolder.Value, true)); } }, cancelVisibility: Visibility.Collapsed, ownerWindow: _window ); }
private static void DeleteSmthPromt(FilesTreeViewNodeModel node, string confirmation, Action <string> deleteAction, Predicate <string> checkAction) { Options opts = node.Options; if (MessBox.ShowDial( $"{confirmation} {opts.FullPath}?", StringResources.Confirmation, StringResources.Yes, StringResources.No ) == StringResources.No) { return; } try { deleteAction(opts.FullPath); if (checkAction(opts.FullPath)) { MessBox.ShowDial(StringResources.ErrorLower); } else { node.RemoveFromParent(); } } catch (Exception) { MessBox.ShowDial(StringResources.ErrorLower); } }
private void SaveChangesCommand_Execute() { var items = Items.Where(it => it.IsChecked && !string.IsNullOrEmpty(it.Text)).ToArray(); GlobalVariables.AppSettings.XmlRules = items.Select(it => it.Text).ToList(); XmlFile.XmlRules = items.Select(it => new Regex(it.Text)).ToList(); MessBox.ShowDial(StringResources.Finished); }
private void BuildCommand_Execute() { if (Apk == null) { return; } if (!Apk.HasJava()) { MessBox.ShowDial(StringResources.JavaNotFoundError, StringResources.ErrorLower); return; } ClearVisLog(); bool success = false; var errors = new List <Error>(); LoadingWindow.ShowWindow( beforeStarting: () => IsBusy = true, threadActions: source => success = Apk.Compile(out errors), finishActions: () => { IsBusy = false; VisLog(LogLine); VisLog(success ? StringResources.Finished : StringResources.ErrorWhileCompiling); VisLog(LogLine); if (GlobalVariables.AppSettings.ShowNotifications) { NotificationService.Instance.ShowMessage(StringResources.CompilationFinished); } if (!success && errors.Any(error => error.Type != Error.ErrorType.None)) { if (MessBox.ShowDial("Обнаружены ошибки. Попробовать исправить?", "", MessBox.MessageButtons.Yes, MessBox.MessageButtons.No) == MessBox.MessageButtons.Yes) { Apktools.FixErrors(errors); BuildCommand_Execute(); } } else { VisLog(StringResources.FileIsSituatedIn + " " + Apk.NewApk); } RaiseCommandsCanExecute(); }, cancelVisibility: Visibility.Collapsed, ownerWindow: _window ); }
private bool TryCreateNewLog(string logPath) { if (_androidProcessLogger != null) { _androidProcessLogger.Close(); _androidProcessLogger = null; } const int createLogMaximumIndex = 50; string logDir = Path.GetDirectoryName(logPath) ?? string.Empty; string logName = Path.GetFileNameWithoutExtension(logPath); string logExt = Path.GetExtension(logPath); int currentIndex = 1; while (true) { try { string logIndexedPath = Path.Combine( logDir, currentIndex == 1 ? $"{logName}{logExt}" : $"{logName} ({currentIndex}){logExt}" ); _androidProcessLogger = new StreamWriter(logIndexedPath, true, Encoding.UTF8) { AutoFlush = true }; return(true); } catch (Exception ex) { if (currentIndex < createLogMaximumIndex) { currentIndex++; continue; } GlobalVariables.BugSnagClient.Notify(ex); MessBox.ShowDial(string.Format(StringResources.FileIsInUse, logPath), StringResources.ErrorLower); return(false); } } }
public override async Task LoadItems() { using (BusyDisposable()) { try { List <DownloadableApktool> items = await DownloadApktoolsListAsync(); ServerApktools.ReplaceRange(items); } catch (Exception) { MessBox.ShowDial(StringResources.CanNotRecieveApktoolsList, StringResources.ErrorLower); } } }
protected override void OnStartup(StartupEventArgs e) { AppDomain.CurrentDomain.UnhandledException += (sender, args) => { var ex = args.ExceptionObject is Exception exception ? exception : new Exception("Domain exception"); Logger.Fatal(ex); GlobalVariables.BugSnagClient.Notify(ex); Clipboard.SetText("Message: " + (args.ExceptionObject as Exception)?.FlattenToString()); MessageBox.Show(StringResources.UnhandledExceptionOccured); }; DispatcherUnhandledException += (sender, args) => { Logger.Error(args.Exception); GlobalVariables.BugSnagClient.Notify(args.Exception); Clipboard.SetText(args.Exception.ToString()); MessageBox.Show(string.Format(StringResources.ExceptionOccured, args.Exception.FlattenToString())); #if !DEBUG args.Handled = true; #endif }; if (e.Args.FirstOrDefault() == "update") { new DownloadWindow().Show(); return; } CommonUtils.LoadSettings(); #if !DEBUG if (!GlobalVariables.Portable) #endif CommonUtils.CheckForUpdate(); if (string.IsNullOrEmpty(GlobalVariables.AppSettings.ApktoolVersion)) { Logger.Error("Apktool not found"); MessBox.ShowDial(StringResources.ApktoolNotFound); } WindowManager.ActivateWindow <MainWindow>(); }
private void SignCommand_Execute() { if (Apk?.NewApk == null) { return; } if (!Apk.HasJava()) { MessBox.ShowDial(StringResources.JavaNotFoundError, StringResources.ErrorLower); return; } bool success = false; LoadingWindow.ShowWindow( beforeStarting: () => IsBusy = true, threadActions: source => success = Apk.Sign(), finishActions: () => { IsBusy = false; VisLog(LogLine); VisLog(success ? StringResources.Finished : StringResources.ErrorWhileSigning); if (success) { string message = $"{StringResources.FileIsSituatedIn} {Apk.SignedApk}"; VisLog(message); string dir = Path.GetDirectoryName(Apk.SignedApk); if (dir != null && MessBox.ShowDial(message, StringResources.Finished, MessBox.MessageButtons.OK, StringResources.Open) == StringResources.Open) { Process.Start(dir); } } }, cancelVisibility: Visibility.Collapsed, ownerWindow: _window ); VisLog(string.Format("{0}{1}Signing...{1}{0}", LogLine, Environment.NewLine)); }
private void CheckPortability([NotNull] GlobalVariables globalVariables) { if (!globalVariables.IsPortable || globalVariables.CanWriteToAppData.Value) { return; } MessBox.ShowDial( string.Format( MainResources.DataWriteDenied, globalVariables.AppDataPath, globalVariables.PortableSwitchFile ), MainResources.Error ); Shutdown(); }
private void InstallFramework(string fileName) { using (BusyDisposable()) { var apktool = new Apktools(null, GlobalVariables.PathToResources, Path.Combine(GlobalVariables.PathToApktoolVersions, $"apktool_{GlobalVariables.AppSettings.ApktoolVersion}.jar")); if (!apktool.HasJava()) { MessBox.ShowDial(StringResources.JavaNotFoundError, StringResources.ErrorLower); return; } apktool.Logging += VisLog; apktool.InstallFramework(fileName); apktool.Logging -= VisLog; } }
/// <summary> /// Устанавливает текущий язык программы /// </summary> /// <param name="language"></param> /// <param name="showDialog"></param> public static void SetLanguageOfApp(string language, bool showDialog = false) { if (TranslateService.SupportedProgramLangs.All(lang => lang != language)) return; Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(language); Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(language); AppSettings.LanguageOfApp = language; if (showDialog && MessBox.ShowDial(StringResources.RestartProgramToApplyLanguage, null, MessBox.MessageButtons.Yes, MessBox.MessageButtons.No) == MessBox.MessageButtons.Yes) { Process.Start(GlobalVariables.PathToExe); Environment.Exit(0); } TranslateService.ReloadItems(); }
/// <summary> /// Загружает файл в редактор /// </summary> /// <param name="pathToFile">Файл</param> public static void LoadFile(string pathToFile) { var ext = Path.GetExtension(pathToFile); if (!GlobalVariables.EditableFileExtenstions.Contains(ext)) { Process.Start(pathToFile); return; } IEditableFile file; try { switch (ext) { case ".xml": file = XmlFile.Create(pathToFile); break; default: //".smali": file = new SmaliFile(pathToFile); break; } } catch (IOException ex) { // todo: add to string resources MessBox.ShowDial($"Не удалось загрузить файл из-за ошибки системы.\nСообщение: {ex.Message}", StringResources.ErrorLower); return; } WindowManager.ActivateWindow<EditorWindow>(); ManualEventManager.GetEvent<AddEditableFilesEvent>() .Publish(new AddEditableFilesEvent(file)); ManualEventManager.GetEvent<EditorScrollToFileAndSelectEvent>() .Publish(new EditorScrollToFileAndSelectEvent(f => f.FileName.Equals(file.FileName, StringComparison.Ordinal))); }
private static void TV_ReplaceFileCommand_Execute(FilesTreeViewNodeModel model) { if (!IOUtils.FileExists(model.Options.FullPath)) { return; } var fd = new OpenFileDialog { CheckFileExists = true, CheckPathExists = true, Multiselect = false }; if (fd.ShowDialog() == true) { File.Copy(fd.FileName, model.Options.FullPath, true); MessBox.ShowDial(StringResources.Finished); } else { MessBox.ShowDial(StringResources.ErrorLower); } }
private void TranslateMoreFolders(string filesFolder, string dictionariesFolder) { var fileApktools = Directory.EnumerateFiles(filesFolder, "*.apk") .Select(file => new Apktools(file, GlobalVariables.PathToResources)) .ToList(); Log("Decompiling files:"); ProgressValue.Value = 0; ProgressMax.Value = fileApktools.Count; for (int i = 0; i < fileApktools.Count; i++) { ProgressValue.Value++; Log(" -- " + fileApktools[i].FileName); if (!fileApktools[i].Decompile(true, false)) { Log("Error while decompiling!"); fileApktools.RemoveAt(i--); } } Log(); Log("Translating files..."); int progressState = 1; int progressMax = fileApktools.Count; foreach (var apktool in fileApktools) { try { Log($" -- ({progressState++} из {progressMax}) {apktool.FileName}", false); string dictPath = Path.Combine(dictionariesFolder, apktool.Manifest.Package); if (!IOUtils.FolderExists(dictPath)) { Log(" - skipped"); continue; } TranslateOneFolder(apktool.FolderOfProject, dictPath, false); Log(" - translated"); } catch (Exception ex) { // ReSharper disable once LocalizableElement MessageBox.Show($"Message: {ex.Message}\nStackTrace: {ex.StackTrace}"); Log(" - error"); } } Log(); Log("Compiling:"); ProgressValue.Value = 0; ProgressMax.Value = fileApktools.Count; string resultFolder = Path.Combine(filesFolder, "Result"); string resultSignedFolder = Path.Combine(filesFolder, "ResultSigned"); foreach (var folder in new[] { resultFolder, resultSignedFolder }) { if (IOUtils.FolderExists(folder)) { IOUtils.DeleteFolder(folder); } IOUtils.CreateFolder(folder); } for (int i = 0; i < fileApktools.Count; i++) { try { ProgressValue.Value++; Log(" -- " + fileApktools[i].FileName, false); List <Error> errors; if (fileApktools[i].Compile(out errors)) { Log(" - compiled", false); File.Copy(fileApktools[i].NewApk, Path.Combine(resultFolder, Path.GetFileName(fileApktools[i].NewApk) ?? string.Empty)); Log(" - copied"); } else { foreach (var error in errors) { Log($" - error: \n File: {error.File}\n Line: {error.Line}\n Message: {error.Message}"); } fileApktools.RemoveAt(i--); } } catch (Exception ex) { // ReSharper disable once LocalizableElement MessageBox.Show($"Message: {ex.Message}\nStackTrace: {ex.StackTrace}"); Log(" - error"); } } Log(); Log("Signing:"); ProgressValue.Value = 0; ProgressMax.Value = fileApktools.Count; for (int i = 0; i < fileApktools.Count; i++) { try { ProgressValue.Value++; Log(" -- " + fileApktools[i].FileName, false); if (fileApktools[i].Sign()) { Log(" - signed", false); File.Copy(fileApktools[i].SignedApk, Path.Combine(resultSignedFolder, Path.GetFileName(fileApktools[i].SignedApk) ?? string.Empty)); Log(" - copied"); } else { Log(" - error"); fileApktools.RemoveAt(i--); } } catch (Exception ex) { MessageBox.Show($@"Message: {ex.Message}\nStackTrace: {ex.StackTrace}"); Log(" - error"); } } Log(); Log("Finished"); if ( MessBox.ShowDial( "Открыть папку с готовыми файлами?", null, MessBox.MessageButtons.Yes, MessBox.MessageButtons.No ) == MessBox.MessageButtons.Yes ) { Process.Start(IOUtils.FolderExists(resultSignedFolder) ? resultSignedFolder : filesFolder); } }
private void FindFilesCommand_Execute() { if (_globalVariables.CurrentProjectFolder.Value.IsNullOrEmpty()) { MessBox.ShowDial(StringResources.SearchWindow_FolderIsNotSelected); return; } string GetFormattedName(string fileName) { return(StartFormattedString + fileName.Substring(_globalVariables.CurrentProjectFolder.Value.Length + 1)); } AddToSearchAdds(TextToSearch.Value); var filesToAdd = new List <FoundItem>(); LoadingProcessWindow.ShowWindow( beforeStarting: () => IsBusy = true, threadActions: (cts, invoker) => { var projectFolder = _globalVariables.CurrentProjectFolder.Value; var buildFolder = Path.DirectorySeparatorChar + "build"; var buildFolderM = Path.DirectorySeparatorChar + "build" + Path.DirectorySeparatorChar; List <string> xmlFiles = Directory.EnumerateFiles(projectFolder, "*.xml", SearchOption.AllDirectories) .Where(file => { // ReSharper disable once PossibleNullReferenceException var dir = Path.GetDirectoryName(file).Substring(projectFolder.Length); return(dir != buildFolder && !dir.StartsWith(buildFolderM, StringComparison.Ordinal)); } ) .ToList(); List <string> smaliFiles = Directory.EnumerateFiles(projectFolder, "*.smali", SearchOption.AllDirectories).ToList(); invoker.ProcessValue = 0; invoker.ProcessMax = xmlFiles.Count + smaliFiles.Count; bool onlyFullWords = OnlyFullWords.Value; bool matchCase = MatchCase.Value; Func <string, string, bool> checkRules; if (!matchCase && !onlyFullWords) { checkRules = (f, s) => f.IndexOf(s, StringComparison.OrdinalIgnoreCase) != -1; } else if (!matchCase /*&& onlyFullWords*/) { checkRules = (f, s) => f.Equals(s, StringComparison.OrdinalIgnoreCase); } else if (/*matchCase &&*/ !onlyFullWords) { checkRules = (f, s) => f.IndexOf(s, StringComparison.Ordinal) != -1; } else /*if (matchCase && onlyFullWords)*/ { checkRules = (f, s) => f.Equals(s, StringComparison.Ordinal); } IEnumerable <IEditableFile> union = xmlFiles.SelectSafe <string, IEditableFile>(XmlFile.Create) .Concat(smaliFiles.SelectSafe(it => new SmaliFile(it))); foreach (IEditableFile file in union) { cts.ThrowIfCancellationRequested(); IOneString found = file.Details?.FirstOrDefault(str => checkRules(str.OldText, TextToSearch.Value)); if (found != null) { filesToAdd.Add(new FoundItem(GetFormattedName(file.FileName), found.OldText)); } invoker.ProcessValue++; } }, finishActions: () => { IsBusy = false; if (filesToAdd.Count == 0) { Files.Clear(); MessBox.ShowDial(StringResources.TextNotFound); } else { Files.ReplaceRange(filesToAdd); } }, ownerWindow: _window ); }
public async Task DownloadJava([NotNull] IVisualProgress visualProgress) { visualProgress.SetLabelText(MainResources.JavaDownloading); visualProgress.ShowIndeterminateLabel(); bool fileDownloaded; const string jreUrl = @"https://pixelcurves.ams3.digitaloceanspaces.com/SaveToGame/jre_1.7.zip"; string fileLocation = Path.Combine(_globalVariables.AppDataPath, "jre.zip"); LDirectory.CreateDirectory(_globalVariables.AppDataPath); using (var client = new WebClient()) { client.DownloadProgressChanged += (sender, args) => visualProgress.SetBarValue(args.ProgressPercentage); while (true) { try { await client.DownloadFileTaskAsync(jreUrl, fileLocation); fileDownloaded = true; break; } catch (Exception ex) { var promt = MessBox.ShowDial( string.Format(MainResources.JavaDownloadFailed, ex.Message), MainResources.Error, MainResources.No, MainResources.Yes ); if (promt == MainResources.Yes) { continue; } fileDownloaded = false; break; } } } if (fileDownloaded) { visualProgress.SetLabelText(MainResources.JavaExtracting); visualProgress.SetBarIndeterminate(); using (var zipFile = new ZipFile(fileLocation)) { await Task.Factory.StartNew(() => zipFile.ExtractAll(_globalVariables.PathToPortableJre)); } LFile.Delete(fileLocation); } visualProgress.HideIndeterminateLabel(); visualProgress.SetLabelText(MainResources.AllDone); }
private void ProcessAll(byte[] xxhdpiBytes, byte[] xhdpiBytes, byte[] hdpiBytes, byte[] mdpiBytes, Dispatcher uiThreadDispatcher) { const string internalDataInApkName = "data.save"; const string externalDataInApkName = "extdata.save"; IVisualProgress visualProgress = VisualProgress.Value; ITaskBarManager taskBarManager = TaskBarManager.Value; string apkFile = Apk.Value; string saveFile = Save.Value; string androidDataFile = Data.Value; string[] androidObbFiles = (string[])Obb.Value?.Clone() ?? new string[0]; string appTitle = AppTitle.Value; bool alternativeSigning = _settings.AlternativeSigning; BackupType backupType = _settings.BackupType; // initializing visualProgress?.SetBarIndeterminate(); visualProgress?.ShowBar(); visualProgress?.ShowIndeterminateLabel(); taskBarManager?.SetProgress(0); taskBarManager?.SetUsualState(); void SetStep(string step, int stepNumber) { WindowTitle.Value = step; Log(step); const int maxStep = 5; int percentage = (stepNumber - 1) * 100 / maxStep; visualProgress?.SetLabelText(step); taskBarManager?.SetProgress(percentage); } SetStep(MainResources.StepInitializing, 1); string resultFilePath = Path.Combine( Path.GetDirectoryName(apkFile) ?? string.Empty, Path.GetFileNameWithoutExtension(apkFile) + "_mod.apk" ); IApktool apktool = _apktoolProvider.Get(); IProcessDataHandler dataHandler = new ProcessDataCombinedHandler(Log); ITempFileProvider tempFileProvider = _tempUtils.CreateTempFileProvider(); ITempFolderProvider tempFolderProvider = _tempUtils.CreateTempFolderProvider(); using (var stgContainerExtracted = AndroidHelper.Logic.Utils.TempUtils.UseTempFolder(tempFolderProvider)) { // extracting SaveToGame container app SetStep(MainResources.CopyingStgApk, 2); string containerZipPath = Path.Combine(_globalVariables.PathToResources, "apk.zip"); using (var zip = new ZipFile(containerZipPath) { Password = _globalVariables.AdditionalFilePassword }) { zip.ExtractAll(stgContainerExtracted.TempFolder); } SetStep(MainResources.AddingData, 3); // creating assets folder for data string stgContainerAssetsPath = Path.Combine(stgContainerExtracted.TempFolder, "assets"); LDirectory.CreateDirectory(stgContainerAssetsPath); // adding backup if (!string.IsNullOrEmpty(saveFile)) { string internalDataPath = Path.Combine(stgContainerAssetsPath, internalDataInApkName); string externalDataPath = Path.Combine(stgContainerAssetsPath, externalDataInApkName); ApkModifer.ParseBackup( pathToBackup: saveFile, backupType: backupType, resultInternalDataPath: internalDataPath, resultExternalDataPath: externalDataPath, tempFolderProvider: tempFolderProvider ); } // adding external data if (!string.IsNullOrEmpty(androidDataFile)) { LFile.Copy( androidDataFile, Path.Combine(stgContainerAssetsPath, externalDataInApkName) ); } // adding obb files if (androidObbFiles.Length != 0) { using (var obbParts = AndroidHelper.Logic.Utils.TempUtils.UseTempFolder(tempFolderProvider)) { ApkModifer.SplitObbFiles( obbFilePaths: androidObbFiles, partsFolderPath: obbParts.TempFolder, // todo: add progress progressNotifier: null ); string assetsDir = Path.Combine(stgContainerExtracted.TempFolder, "assets", "111111222222333333"); LDirectory.CreateDirectory(assetsDir); IEnumerable <string> filesToAdd = LDirectory.EnumerateFiles(obbParts.TempFolder); foreach (var file in filesToAdd) { LFile.Copy(file, Path.Combine(assetsDir, Path.GetFileName(file))); } } } // adding resigned apk to container using (var sourceResigned = AndroidHelper.Logic.Utils.TempUtils.UseTempFile(tempFileProvider)) { apktool.Sign( sourceApkPath: apkFile, signedApkPath: sourceResigned.TempFile, tempFileProvider: tempFileProvider, dataHandler: dataHandler, deleteMetaInf: !alternativeSigning ); LFile.Copy( sourceFileName: sourceResigned.TempFile, destFileName: Path.Combine(stgContainerAssetsPath, "install.bin"), overwrite: false ); } // modifying AndroidManifest { string pathToManifest = Path.Combine(stgContainerExtracted.TempFolder, "AndroidManifest.xml"); string sourcePackageName; using (var sourceManifest = AndroidHelper.Logic.Utils.TempUtils.UseTempFile(tempFileProvider)) { apktool.ExtractSimpleManifest( apkPath: apkFile, resultManifestPath: sourceManifest.TempFile, tempFolderProvider: tempFolderProvider ); sourcePackageName = new AndroidManifest(sourceManifest.TempFile).Package; } LFile.WriteAllText( pathToManifest, LFile.ReadAllText(pathToManifest, Encoding.UTF8) .Replace("change_package", sourcePackageName) .Replace("@string/app_name", appTitle) ); } // adding icons { string iconsFolder = Path.Combine(stgContainerExtracted.TempFolder, "res", "mipmap-"); void DeleteIcon(string folder) => LFile.Delete(Path.Combine($"{iconsFolder}{folder}", "ic_launcher.png")); DeleteIcon("xxhdpi-v4"); DeleteIcon("xhdpi-v4"); DeleteIcon("hdpi-v4"); DeleteIcon("mdpi-v4"); void WriteIcon(string folder, byte[] imageBytes) => LFile.WriteAllBytes(Path.Combine($"{iconsFolder}{folder}", "ic_launcher.png"), imageBytes); WriteIcon("xxhdpi-v4", xxhdpiBytes); WriteIcon("xhdpi-v4", xhdpiBytes); WriteIcon("hdpi-v4", hdpiBytes); WriteIcon("mdpi-v4", mdpiBytes); } // compiling + signing using (var compiledContainer = AndroidHelper.Logic.Utils.TempUtils.UseTempFile(tempFileProvider)) { // compiling SetStep(MainResources.StepCompiling, 4); // todo: check errors List <Error> compilationErrors; apktool.Compile( projectFolderPath: stgContainerExtracted.TempFolder, destinationApkPath: compiledContainer.TempFile, dataHandler: dataHandler, errors: out compilationErrors ); if (compilationErrors.Count > 0) { Log(MainResources.ErrorUp); return; } // signing SetStep(MainResources.StepSigning, 5); apktool.Sign( sourceApkPath: compiledContainer.TempFile, signedApkPath: resultFilePath, tempFileProvider: tempFileProvider, dataHandler: dataHandler, deleteMetaInf: !alternativeSigning ); } } visualProgress?.HideIndeterminateLabel(); visualProgress?.HideBar(); SetStep(MainResources.AllDone, 6); Log(string.Empty); Log($"{MainResources.Path_to_file} {resultFilePath}"); _globalVariables.LatestModdedApkPath = resultFilePath; if (_settings.Notifications) { _notificationManager.Show( title: MainResources.Information_Title, text: MainResources.ModificationCompletedContent ); } string dialogResult = MessBox.ShowDial( $"{MainResources.Path_to_file} {resultFilePath}", MainResources.Successful, MainResources.OK, MainResources.Open, MainResources.Install ); if (dialogResult == MainResources.Open) { Process.Start("explorer.exe", $"/select,{resultFilePath}"); } else if (dialogResult == MainResources.Install) { uiThreadDispatcher.Invoke(() => _adbInstallWindowProvider.Get().ShowDialog()); } taskBarManager?.SetNoneState(); }