feat(gui): add button to install desktop file directly from jadx-gui (PR #2404)
* fix: missing/incorrect .desktop file values - correct comment - Add StartupWMClass * feat: add button to install desktop file from jadx-gui (#1392) * fix: use POSIX compliant realpath instead of readlink * fix: get XDG executable from PATH
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Name=JADX GUI
|
Name=JADX GUI
|
||||||
Comment=Dex to Java compiler
|
Comment=Dex to Java decompiler
|
||||||
Icon=jadx
|
Icon=jadx
|
||||||
Exec=jadx-gui %f
|
Exec=jadx-gui %f
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
Categories=Development;Java;
|
Categories=Development;Java;
|
||||||
Keywords=Java;Decompiler;
|
Keywords=Java;Decompiler;
|
||||||
|
StartupWMClass=jadx-gui-JadxGUI
|
||||||
|
|||||||
@@ -231,6 +231,16 @@ public class FileUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Path createTempFileNonPrefixed(String fileName) {
|
||||||
|
try {
|
||||||
|
Path path = Files.createFile(tempRootDir.resolve(fileName));
|
||||||
|
path.toFile().deleteOnExit();
|
||||||
|
return path;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new JadxRuntimeException("Failed to create non-prefixed temp file: " + fileName, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void copyStream(InputStream input, OutputStream output) throws IOException {
|
public static void copyStream(InputStream input, OutputStream output) throws IOException {
|
||||||
byte[] buffer = new byte[READ_BUFFER_SIZE];
|
byte[] buffer = new byte[READ_BUFFER_SIZE];
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -266,6 +276,11 @@ public class FileUtils {
|
|||||||
StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void writeFile(Path file, InputStream is) throws IOException {
|
||||||
|
FileUtils.makeDirsForFile(file);
|
||||||
|
Files.copy(is, file, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
}
|
||||||
|
|
||||||
public static String readFile(Path textFile) throws IOException {
|
public static String readFile(Path textFile) throws IOException {
|
||||||
return Files.readString(textFile);
|
return Files.readString(textFile);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,11 +110,19 @@ project.components.withType(AdhocComponentWithVariants::class.java).forEach { c
|
|||||||
|
|
||||||
tasks.startShadowScripts {
|
tasks.startShadowScripts {
|
||||||
doLast {
|
doLast {
|
||||||
val newContent =
|
val newWindowsScriptContent =
|
||||||
windowsScript.readText()
|
windowsScript.readText()
|
||||||
.replace("java.exe", "javaw.exe")
|
.replace("java.exe", "javaw.exe")
|
||||||
.replace("\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS%", "start \"jadx-gui\" /B \"%JAVA_EXE%\" %DEFAULT_JVM_OPTS%")
|
.replace("\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS%", "start \"jadx-gui\" /B \"%JAVA_EXE%\" %DEFAULT_JVM_OPTS%")
|
||||||
windowsScript.writeText(newContent)
|
// Add launch script path as a property
|
||||||
|
val newUnixScriptContent =
|
||||||
|
unixScript.readText()
|
||||||
|
.replace(
|
||||||
|
Regex("DEFAULT_JVM_OPTS=.+", RegexOption.MULTILINE),
|
||||||
|
{ result -> result.value + "\" \\\"-Djadx.launchScript.path=\$(realpath $0)\\\"\"" },
|
||||||
|
)
|
||||||
|
windowsScript.writeText(newWindowsScriptContent)
|
||||||
|
unixScript.writeText(newUnixScriptContent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -153,11 +153,13 @@ import jadx.gui.ui.treenodes.StartPageNode;
|
|||||||
import jadx.gui.ui.treenodes.SummaryNode;
|
import jadx.gui.ui.treenodes.SummaryNode;
|
||||||
import jadx.gui.update.JadxUpdate;
|
import jadx.gui.update.JadxUpdate;
|
||||||
import jadx.gui.utils.CacheObject;
|
import jadx.gui.utils.CacheObject;
|
||||||
|
import jadx.gui.utils.DesktopEntryUtils;
|
||||||
import jadx.gui.utils.FontUtils;
|
import jadx.gui.utils.FontUtils;
|
||||||
import jadx.gui.utils.ILoadListener;
|
import jadx.gui.utils.ILoadListener;
|
||||||
import jadx.gui.utils.LafManager;
|
import jadx.gui.utils.LafManager;
|
||||||
import jadx.gui.utils.Link;
|
import jadx.gui.utils.Link;
|
||||||
import jadx.gui.utils.NLS;
|
import jadx.gui.utils.NLS;
|
||||||
|
import jadx.gui.utils.SystemInfo;
|
||||||
import jadx.gui.utils.UiUtils;
|
import jadx.gui.utils.UiUtils;
|
||||||
import jadx.gui.utils.dbg.UIWatchDog;
|
import jadx.gui.utils.dbg.UIWatchDog;
|
||||||
import jadx.gui.utils.fileswatcher.LiveReloadWorker;
|
import jadx.gui.utils.fileswatcher.LiveReloadWorker;
|
||||||
@@ -1186,6 +1188,9 @@ public class MainWindow extends JFrame implements ExportProjectDialog.ExportProj
|
|||||||
JMenu help = new JadxMenu(NLS.str("menu.help"), shortcutsController);
|
JMenu help = new JadxMenu(NLS.str("menu.help"), shortcutsController);
|
||||||
help.setMnemonic(KeyEvent.VK_H);
|
help.setMnemonic(KeyEvent.VK_H);
|
||||||
help.add(showLogAction);
|
help.add(showLogAction);
|
||||||
|
if (SystemInfo.IS_UNIX && !SystemInfo.IS_MAC) {
|
||||||
|
help.add(new JadxGuiAction(ActionModel.CREATE_DESKTOP_ENTRY, this::createDesktopEntry));
|
||||||
|
}
|
||||||
if (Jadx.isDevVersion()) {
|
if (Jadx.isDevVersion()) {
|
||||||
help.add(new AbstractAction("Show sample error report") {
|
help.add(new AbstractAction("Show sample error report") {
|
||||||
@Override
|
@Override
|
||||||
@@ -1724,6 +1729,16 @@ public class MainWindow extends JFrame implements ExportProjectDialog.ExportProj
|
|||||||
pluginsMenu.add(item);
|
pluginsMenu.add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createDesktopEntry() {
|
||||||
|
if (DesktopEntryUtils.createDesktopEntry()) {
|
||||||
|
JOptionPane.showMessageDialog(this, NLS.str("message.desktop_entry_creation_success"),
|
||||||
|
NLS.str("message.success_title"), JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
} else {
|
||||||
|
JOptionPane.showMessageDialog(this, NLS.str("message.desktop_entry_creation_error"),
|
||||||
|
NLS.str("message.errorTitle"), JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public RenameMappingsGui getRenameMappings() {
|
public RenameMappingsGui getRenameMappings() {
|
||||||
return renameMappings;
|
return renameMappings;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ public enum ActionModel {
|
|||||||
Shortcut.keyboard(KeyEvent.VK_D, UiUtils.ctrlButton() | KeyEvent.ALT_DOWN_MASK)),
|
Shortcut.keyboard(KeyEvent.VK_D, UiUtils.ctrlButton() | KeyEvent.ALT_DOWN_MASK)),
|
||||||
SHOW_LOG(MENU_TOOLBAR, "menu.log", "menu.log", "ui/logVerbose",
|
SHOW_LOG(MENU_TOOLBAR, "menu.log", "menu.log", "ui/logVerbose",
|
||||||
Shortcut.keyboard(KeyEvent.VK_L, UiUtils.ctrlButton() | KeyEvent.SHIFT_DOWN_MASK)),
|
Shortcut.keyboard(KeyEvent.VK_L, UiUtils.ctrlButton() | KeyEvent.SHIFT_DOWN_MASK)),
|
||||||
|
CREATE_DESKTOP_ENTRY(MENU_TOOLBAR, "menu.create_desktop_entry", "menu.create_desktop_entry", null, Shortcut.none()),
|
||||||
BACK(MENU_TOOLBAR, "nav.back", "nav.back", "ui/left",
|
BACK(MENU_TOOLBAR, "nav.back", "nav.back", "ui/left",
|
||||||
Shortcut.keyboard(KeyEvent.VK_ESCAPE)),
|
Shortcut.keyboard(KeyEvent.VK_ESCAPE)),
|
||||||
BACK_V(MENU_TOOLBAR, "nav.back", "nav.back", "ui/left",
|
BACK_V(MENU_TOOLBAR, "nav.back", "nav.back", "ui/left",
|
||||||
|
|||||||
@@ -0,0 +1,155 @@
|
|||||||
|
package jadx.gui.utils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import jadx.core.export.TemplateFile;
|
||||||
|
import jadx.core.utils.files.FileUtils;
|
||||||
|
|
||||||
|
public class DesktopEntryUtils {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(DesktopEntryUtils.class);
|
||||||
|
private static final Map<Integer, String> SIZE_TO_LOGO_MAP = Map.of(
|
||||||
|
16, "jadx-logo-16px.png",
|
||||||
|
32, "jadx-logo-32px.png",
|
||||||
|
48, "jadx-logo-48px.png",
|
||||||
|
252, "jadx-logo.png",
|
||||||
|
256, "jadx-logo.png");
|
||||||
|
private static final Path XDG_DESKTOP_MENU_COMMAND_PATH = findExecutablePath("xdg-desktop-menu");
|
||||||
|
private static final Path XDG_ICON_RESOURCE_COMMAND_PATH = findExecutablePath("xdg-icon-resource");
|
||||||
|
|
||||||
|
public static boolean createDesktopEntry() {
|
||||||
|
if (XDG_DESKTOP_MENU_COMMAND_PATH == null) {
|
||||||
|
LOG.error("xdg-desktop-menu was not found in $PATH");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (XDG_ICON_RESOURCE_COMMAND_PATH == null) {
|
||||||
|
LOG.error("xdg-icon-resource was not found in $PATH");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Path desktopTempFile = FileUtils.createTempFileNonPrefixed("jadx-gui.desktop");
|
||||||
|
Path iconTempFolder = FileUtils.createTempDir("logos");
|
||||||
|
LOG.debug("Creating desktop with temp files: {}, {}", desktopTempFile, iconTempFolder);
|
||||||
|
try {
|
||||||
|
return createDesktopEntry(desktopTempFile, iconTempFolder);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
FileUtils.deleteFileIfExists(desktopTempFile);
|
||||||
|
FileUtils.deleteDirIfExists(iconTempFolder);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Failed to clean up temp files", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean createDesktopEntry(Path desktopTempFile, Path iconTempFolder) {
|
||||||
|
String launchScriptPath = getLaunchScriptPath();
|
||||||
|
if (launchScriptPath == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (Map.Entry<Integer, String> entry : SIZE_TO_LOGO_MAP.entrySet()) {
|
||||||
|
Path path = iconTempFolder.resolve(entry.getKey() + ".png");
|
||||||
|
if (!writeLogoFile(entry.getValue(), path)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!installIcon(entry.getKey(), path)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!writeDesktopFile(launchScriptPath, desktopTempFile)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return installDesktopEntry(desktopTempFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean installDesktopEntry(Path desktopTempFile) {
|
||||||
|
try {
|
||||||
|
ProcessBuilder desktopFileInstallCommand = new ProcessBuilder(Objects.requireNonNull(XDG_DESKTOP_MENU_COMMAND_PATH).toString(),
|
||||||
|
"install", desktopTempFile.toString());
|
||||||
|
Process process = desktopFileInstallCommand.start();
|
||||||
|
int statusCode = process.waitFor();
|
||||||
|
if (statusCode != 0) {
|
||||||
|
LOG.error("Got error code {} while installing desktop file", statusCode);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("Failed to install desktop file", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LOG.info("Successfully installed desktop file");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean installIcon(int size, Path iconPath) {
|
||||||
|
try {
|
||||||
|
ProcessBuilder iconInstallCommand =
|
||||||
|
new ProcessBuilder(Objects.requireNonNull(XDG_ICON_RESOURCE_COMMAND_PATH).toString(), "install", "--novendor", "--size",
|
||||||
|
String.valueOf(size), iconPath.toString(),
|
||||||
|
"jadx");
|
||||||
|
Process process = iconInstallCommand.start();
|
||||||
|
int statusCode = process.waitFor();
|
||||||
|
if (statusCode != 0) {
|
||||||
|
LOG.error("Got error code {} while installing icon of size {}", statusCode, size);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("Failed to install icon of size {}", size, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LOG.info("Successfully installed icon of size {}", size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Path findExecutablePath(String executableName) {
|
||||||
|
for (String pathDirectory : System.getenv("PATH").split(File.pathSeparator)) {
|
||||||
|
Path path = Paths.get(pathDirectory, executableName);
|
||||||
|
if (path.toFile().isFile() && path.toFile().canExecute()) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean writeDesktopFile(String launchScriptPath, Path desktopFilePath) {
|
||||||
|
try {
|
||||||
|
TemplateFile tmpl = TemplateFile.fromResources("/files/jadx-gui.desktop.tmpl");
|
||||||
|
tmpl.add("launchScriptPath", launchScriptPath);
|
||||||
|
FileUtils.writeFile(desktopFilePath, tmpl.build());
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("Failed to save .desktop file at: {}", desktopFilePath, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LOG.debug("Wrote .desktop file to {}", desktopFilePath);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean writeLogoFile(String logoFile, Path logoPath) {
|
||||||
|
try (InputStream is = DesktopEntryUtils.class.getResourceAsStream("/logos/" + logoFile)) {
|
||||||
|
FileUtils.writeFile(logoPath, is);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("Failed to write logo file at: {}", logoPath, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LOG.debug("Wrote logo file to: {}", logoPath);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @Nullable String getLaunchScriptPath() {
|
||||||
|
String launchScriptPath = System.getProperty("jadx.launchScript.path");
|
||||||
|
if (launchScriptPath.isEmpty()) {
|
||||||
|
LOG.error(
|
||||||
|
"The jadx.launchScript.path property is not set. Please launch JADX with the bundled launch script or set it to the appropriate value yourself.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
LOG.debug("JADX launch script path: {}", launchScriptPath);
|
||||||
|
return launchScriptPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Name=JADX GUI
|
||||||
|
Comment=Dex to Java decompiler
|
||||||
|
Icon=jadx
|
||||||
|
Exec={{launchScriptPath}} %f
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
Categories=Development;Java;
|
||||||
|
Keywords=Java;Decompiler;
|
||||||
|
StartupWMClass=jadx-gui-JadxGUI
|
||||||
@@ -24,6 +24,7 @@ menu.tools=Tools
|
|||||||
#menu.reset_cache=Reset code cache
|
#menu.reset_cache=Reset code cache
|
||||||
menu.deobfuscation=Deobfuskierung
|
menu.deobfuscation=Deobfuskierung
|
||||||
menu.log=Log-Anzeige
|
menu.log=Log-Anzeige
|
||||||
|
#menu.create_desktop_entry=Create Desktop Entry
|
||||||
menu.help=Hilfe
|
menu.help=Hilfe
|
||||||
menu.about=Über
|
menu.about=Über
|
||||||
#menu.quark=Quark Engine
|
#menu.quark=Quark Engine
|
||||||
@@ -113,6 +114,9 @@ message.indexingClassesSkipped=<html>Jadx hat nur noch wenig Speicherplatz. Dahe
|
|||||||
#message.enter_new_name=Enter new name
|
#message.enter_new_name=Enter new name
|
||||||
#message.could_not_rename=Can't rename the file
|
#message.could_not_rename=Can't rename the file
|
||||||
#message.confirm_remove_script=Do you really want to remove script?
|
#message.confirm_remove_script=Do you really want to remove script?
|
||||||
|
#message.desktop_entry_creation_error=Failed to create desktop entry (check log for details).
|
||||||
|
#message.desktop_entry_creation_success=Desktop entry created successfully!
|
||||||
|
#message.success_title=Success
|
||||||
|
|
||||||
heapUsage.text=JADX-Speicherauslastung: %.2f GB von %.2f GB
|
heapUsage.text=JADX-Speicherauslastung: %.2f GB von %.2f GB
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ menu.decompile_all=Decompile all classes
|
|||||||
menu.reset_cache=Reset code cache
|
menu.reset_cache=Reset code cache
|
||||||
menu.deobfuscation=Deobfuscation
|
menu.deobfuscation=Deobfuscation
|
||||||
menu.log=Log Viewer
|
menu.log=Log Viewer
|
||||||
|
menu.create_desktop_entry=Create Desktop Entry
|
||||||
menu.help=Help
|
menu.help=Help
|
||||||
menu.about=About
|
menu.about=About
|
||||||
menu.quark=Quark Engine
|
menu.quark=Quark Engine
|
||||||
@@ -113,6 +114,9 @@ message.indexingClassesSkipped=<html>Jadx is running low on memory. Therefore %d
|
|||||||
message.enter_new_name=Enter new name
|
message.enter_new_name=Enter new name
|
||||||
message.could_not_rename=Can't rename the file
|
message.could_not_rename=Can't rename the file
|
||||||
message.confirm_remove_script=Do you really want to remove script?
|
message.confirm_remove_script=Do you really want to remove script?
|
||||||
|
message.desktop_entry_creation_error=Failed to create desktop entry (check log for details).
|
||||||
|
message.desktop_entry_creation_success=Desktop entry created successfully!
|
||||||
|
message.success_title=Success
|
||||||
|
|
||||||
heapUsage.text=JADX memory usage: %.2f GB of %.2f GB
|
heapUsage.text=JADX memory usage: %.2f GB of %.2f GB
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ menu.tools=Herramientas
|
|||||||
#menu.reset_cache=Reset code cache
|
#menu.reset_cache=Reset code cache
|
||||||
menu.deobfuscation=Desofuscación
|
menu.deobfuscation=Desofuscación
|
||||||
menu.log=Visor log
|
menu.log=Visor log
|
||||||
|
#menu.create_desktop_entry=Create Desktop Entry
|
||||||
menu.help=Ayuda
|
menu.help=Ayuda
|
||||||
menu.about=Acerca de...
|
menu.about=Acerca de...
|
||||||
#menu.quark=Quark Engine
|
#menu.quark=Quark Engine
|
||||||
@@ -113,6 +114,9 @@ nav.forward=Adelante
|
|||||||
#message.enter_new_name=Enter new name
|
#message.enter_new_name=Enter new name
|
||||||
#message.could_not_rename=Can't rename the file
|
#message.could_not_rename=Can't rename the file
|
||||||
#message.confirm_remove_script=Do you really want to remove script?
|
#message.confirm_remove_script=Do you really want to remove script?
|
||||||
|
#message.desktop_entry_creation_error=Failed to create desktop entry (check log for details).
|
||||||
|
#message.desktop_entry_creation_success=Desktop entry created successfully!
|
||||||
|
#message.success_title=Success
|
||||||
|
|
||||||
#heapUsage.text=JADX memory usage: %.2f GB of %.2f GB
|
#heapUsage.text=JADX memory usage: %.2f GB of %.2f GB
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ menu.decompile_all=Deskompilasi semua kelas
|
|||||||
menu.reset_cache=Reset cache kode
|
menu.reset_cache=Reset cache kode
|
||||||
menu.deobfuscation=Deobfikasi
|
menu.deobfuscation=Deobfikasi
|
||||||
menu.log=Pemantau Log
|
menu.log=Pemantau Log
|
||||||
|
#menu.create_desktop_entry=Create Desktop Entry
|
||||||
menu.help=Bantuan
|
menu.help=Bantuan
|
||||||
menu.about=Tentang
|
menu.about=Tentang
|
||||||
menu.quark=Mesin Quark
|
menu.quark=Mesin Quark
|
||||||
@@ -113,6 +114,9 @@ message.indexingClassesSkipped=<html>JADX kekurangan memori. Oleh karena itu %d
|
|||||||
#message.enter_new_name=Enter new name
|
#message.enter_new_name=Enter new name
|
||||||
#message.could_not_rename=Can't rename the file
|
#message.could_not_rename=Can't rename the file
|
||||||
#message.confirm_remove_script=Do you really want to remove script?
|
#message.confirm_remove_script=Do you really want to remove script?
|
||||||
|
#message.desktop_entry_creation_error=Failed to create desktop entry (check log for details).
|
||||||
|
#message.desktop_entry_creation_success=Desktop entry created successfully!
|
||||||
|
#message.success_title=Success
|
||||||
|
|
||||||
heapUsage.text=Penggunaan memori JADX: %.2f GB dari %.2f GB
|
heapUsage.text=Penggunaan memori JADX: %.2f GB dari %.2f GB
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ menu.tools=도구
|
|||||||
#menu.reset_cache=Reset code cache
|
#menu.reset_cache=Reset code cache
|
||||||
menu.deobfuscation=난독화 해제
|
menu.deobfuscation=난독화 해제
|
||||||
menu.log=로그 뷰어
|
menu.log=로그 뷰어
|
||||||
|
#menu.create_desktop_entry=Create Desktop Entry
|
||||||
menu.help=도움말
|
menu.help=도움말
|
||||||
menu.about=정보
|
menu.about=정보
|
||||||
#menu.quark=Quark Engine
|
#menu.quark=Quark Engine
|
||||||
@@ -113,6 +114,9 @@ message.indexingClassesSkipped=<html>Jadx의 메모리가 부족합니다. 따
|
|||||||
#message.enter_new_name=Enter new name
|
#message.enter_new_name=Enter new name
|
||||||
#message.could_not_rename=Can't rename the file
|
#message.could_not_rename=Can't rename the file
|
||||||
#message.confirm_remove_script=Do you really want to remove script?
|
#message.confirm_remove_script=Do you really want to remove script?
|
||||||
|
#message.desktop_entry_creation_error=Failed to create desktop entry (check log for details).
|
||||||
|
#message.desktop_entry_creation_success=Desktop entry created successfully!
|
||||||
|
#message.success_title=Success
|
||||||
|
|
||||||
heapUsage.text=JADX 메모리 사용량 : %.2f GB / %.2f GB
|
heapUsage.text=JADX 메모리 사용량 : %.2f GB / %.2f GB
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ menu.tools=Ferramentas
|
|||||||
#menu.reset_cache=Reset code cache
|
#menu.reset_cache=Reset code cache
|
||||||
menu.deobfuscation=Desofuscar
|
menu.deobfuscation=Desofuscar
|
||||||
menu.log=Visualizador de log
|
menu.log=Visualizador de log
|
||||||
|
#menu.create_desktop_entry=Create Desktop Entry
|
||||||
menu.help=Ajuda
|
menu.help=Ajuda
|
||||||
menu.about=Sobre
|
menu.about=Sobre
|
||||||
#menu.quark=Quark Engine
|
#menu.quark=Quark Engine
|
||||||
@@ -113,6 +114,9 @@ message.indexingClassesSkipped=<html>Jadx está rodando com pouca memória. Por
|
|||||||
#message.enter_new_name=Enter new name
|
#message.enter_new_name=Enter new name
|
||||||
#message.could_not_rename=Can't rename the file
|
#message.could_not_rename=Can't rename the file
|
||||||
#message.confirm_remove_script=Do you really want to remove script?
|
#message.confirm_remove_script=Do you really want to remove script?
|
||||||
|
#message.desktop_entry_creation_error=Failed to create desktop entry (check log for details).
|
||||||
|
#message.desktop_entry_creation_success=Desktop entry created successfully!
|
||||||
|
#message.success_title=Success
|
||||||
|
|
||||||
heapUsage.text=Uso de memória do JADX: %.2f GB of %.2f GB
|
heapUsage.text=Uso de memória do JADX: %.2f GB of %.2f GB
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ menu.decompile_all=Декомпилировать все
|
|||||||
menu.reset_cache=Сбросить кэш
|
menu.reset_cache=Сбросить кэш
|
||||||
menu.deobfuscation=Деобфускация
|
menu.deobfuscation=Деобфускация
|
||||||
menu.log=Просмотр логов
|
menu.log=Просмотр логов
|
||||||
|
#menu.create_desktop_entry=Create Desktop Entry
|
||||||
menu.help=Помощь
|
menu.help=Помощь
|
||||||
menu.about=О программе
|
menu.about=О программе
|
||||||
#menu.quark=Quark Engine
|
#menu.quark=Quark Engine
|
||||||
@@ -113,6 +114,9 @@ message.indexingClassesSkipped=<html>JaDX запущен с малым коли
|
|||||||
#message.enter_new_name=Enter new name
|
#message.enter_new_name=Enter new name
|
||||||
#message.could_not_rename=Can't rename the file
|
#message.could_not_rename=Can't rename the file
|
||||||
#message.confirm_remove_script=Do you really want to remove script?
|
#message.confirm_remove_script=Do you really want to remove script?
|
||||||
|
#message.desktop_entry_creation_error=Failed to create desktop entry (check log for details).
|
||||||
|
#message.desktop_entry_creation_success=Desktop entry created successfully!
|
||||||
|
#message.success_title=Success
|
||||||
|
|
||||||
heapUsage.text=JADX использует: %.2f ГБ из %.2f ГБ
|
heapUsage.text=JADX использует: %.2f ГБ из %.2f ГБ
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ menu.decompile_all=反编译所有类
|
|||||||
menu.reset_cache=重置代码缓存
|
menu.reset_cache=重置代码缓存
|
||||||
menu.deobfuscation=反混淆
|
menu.deobfuscation=反混淆
|
||||||
menu.log=日志查看器
|
menu.log=日志查看器
|
||||||
|
#menu.create_desktop_entry=Create Desktop Entry
|
||||||
menu.help=帮助
|
menu.help=帮助
|
||||||
menu.about=关于
|
menu.about=关于
|
||||||
menu.quark=Quark 引擎
|
menu.quark=Quark 引擎
|
||||||
@@ -113,6 +114,9 @@ message.indexingClassesSkipped=<html>Jadx 的内存不足。因此,%d 个类
|
|||||||
message.enter_new_name=输入新名称
|
message.enter_new_name=输入新名称
|
||||||
message.could_not_rename=无法重命名文件
|
message.could_not_rename=无法重命名文件
|
||||||
message.confirm_remove_script=您真的要删除脚本吗?
|
message.confirm_remove_script=您真的要删除脚本吗?
|
||||||
|
#message.desktop_entry_creation_error=Failed to create desktop entry (check log for details).
|
||||||
|
#message.desktop_entry_creation_success=Desktop entry created successfully!
|
||||||
|
#message.success_title=Success
|
||||||
|
|
||||||
heapUsage.text=JADX 内存使用率:%.2f GB / %.2f GB
|
heapUsage.text=JADX 内存使用率:%.2f GB / %.2f GB
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ menu.decompile_all=反編譯所有類別
|
|||||||
menu.reset_cache=重設程式碼快取
|
menu.reset_cache=重設程式碼快取
|
||||||
menu.deobfuscation=去模糊化
|
menu.deobfuscation=去模糊化
|
||||||
menu.log=記錄檔檢視器
|
menu.log=記錄檔檢視器
|
||||||
|
#menu.create_desktop_entry=Create Desktop Entry
|
||||||
menu.help=幫助
|
menu.help=幫助
|
||||||
menu.about=關於
|
menu.about=關於
|
||||||
menu.quark= Quark 引擎
|
menu.quark= Quark 引擎
|
||||||
@@ -113,6 +114,9 @@ message.indexingClassesSkipped=<html>Jadx 的記憶體不足。故 %d 個類別
|
|||||||
#message.enter_new_name=Enter new name
|
#message.enter_new_name=Enter new name
|
||||||
#message.could_not_rename=Can't rename the file
|
#message.could_not_rename=Can't rename the file
|
||||||
#message.confirm_remove_script=Do you really want to remove script?
|
#message.confirm_remove_script=Do you really want to remove script?
|
||||||
|
#message.desktop_entry_creation_error=Failed to create desktop entry (check log for details).
|
||||||
|
#message.desktop_entry_creation_success=Desktop entry created successfully!
|
||||||
|
#message.success_title=Success
|
||||||
|
|
||||||
heapUsage.text=JADX 記憶體使用率:%.2f GB / %.2f GB
|
heapUsage.text=JADX 記憶體使用率:%.2f GB / %.2f GB
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user