From 0abc5b493a0673efe75d3b97105892bd5edd44d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sat, 18 Nov 2023 12:28:33 +0100 Subject: [PATCH] Fixed #2025, #2078, #2053 Problems starting the app on Windows when the username has unicode characters --- CHANGELOG.md | 6 +- .../flash/configuration/Configuration.java | 4 + src/com/jpexs/decompiler/flash/gui/Main.java | 113 ++++++++++++++---- .../locales/AdvancedSettingsDialog.properties | 3 + .../AdvancedSettingsDialog_cs.properties | 3 + 5 files changed, 103 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index abbfc3d8e..22e422b35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ All notable changes to this project will be documented in this file. - [#2111] Flex AS3 editation - use SWF dependencies defined in GUI - SWF dependencies label was not updated on startup - [#2127] Wrong parameter order in AS1/2 P-code Action GetURL2 documentation +- [#2025], [#2078], [#2053] Problems starting the app on Windows when the username has unicode characters ### Changed - [#2120] Exported assets no longer take names from assigned classes if there is more than 1 assigned class @@ -3289,8 +3290,11 @@ Major version of SWF to XML export changed to 2. [#2116]: https://www.free-decompiler.com/flash/issues/2116 [#2122]: https://www.free-decompiler.com/flash/issues/2122 [#2111]: https://www.free-decompiler.com/flash/issues/2111 -[#2120]: https://www.free-decompiler.com/flash/issues/2120 [#2127]: https://www.free-decompiler.com/flash/issues/2127 +[#2025]: https://www.free-decompiler.com/flash/issues/2025 +[#2078]: https://www.free-decompiler.com/flash/issues/2078 +[#2053]: https://www.free-decompiler.com/flash/issues/2053 +[#2120]: https://www.free-decompiler.com/flash/issues/2120 [#1130]: https://www.free-decompiler.com/flash/issues/1130 [#1220]: https://www.free-decompiler.com/flash/issues/1220 [#1717]: https://www.free-decompiler.com/flash/issues/1717 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java index 84686edc9..69623ad9d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -987,6 +987,10 @@ public final class Configuration { @ConfigurationCategory("export") public static ConfigurationItem as3ExportNamesUseClassNamesOnly = null; + @ConfigurationDefaultString("") + @ConfigurationDirectory + public static ConfigurationItem jnaTempDirectory = null; + private enum OSId { WINDOWS, OSX, UNIX } diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index 80f1514d2..bad77df4c 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -22,10 +22,8 @@ import com.eclipsesource.json.JsonObject; import com.eclipsesource.json.JsonValue; import com.jpexs.debugger.flash.Debugger; import com.jpexs.debugger.flash.DebuggerCommands; -import com.jpexs.debugger.flash.DebuggerConnection; import com.jpexs.debugger.flash.Variable; import com.jpexs.debugger.flash.VariableType; -import com.jpexs.debugger.flash.messages.in.InCallFunction; import com.jpexs.decompiler.flash.ApplicationInfo; import com.jpexs.decompiler.flash.Bundle; import com.jpexs.decompiler.flash.EventListener; @@ -48,7 +46,6 @@ import com.jpexs.decompiler.flash.console.CommandLineArgumentParser; import com.jpexs.decompiler.flash.console.ContextMenuTools; import com.jpexs.decompiler.flash.exporters.modes.ExeExportMode; import com.jpexs.decompiler.flash.gfx.GfxConvertor; -import com.jpexs.decompiler.flash.gui.abc.LinkDialog; import com.jpexs.decompiler.flash.gui.debugger.DebugListener; import com.jpexs.decompiler.flash.gui.debugger.DebuggerTools; import com.jpexs.decompiler.flash.gui.pipes.FirstInstance; @@ -95,6 +92,7 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -2320,27 +2318,7 @@ public class Main { initUiLang(); - if (Configuration.useRibbonInterface.get()) { - View.setLookAndFeel(); - } else { - try { - UIManager.put(SubstanceLookAndFeel.COLORIZATION_FACTOR, null); - UIManager.put("Tree.expandedIcon", null); - UIManager.put("Tree.collapsedIcon", null); - UIManager.put("ColorChooserUI", null); - UIManager.put("ColorChooser.swatchesRecentSwatchSize", null); - UIManager.put("ColorChooser.swatchesSwatchSize", null); - UIManager.put("RibbonApplicationMenuPopupPanelUI", null); - UIManager.put("RibbonApplicationMenuButtonUI", null); - UIManager.put("ProgressBarUI", null); - UIManager.put("TextField.background", null); - UIManager.put("FormattedTextField.background", null); - UIManager.put("CommandButtonUI", null); - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { - logger.log(Level.SEVERE, null, ex); - } - } + initLookAndFeel(); View.execInEventDispatch(() -> { ErrorLogFrame.createNewInstance(); @@ -2639,6 +2617,90 @@ public class Main { UIManager.put("ColorChooser.sampleText", AppStrings.translate("ColorChooser.sampleText")); } + + public static String getDefaultCharacterEncoding() { + // Creating an array of byte type chars and + // passing random alphabet as an argument.abstract + // Say alphabet be 'w' + byte[] byte_array = { 'w' }; + + // Creating an object of InputStream + InputStream instream + = new ByteArrayInputStream(byte_array); + + // Now, opening new file input stream reader + InputStreamReader streamreader + = new InputStreamReader(instream); + String defaultCharset = streamreader.getEncoding(); + + // Returning default character encoding + return defaultCharset; + } + + private static void initLookAndFeel() { + if (Configuration.useRibbonInterface.get()) { + View.setLookAndFeel(); + } else { + try { + UIManager.put(SubstanceLookAndFeel.COLORIZATION_FACTOR, null); + UIManager.put("Tree.expandedIcon", null); + UIManager.put("Tree.collapsedIcon", null); + UIManager.put("ColorChooserUI", null); + UIManager.put("ColorChooser.swatchesRecentSwatchSize", null); + UIManager.put("ColorChooser.swatchesSwatchSize", null); + UIManager.put("RibbonApplicationMenuPopupPanelUI", null); + UIManager.put("RibbonApplicationMenuButtonUI", null); + UIManager.put("ProgressBarUI", null); + UIManager.put("TextField.background", null); + UIManager.put("FormattedTextField.background", null); + UIManager.put("CommandButtonUI", null); + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { + logger.log(Level.SEVERE, null, ex); + } + } + } + + public static void initJna() { + if (Platform.isWindows()) { + String jnaTempDir = Configuration.jnaTempDirectory.get(); + if (!jnaTempDir.isEmpty()) { + System.setProperty("jna.tmpdir", jnaTempDir); + } else { + jnaTempDir = System.getProperty("java.io.tmpdir"); + } + + try { + com.sun.jna.Native.toByteArray(""); //Trigger JNA.Native class static initializer, which will load the DLL + } catch (UnsatisfiedLinkError error) { + initLookAndFeel(); + ViewMessages.showMessageDialog(null, + "Cannot read JNA DLL file from current Temporary directory:\r\n" + + jnaTempDir + "\r\n" + + "The reason is probably Unicode characters in the path or in your username.\r\n" + + "In the following dialog, please specify new temporary directory path,\r\n" + + "which DOES NOT contain any special Unicode characters. (Only basic latin supported)\r\n" + + "Then application restart is required.", + "FFDec JNA Error", JOptionPane.ERROR_MESSAGE); + View.execInEventDispatch(new Runnable() { + @Override + public void run() { + JFileChooser fc = new JFileChooser(); + fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + fc.setDialogTitle("Select new temporary directory without Unicode characters in its path"); + if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { + File dir = Helper.fixDialogFile(fc.getSelectedFile()); + Configuration.jnaTempDirectory.set(dir.getAbsolutePath()); + Configuration.saveConfig(); + System.exit(0); + } else { + System.exit(1); + } + } + }); + } + } + } public static void initLang() { if (!Configuration.locale.hasValue()) { @@ -2738,7 +2800,7 @@ public class Main { * @param args the command line arguments * @throws IOException On error */ - public static void main(String[] args) throws IOException { + public static void main(String[] args) throws IOException { decodeLaunch5jArgs(args); setSessionLoaded(false); @@ -2753,6 +2815,7 @@ public class Main { AppStrings.setResourceClass(MainFrame.class); initLogging(Configuration._debugMode.get()); + initJna(); initLang(); if (Configuration.cacheOnDisk.get()) { diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties index ff65886a9..84c16615e 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties @@ -754,3 +754,6 @@ config.description.boxBlurPixelsLimit = Maximum number of pixels to calculate bo config.name.as3ExportNamesUseClassNamesOnly = Exported assets have names bases on classes only (AS3) config.description.as3ExportNamesUseClassNamesOnly = Exported asset files (images, sound, ...) take names only from SymbolClass tag - their assigned classes. No character id is added. Also when multiple classes is assigned to same asset, it is exported multiple times. (For ActionScript 3 SWFs) + +config.name.jnaTempDirectory = JNA Temporary directory +config.description.jnaTempDirectory = Temporary directory path for JNA DLLs, etc. This needs to be set to a path not including any Unicode characters. When not set, current user TEMP directory is used. diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties index 8b767368d..3f779f77c 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties @@ -744,3 +744,6 @@ config.description.boxBlurPixelsLimit = Maxim\u00e1ln\u00ed po\u010det pixel\u01 config.name.as3ExportNamesUseClassNamesOnly = Exportovan\u00e9 zdroje maj\u00ed n\u00e1zvy zalo\u017een\u00e9 pouze na n\u00e1zvech t\u0159\u00edd (AS3) config.description.as3ExportNamesUseClassNamesOnly = Exportovan\u00e9 soubory zdroj\u016f (obr\u00e1zky, zvuky, ...) p\u0159eberou n\u00e1zvy z SymbolClass tagu - jejich p\u0159i\u0159azen\u00e9 t\u0159\u00eddy. Id charakteru nebude p\u0159id\u00e1no. Tak\u00e9 pokud bude v\u00edce t\u0159\u00edd p\u0159i\u0159azeno jednomu assetu, bude exportov\u00e1n v\u00edcekr\u00e1t. (Pro ActionScript 3 SWF soubory) + +config.name.jnaTempDirectory = Do\u010dasn\u00fd adres\u00e1\u0159 JNA +config.description.jnaTempDirectory = Cesta k do\u010dasn\u00e9mu adres\u00e1\u0159i pro JNA DLL knihovny, atd. Toto mus\u00ed b\u00fdt nastaveno na cestu, kter\u00e1 neobsahuje \u017e\u00e1dn\u00e9 Unicode znaky. Pokud nen\u00ed nastaveno, je pou\u017eit TEMP adres\u00e1\u0159 aktu\u00e1ln\u00edho u\u017eivatele.