diff --git a/CHANGELOG.md b/CHANGELOG.md index 65bcf7fba..b4cda264a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file. (Can be turned on in advanced settings) - Icons for Simple editor library folders - [#2448] Simple editor - Option to turn off half transparent parent layers +- Localized "Open with FFDec" context menu (switch association off/on to apply if already installed) ### Fixed - [#2424] DefineEditText handling of letterSpacing, font size on incorrect values @@ -47,6 +48,7 @@ All notable changes to this project will be documented in this file. - [#2419] AS3 - There should be empty line after class header - AS 1/2/3 - Fast switching of scripts causing incorrect caret position remembered - AS 1/2 - Remembering caret position for frames +- Cleaner file association ## [22.0.2] - 2025-01-17 ### Added diff --git a/installer.nsi b/installer.nsi index af650b18a..946bfeb35 100644 --- a/installer.nsi +++ b/installer.nsi @@ -25,7 +25,7 @@ Unicode true SetCompressor /SOLID lzma !include "StrFunc.nsh" !include x64.nsh - +!include Integration.nsh !define APP_SHORTVERNAME "JPEXS FFDec v. ${APP_VER}" @@ -362,10 +362,63 @@ var SMDir Exch $R2 !macroend +var clsname +!define VERB "ffdec" +!define VERBNAME "Open with FFDec" +!define MUIVERB_ID "1001" +var ext !define REG_CLASSES_HKEY HKLM +Function un.RemoveExtContextMenu + pop $ext + ; ----------- Remove "Open With" + DeleteRegKey ${REG_CLASSES_HKEY} "Software\Classes\Applications\${APP_EXENAME}" + ReadRegStr $clsname ${REG_CLASSES_HKEY} "Software\Classes\.$ext" "" + IfErrors step2 + DeleteRegKey ${REG_CLASSES_HKEY} "Software\Classes\$clsname\shell\${VERB}" + step2: + DeleteRegKey ${REG_CLASSES_HKEY} "Software\Classes\SystemFileAssociations\.$ext\Shell\${VERB}" +FunctionEnd + +Function AddToExtContextMenu + pop $ext + + ; ------------ Register "Open With" + WriteRegStr ${REG_CLASSES_HKEY} "Software\Classes\Applications\${APP_EXENAME}\shell\open" "" ${VERB} + WriteRegStr ${REG_CLASSES_HKEY} "Software\Classes\Applications\${APP_EXENAME}\shell\open\command" "" '"$INSTDIR\${APP_EXENAME}" "%1"' + WriteRegStr ${REG_CLASSES_HKEY} "Software\Classes\.$ext\OpenWithList\${APP_EXENAME}" "" "" + + ; ------------ Associate file extension + !insertmacro IfKeyExists ${REG_CLASSES_HKEY} "Software\Classes" ".$ext" + Pop $R0 + ${If} $R0 == 0 + WriteRegStr ${REG_CLASSES_HKEY} "Software\Classes\.$ext" "" "ShockwaveFlash.ShockwaveFlash" + ${EndIf} + + ReadRegStr $clsname ${REG_CLASSES_HKEY} "Software\Classes\.$ext" "" + !insertmacro IfKeyExists ${REG_CLASSES_HKEY} "Software\Classes" $clsname + Pop $R0 + ${If} $R0 == 0 + WriteRegStr ${REG_CLASSES_HKEY} "Software\Classes\$clsname" "" "Flash Movie" + ${EndIf} + + WriteRegStr ${REG_CLASSES_HKEY} "Software\Classes\$clsname\shell\${VERB}" "" "${VERBNAME}" + WriteRegStr ${REG_CLASSES_HKEY} "Software\Classes\$clsname\shell\${VERB}\command" "" '"$INSTDIR\${APP_EXENAME}" "%1"' + WriteRegStr ${REG_CLASSES_HKEY} "Software\Classes\$clsname\shell\${VERB}" "MUIVerb" '@$INSTDIR\${APP_EXENAME},-${MUIVERB_ID}' + + + ; ----------- Associate global verb - if anybody changes default app, it won't remove the verbs + !insertmacro IfKeyExists ${REG_CLASSES_HKEY} "Software\Classes" "SystemFileAssociations" + Pop $R0 + ${If} $R0 == 1 + WriteRegStr ${REG_CLASSES_HKEY} "Software\Classes\SystemFileAssociations\.$ext\Shell\${VERB}" "" "${VERBNAME}" + WriteRegStr ${REG_CLASSES_HKEY} "Software\Classes\SystemFileAssociations\.$ext\Shell\${VERB}\Command" "" '"$INSTDIR\${APP_EXENAME}" "%1"' + WriteRegStr ${REG_CLASSES_HKEY} "Software\Classes\SystemFileAssociations\.$ext\Shell\${VERB}" "MUIVerb" '@$INSTDIR\${APP_EXENAME},-${MUIVERB_ID}' + ${EndIf} +FunctionEnd + Section "FFDec" SecDummy SetShellVarContext all @@ -443,13 +496,33 @@ Function .onInit SectionSetFlags ${SecDummy} $0 FunctionEnd +Section "$(STRING_ADD_CONTEXT_MENU)" SecContextMenu + SetRegView 64 + Push "swf" + Call AddToExtContextMenu + Push "spl" + Call AddToExtContextMenu + Push "gfx" + Call AddToExtContextMenu + + SetRegView 32 + Push "swf" + Call AddToExtContextMenu + Push "spl" + Call AddToExtContextMenu + Push "gfx" + Call AddToExtContextMenu + + ${NotifyShell_AssocChanged} +SectionEnd + ;-------------------------------- ;Descriptions ;Assign language strings to sections !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SecDummy} "$(STRING_SECTION_APP)" - ; !insertmacro MUI_DESCRIPTION_TEXT ${SecContextMenu} "$(STRING_SECTION_CONTEXT_MENU)" + !insertmacro MUI_DESCRIPTION_TEXT ${SecContextMenu} "$(STRING_SECTION_CONTEXT_MENU)" !insertmacro MUI_DESCRIPTION_TEXT ${SecShortcut} "$(STRING_SECTION_SHORTCUT)" !insertmacro MUI_FUNCTION_DESCRIPTION_END @@ -498,6 +571,23 @@ Section "Uninstall" RmDir /r "$SMPROGRAMS\$SMDir\*.*" RmDir "$SMPROGRAMS\$SMDir" + SetRegView 64 + Push "swf" + Call un.RemoveExtContextMenu + Push "spl" + Call un.RemoveExtContextMenu + Push "gfx" + Call un.RemoveExtContextMenu + + SetRegView 32 + Push "swf" + Call un.RemoveExtContextMenu + Push "spl" + Call un.RemoveExtContextMenu + Push "gfx" + Call un.RemoveExtContextMenu + + ${NotifyShell_AssocChanged} StrCmp $uninstlocal 1 0 +5 SetShellVarContext current diff --git a/openwith.rc b/openwith.rc new file mode 100644 index 000000000..7120783e0 --- /dev/null +++ b/openwith.rc @@ -0,0 +1,125 @@ +// English (en-US) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +STRINGTABLE +BEGIN + 1001 "Open in FFDec" +END + +// Catalan (ca-ES) +LANGUAGE 0x03, 0x01 // LANG_CATALAN +STRINGTABLE +BEGIN + 1001 "Obre amb FFDec" +END + +// Czech (cs-CZ) +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +STRINGTABLE +BEGIN + 1001 "Otevřít v FFDec" +END + +// Chinese (zh-CN) +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED +STRINGTABLE +BEGIN + 1001 "在 FFDec 中打开" +END + +// Dutch (nl-NL) +LANGUAGE LANG_DUTCH, SUBLANG_DUTCH +STRINGTABLE +BEGIN + 1001 "Openen in FFDec" +END + +// French (fr-FR) +LANGUAGE LANG_FRENCH, SUBLANG_FRENCH +STRINGTABLE +BEGIN + 1001 "Ouvrir avec FFDec" +END + +// German (de-DE) +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN +STRINGTABLE +BEGIN + 1001 "In FFDec öffnen" +END + +// Hungarian (hu-HU) +LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT +STRINGTABLE +BEGIN + 1001 "Megnyitás FFDec-kel" +END + +// Italian (it-IT) +LANGUAGE LANG_ITALIAN, SUBLANG_ITALIAN +STRINGTABLE +BEGIN + 1001 "Apri con FFDec" +END + +// Japanese (ja-JP) +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT +STRINGTABLE +BEGIN + 1001 "FFDec で開く" +END + +// Polish (pl-PL) +LANGUAGE LANG_POLISH, SUBLANG_DEFAULT +STRINGTABLE +BEGIN + 1001 "Otwórz w FFDec" +END + +// Portuguese - Portugal (pt-PT) +LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE +STRINGTABLE +BEGIN + 1001 "Abrir com o FFDec" +END + +// Portuguese - Brazil (pt-BR) +LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN +STRINGTABLE +BEGIN + 1001 "Abrir no FFDec" +END + +// Russian (ru-RU) +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +STRINGTABLE +BEGIN + 1001 "Открыть в FFDec" +END + +// Spanish (es-ES) +LANGUAGE LANG_SPANISH, SUBLANG_SPANISH +STRINGTABLE +BEGIN + 1001 "Abrir con FFDec" +END + +// Swedish (sv-SE) +LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT +STRINGTABLE +BEGIN + 1001 "Öppna med FFDec" +END + +// Turkish (tr-TR) +LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT +STRINGTABLE +BEGIN + 1001 "FFDec ile aç" +END + +// Ukrainian (uk-UA) +LANGUAGE 0x22, 0x01 // LANG_UKRAINIAN +STRINGTABLE +BEGIN + 1001 "Відкрити у FFDec" +END \ No newline at end of file diff --git a/resources/ffdec.exe b/resources/ffdec.exe index b7f76d514..8c4030fce 100644 Binary files a/resources/ffdec.exe and b/resources/ffdec.exe differ diff --git a/src/com/jpexs/decompiler/flash/console/ContextMenuTools.java b/src/com/jpexs/decompiler/flash/console/ContextMenuTools.java index 0cf11a954..463030f83 100644 --- a/src/com/jpexs/decompiler/flash/console/ContextMenuTools.java +++ b/src/com/jpexs/decompiler/flash/console/ContextMenuTools.java @@ -88,10 +88,12 @@ public class ContextMenuTools { String appDir = getAppDir(); String verb = "ffdec"; - String verbName = "Open with FFDec"; + String verbName = "Open with FFDec"; //Note: This is later localized by using MUIVerb key to load strings from the EXE + int muiVerbCode = 1001; boolean exists; try { + //0) Add to "Open with" exists = Advapi32Util.registryKeyExists(REG_CLASSES_HKEY, REG_CLASSES_PATH + "Applications\\" + exeName); if ((!exists) && add) { //add Advapi32Util.registryCreateKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + "Applications\\" + exeName); @@ -100,9 +102,14 @@ public class ContextMenuTools { Advapi32Util.registrySetStringValue(REG_CLASSES_HKEY, REG_CLASSES_PATH + "Applications\\" + exeName + "\\shell\\open", "", verbName); Advapi32Util.registryCreateKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + "Applications\\" + exeName + "\\shell\\open\\command"); Advapi32Util.registrySetStringValue(REG_CLASSES_HKEY, REG_CLASSES_PATH + "Applications\\" + exeName + "\\shell\\open\\command", "", "\"" + appDir + exeName + "\" \"%1\""); - } - + if (exists && (!add)) { //remove + registryDeleteKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + "Applications\\" + exeName + "\\shell\\open\\command"); + registryDeleteKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + "Applications\\" + exeName + "\\shell\\open"); + registryDeleteKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + "Applications\\" + exeName + "\\shell"); + registryDeleteKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + "Applications\\" + exeName); + } + for (String ext : extensions) { // 1) Add to context menu of SWF @@ -117,6 +124,20 @@ public class ContextMenuTools { Advapi32Util.registryCreateKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + clsName); Advapi32Util.registrySetStringValue(REG_CLASSES_HKEY, REG_CLASSES_PATH + clsName, "", "Flash Movie"); } + + //Open with per extension + + exists = Advapi32Util.registryKeyExists(REG_CLASSES_HKEY, REG_CLASSES_PATH + "." + ext + "\\OpenWithList\\" + exeName); + if ((!exists) && add) { //add + Advapi32Util.registryCreateKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + "." + ext + "\\OpenWithList\\" + exeName); + } + if (exists && (!add)) { //remove + registryDeleteKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + "." + ext + "\\OpenWithList\\" + exeName); + } + + if (add) { + Advapi32Util.registrySetStringValue(REG_CLASSES_HKEY, clsName, verb); + } if (!Advapi32Util.registryKeyExists(REG_CLASSES_HKEY, REG_CLASSES_PATH + clsName + "\\shell")) { Advapi32Util.registryCreateKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + clsName + "\\shell"); @@ -126,56 +147,19 @@ public class ContextMenuTools { if ((!exists) && add) { //add Advapi32Util.registryCreateKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + clsName + "\\shell\\" + verb); - Advapi32Util.registrySetStringValue(REG_CLASSES_HKEY, REG_CLASSES_PATH + clsName + "\\shell\\" + verb, "", verbName); Advapi32Util.registryCreateKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + clsName + "\\shell\\" + verb + "\\command"); - Advapi32Util.registrySetStringValue(REG_CLASSES_HKEY, REG_CLASSES_PATH + clsName + "\\shell\\" + verb + "\\command", "", "\"" + appDir + exeName + "\" \"%1\""); } - if (exists && (!add)) { //remove + if (add) { + Advapi32Util.registrySetStringValue(REG_CLASSES_HKEY, REG_CLASSES_PATH + clsName + "\\shell\\" + verb, "", verbName); + Advapi32Util.registrySetStringValue(REG_CLASSES_HKEY, REG_CLASSES_PATH + clsName + "\\shell\\" + verb + "\\command", "", "\"" + appDir + exeName + "\" \"%1\""); + Advapi32Util.registrySetStringValue(REG_CLASSES_HKEY, REG_CLASSES_PATH + clsName + "\\shell\\" + verb, "MUIVerb", "@" + appDir + exeName + ",-" + muiVerbCode); + } + if (exists && (!add)) { //remove registryDeleteKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + clsName + "\\shell\\" + verb + "\\command"); registryDeleteKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + clsName + "\\shell\\" + verb); } } - exists = Advapi32Util.registryKeyExists(REG_CLASSES_HKEY, REG_CLASSES_PATH + "Applications\\" + exeName); - - if (exists && (!add)) { //remove - registryDeleteKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + "Applications\\" + exeName + "\\shell\\open\\command"); - registryDeleteKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + "Applications\\" + exeName + "\\shell\\open"); - registryDeleteKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + "Applications\\" + exeName + "\\shell"); - registryDeleteKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + "Applications\\" + exeName); - } - //2) Add to OpenWith list - if (Advapi32Util.registryValueExists(WinReg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\." + ext + "\\OpenWithList", "MRUList")) { - String mruList = Advapi32Util.registryGetStringValue(WinReg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\." + ext + "\\OpenWithList", "MRUList"); - if (mruList != null) { - exists = false; - char appChar = 0; - for (int i = 0; i < mruList.length(); i++) { - String app = Advapi32Util.registryGetStringValue(WinReg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\." + ext + "\\OpenWithList", "" + mruList.charAt(i)); - if (app.equals(exeName)) { - appChar = mruList.charAt(i); - exists = true; - break; - } - } - if ((!exists) && add) { //add - for (int c = 'a'; c <= 'z'; c++) { - if (mruList.indexOf(c) == -1) { - mruList += (char) c; - Advapi32Util.registrySetStringValue(WinReg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\." + ext + "\\OpenWithList", "" + (char) c, exeName); - Advapi32Util.registrySetStringValue(WinReg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\." + ext + "\\OpenWithList", "MRUList", mruList); - break; - } - } - } - if (exists && (!add)) { //remove - mruList = mruList.replace("" + appChar, ""); - Advapi32Util.registrySetStringValue(WinReg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\." + ext + "\\OpenWithList", "MRUList", mruList); - registryDeleteValue(WinReg.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\." + ext + "\\OpenWithList", "" + appChar); - } - } - } - //On some systems, file must be associated in SystemFileAssociations too if (Advapi32Util.registryKeyExists(REG_CLASSES_HKEY, REG_CLASSES_PATH + "SystemFileAssociations")) { exists = Advapi32Util.registryKeyExists(REG_CLASSES_HKEY, REG_CLASSES_PATH + "SystemFileAssociations\\." + ext + "\\Shell\\" + verb); @@ -187,9 +171,12 @@ public class ContextMenuTools { Advapi32Util.registryCreateKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + "SystemFileAssociations\\." + ext + "\\Shell"); } Advapi32Util.registryCreateKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + "SystemFileAssociations\\." + ext + "\\Shell\\" + verb); - Advapi32Util.registrySetStringValue(REG_CLASSES_HKEY, REG_CLASSES_PATH + "SystemFileAssociations\\." + ext + "\\Shell\\" + verb, "", verbName); Advapi32Util.registryCreateKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + "SystemFileAssociations\\." + ext + "\\Shell\\" + verb + "\\Command"); - Advapi32Util.registrySetStringValue(REG_CLASSES_HKEY, REG_CLASSES_PATH + "SystemFileAssociations\\." + ext + "\\Shell\\" + verb + "\\Command", "", "\"" + appDir + exeName + "\" \"%1\""); + } + if (add) { + Advapi32Util.registrySetStringValue(REG_CLASSES_HKEY, REG_CLASSES_PATH + "SystemFileAssociations\\." + ext + "\\Shell\\" + verb, "", verbName); + Advapi32Util.registrySetStringValue(REG_CLASSES_HKEY, REG_CLASSES_PATH + "SystemFileAssociations\\." + ext + "\\Shell\\" + verb + "\\Command", "", "\"" + appDir + exeName + "\" \"%1\""); + Advapi32Util.registrySetStringValue(REG_CLASSES_HKEY, REG_CLASSES_PATH + "SystemFileAssociations\\." + ext + "\\Shell\\" + verb, "MUIVerb", "@" + appDir + exeName + ",-" + muiVerbCode); } if (exists && (!add)) { //remove registryDeleteKey(REG_CLASSES_HKEY, REG_CLASSES_PATH + "SystemFileAssociations\\." + ext + "\\Shell\\" + verb + "\\Command");