├── ApkShellext2 ├── Resources │ ├── Apple.png │ ├── apkm.png │ ├── logo.png │ ├── logo1.png │ ├── play.png │ ├── Amazon.png │ ├── Android.png │ ├── GitHub.png │ ├── QR-Scan.png │ ├── Windows.png │ ├── output.png │ ├── rename.png │ ├── restart.png │ ├── udpate.png │ ├── telegram_s.png │ ├── App-store-icon.png │ ├── msft store icon.png │ ├── net_cloud_drive.png │ ├── Patreon_Mark_Coral.jpg │ ├── Apkshellext_icons │ │ ├── apkshell.psd │ │ ├── apkshell_b.png │ │ ├── apkshell_w.png │ │ ├── apkshell_b32.png │ │ ├── apkshell_b64.png │ │ ├── apkshell_nc.png │ │ ├── apkshell_w32.png │ │ └── apkshell_w64.png │ ├── restart_explorer.bat │ ├── uninstall.bat │ ├── install.bat │ └── debug.bat ├── Properties │ ├── AssemblyInfo.cs │ ├── Settings.cs │ ├── Settings.settings │ ├── Resources.my-MM.resx │ ├── Resources.he-IL.resx │ ├── Resources.el-GR.resx │ ├── Resources.ko-KR.resx │ ├── Resources.ja-JP.resx │ ├── Settings.Designer.cs │ ├── Resources.zh-TW.resx │ └── NonLocalizeResources.resx ├── ApkShellext2.csproj.user ├── ApkInfoTipHandler.cs ├── app.config ├── AppPackageReader.cs ├── AppxbundleReader.cs ├── ApkThumbnailHandler.cs ├── AppxReader.cs ├── Preferences.resx ├── ApkIconHandler.cs └── IpaReader.cs ├── ApkShellextService ├── App.config ├── Properties │ └── AssemblyInfo.cs ├── apkShellextServiceInstaller.cs ├── apkShellextService.csproj └── apkShellextService.cs ├── apkshellextTest ├── App.config ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Program.cs ├── Form1.cs ├── apkshellextTest.csproj ├── Form1.resx └── Form1.Designer.cs ├── .gitattributes ├── .github └── FUNDING.yml ├── .gitmodules ├── LICENSE ├── ApkShellext2.sln ├── README.md └── .gitignore /ApkShellext2/Resources/Apple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/Apple.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/apkm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/apkm.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/logo.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/logo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/logo1.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/play.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/Amazon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/Amazon.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/Android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/Android.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/GitHub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/GitHub.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/QR-Scan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/QR-Scan.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/Windows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/Windows.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/output.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/rename.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/rename.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/restart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/restart.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/udpate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/udpate.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/telegram_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/telegram_s.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/App-store-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/App-store-icon.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/msft store icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/msft store icon.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/net_cloud_drive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/net_cloud_drive.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/Patreon_Mark_Coral.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/Patreon_Mark_Coral.jpg -------------------------------------------------------------------------------- /ApkShellext2/Resources/Apkshellext_icons/apkshell.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/Apkshellext_icons/apkshell.psd -------------------------------------------------------------------------------- /ApkShellext2/Resources/Apkshellext_icons/apkshell_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/Apkshellext_icons/apkshell_b.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/Apkshellext_icons/apkshell_w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/Apkshellext_icons/apkshell_w.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/Apkshellext_icons/apkshell_b32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/Apkshellext_icons/apkshell_b32.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/Apkshellext_icons/apkshell_b64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/Apkshellext_icons/apkshell_b64.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/Apkshellext_icons/apkshell_nc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/Apkshellext_icons/apkshell_nc.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/Apkshellext_icons/apkshell_w32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/Apkshellext_icons/apkshell_w32.png -------------------------------------------------------------------------------- /ApkShellext2/Resources/Apkshellext_icons/apkshell_w64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkguo/apkshellext/HEAD/ApkShellext2/Resources/Apkshellext_icons/apkshell_w64.png -------------------------------------------------------------------------------- /ApkShellextService/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /apkshellextTest/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ApkShellext2/Resources/restart_explorer.bat: -------------------------------------------------------------------------------- 1 | REM CHOICE /M "Restart explorer process?" 2 | REM IF %ERRORLEVEL%==1 ( 3 | TASKKILL /F /IM explorer.exe 4 | TASKKILL /F /IM dllhost.exe 5 | REM pause 6 | START %WINDIR%\explorer.exe 7 | REM ) -------------------------------------------------------------------------------- /apkshellextTest/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /apkshellextTest/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace apkshellextTest 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// The main entry point for the application. 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | Application.EnableVisualStyles(); 18 | Application.SetCompatibleTextRenderingDefault(false); 19 | Application.Run(new Form1()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: kkguo # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ApkShellext2/SharpZipLib"] 2 | path = ApkShellext2/SharpZipLib 3 | url = https://github.com/kkguo/SharpZipLib.git 4 | [submodule "ApkShellext2/SharpShell"] 5 | path = ApkShellext2/SharpShell 6 | url = https://github.com/kkguo/sharpshell.git 7 | [submodule "ApkShellext2/PlistCS"] 8 | path = ApkShellext2/PlistCS 9 | url = https://github.com/kkguo/PlistCS.git 10 | [submodule "ApkShellext2/PNGDecrush"] 11 | path = ApkShellext2/PNGDecrush 12 | url = https://github.com/kkguo/PNGDecrush.git 13 | [submodule "ApkShellext2/Ionic.Zlib"] 14 | path = ApkShellext2/Ionic.Zlib 15 | url = https://github.com/kkguo/Ionic.Zlib.git 16 | [submodule "QRCoder"] 17 | path = QRCoder 18 | url = https://github.com/kkguo/QRCoder.git 19 | [submodule "ApkShellext2/QRCoder"] 20 | path = ApkShellext2/QRCoder 21 | url = https://github.com/codebude/QRCoder.git 22 | [submodule "ApkShellext2/SVG"] 23 | path = ApkShellext2/SVG 24 | url = https://github.com/vvvv/SVG.git 25 | [submodule "ApkShellext2/WebP-wrapper"] 26 | path = ApkShellext2/WebP-wrapper 27 | url = https://github.com/JosePineiro/WebP-wrapper.git 28 | -------------------------------------------------------------------------------- /ApkShellextService/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的常规信息通过以下 6 | // 特性集控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("apkShellextService")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("KK")] 12 | [assembly: AssemblyProduct("apkShellext")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 使此程序集中的类型 18 | // 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | // 则将该类型上的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("caa5fbf9-1ae8-4f71-8a7a-3eeb312c0fc4")] 24 | 25 | // 程序集的版本信息由下面四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Jingang Guo, KK 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /apkshellextTest/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace apkshellextTest.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ApkShellext2/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // 有关程序集的常规信息通过以下 7 | // 特性集控制。更改这些特性值可修改 8 | // 与程序集关联的信息。 9 | [assembly: AssemblyTitle("ApkShellext2")] 10 | [assembly: AssemblyDescription("Windows shell plugin enabling showing app package file icon on windows.")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("KKHOMEBREW")] 13 | [assembly: AssemblyProduct("ApkShellext2")] 14 | [assembly: AssemblyCopyright("Copyright © KK 2019")] 15 | [assembly: AssemblyTrademark("ApkShellExt")] 16 | 17 | // 将 ComVisible 设置为 false 使此程序集中的类型 18 | // 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | // 则将该类型上的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(true)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("1F869CEE-4FDA-35D9-896F-43975A87D1F5")] 24 | 25 | // 程序集的版本信息由下面四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: 34 | [assembly: AssemblyVersion("0.2.0.7")] 35 | [assembly: NeutralResourcesLanguage("en-US")] 36 | //[assembly: AssemblyVersion("0.1.2.*")] 37 | //[assembly: AssemblyFileVersion("0.1.0")] 38 | -------------------------------------------------------------------------------- /ApkShellextService/apkShellextServiceInstaller.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Configuration.Install; 3 | using System.ServiceProcess; 4 | 5 | namespace ApkShellext2 { 6 | [RunInstaller(true)] 7 | public class apkShellextServiceInstaller : Installer { 8 | 9 | public apkShellextServiceInstaller() { 10 | ServiceProcessInstaller serviceProcessInstaller = 11 | new ServiceProcessInstaller(); 12 | ServiceInstaller serviceInstaller = new ServiceInstaller(); 13 | 14 | //# Service Account Information 15 | serviceProcessInstaller.Account = ServiceAccount.LocalSystem; 16 | serviceProcessInstaller.Username = null; 17 | serviceProcessInstaller.Password = null; 18 | 19 | //# Service Information 20 | serviceInstaller.DisplayName = "ApkShellext Service"; 21 | serviceInstaller.StartType = ServiceStartMode.Automatic; 22 | 23 | //# This must be identical to the WindowsService.ServiceBase name 24 | //# set in the constructor of WindowsService.cs 25 | serviceInstaller.ServiceName = "apkShellext Service"; 26 | 27 | this.Installers.Add(serviceProcessInstaller); 28 | this.Installers.Add(serviceInstaller); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ApkShellext2/Properties/Settings.cs: -------------------------------------------------------------------------------- 1 | namespace ApkShellext2.Properties { 2 | 3 | 4 | // This class allows you to handle specific events on the settings class: 5 | // The SettingChanging event is raised before a setting's value is changed. 6 | // The PropertyChanged event is raised after a setting's value is changed. 7 | // The SettingsLoaded event is raised after the setting values are loaded. 8 | // The SettingsSaving event is raised before the setting values are saved. 9 | internal sealed partial class Settings { 10 | 11 | public Settings() { 12 | // // To add event handlers for saving and changing settings, uncomment the lines below: 13 | // 14 | // this.SettingChanging += this.SettingChangingEventHandler; 15 | // 16 | // this.SettingsSaving += this.SettingsSavingEventHandler; 17 | // 18 | } 19 | 20 | private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) { 21 | // Add code to handle the SettingChangingEvent event here. 22 | } 23 | 24 | private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) { 25 | // Add code to handle the SettingsSaving event here. 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /apkshellextTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("apkshellextTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("apkshellextTest")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("6853ddbc-05ea-476a-b1ca-47f6e64ff795")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /ApkShellext2/ApkShellext2.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | false 5 | 6 | Program 7 | C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe 8 | C:\Users\guojin\Documents\Brews\ApkShellext2\ApkShellext2\bin\Debug\ 9 | /codebase apkshellext2.dll 10 | 16 | 17 | 18 | C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe 19 | C:\Users\guojin\Documents\Brews\ApkShellext2\ApkShellext2\bin\Debug\ 20 | /codebase apkshellext2.dll 21 | Program 22 | 23 | -------------------------------------------------------------------------------- /ApkShellext2/Resources/uninstall.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | ECHO ####################################################### 3 | ECHO ## APK Shell Extension 2 ## 4 | ECHO ## ## 5 | ECHO ## http://apkshellext.com s ## 6 | ECHO ####################################################### 7 | 8 | REM === check and get the UAC for administrator privilege === 9 | REM === code from https://sites.google.com/site/eneerge/scripts/batchgotadmin 10 | REM === 11 | :: BatchGotAdmin 12 | :------------------------------------- 13 | REM --> Check for permissions 14 | >nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system" 15 | 16 | REM --> If error flag set, we do not have admin. 17 | if '%errorlevel%' NEQ '0' ( 18 | echo Requesting administrative privileges... 19 | goto UACPrompt 20 | ) else ( goto gotAdmin ) 21 | 22 | :UACPrompt 23 | echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs" 24 | echo UAC.ShellExecute "%~s0", "", "", "runas", 1 >> "%temp%\getadmin.vbs" 25 | 26 | "%temp%\getadmin.vbs" 27 | exit /B 28 | 29 | :gotAdmin 30 | if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" ) 31 | pushd "%CD%" 32 | CD /D "%~dp0" 33 | :-------------------------------------- 34 | 35 | REM SYSTEMINFO | FIND /i "x64-based pc" 36 | echo %PROCESSOR_IDENTIFIER% | FIND /i "x86" 37 | 38 | set FRAMEWORK=%windir%\Microsoft.NET\Framework 39 | set DOTNETVERSION=v4.0.30319 40 | IF %ERRORLEVEL%==1 ( 41 | set FRAMEWORK=%FRAMEWORK%64 42 | ) 43 | set REGASM="%FRAMEWORK%\%DOTNETVERSION%\regasm.exe" 44 | %REGASM% /unregister "%~dp0\apkshellext2.dll" 45 | 46 | ECHO. 47 | REM ECHO The apkshellext.dll may can't be deleted before explorer restart. 48 | 49 | ECHO. 50 | ECHO /-------------------------------------------------------------------\ 51 | ECHO apkshellext is an open-source project, 52 | ECHO Please visit http://apkshellext.com for more information 53 | ECHO \-------------------------------------------------------------------/ 54 | 55 | PAUSE 56 | @ECHO ON 57 | -------------------------------------------------------------------------------- /ApkShellext2/Resources/install.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | ECHO ####################################################### 3 | ECHO ## APK Shell Extension 2 ## 4 | ECHO ## ## 5 | ECHO ## http://www.apkshellext.com ## 6 | ECHO ####################################################### 7 | 8 | REM === check and get the UAC for administrator privilege === 9 | REM === code from https://sites.google.com/site/eneerge/scripts/batchgotadmin 10 | :: BatchGotAdmin 11 | :------------------------------------- 12 | REM --> Check for permissions 13 | >nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system" 14 | 15 | REM --> If error flag set, we do not have admin. 16 | if '%errorlevel%' NEQ '0' ( 17 | if '%1' EQU '1' ( 18 | echo Cannot elevate administrator privilege 19 | echo Please try again with "Run as Administrator" 20 | echo Installation failed. 21 | pause 22 | exit /B 23 | ) else ( 24 | echo Requesting administrative privileges... 25 | goto UACPrompt 26 | ) 27 | ) else ( goto gotAdmin ) 28 | 29 | :UACPrompt 30 | echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs" 31 | echo UAC.ShellExecute "%~s0", "1", "", "runas", 1 >> "%temp%\getadmin.vbs" 32 | 33 | "%temp%\getadmin.vbs" 34 | exit /B 35 | 36 | :gotAdmin 37 | if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" ) 38 | pushd "%CD%" 39 | CD /D "%~dp0" 40 | :-------------------------------------- 41 | 42 | REM SYSTEMINFO | FIND /i "x64-based pc" 43 | echo %PROCESSOR_IDENTIFIER% | FIND /i "x86" 44 | 45 | set FRAMEWORK=%windir%\Microsoft.NET\Framework 46 | set DOTNETVERSION=v4.0.30319 47 | IF %ERRORLEVEL%==1 ( 48 | set FRAMEWORK=%FRAMEWORK%64 49 | ) 50 | set REGASM="%FRAMEWORK%\%DOTNETVERSION%\regasm.exe" 51 | %REGASM% /codebase "%~dp0\apkshellext2.dll" 52 | 53 | ECHO Done! 54 | ECHO. 55 | ECHO /-------------------------------------------------------------------\ 56 | ECHO apkshellext is an open-source project, 57 | ECHO Please visit http://www.apkshellext.com for more information 58 | ECHO \-------------------------------------------------------------------/ 59 | 60 | PAUSE 61 | @ECHO ON 62 | -------------------------------------------------------------------------------- /ApkShellext2/Resources/debug.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | ECHO ####################################################### 3 | ECHO ## APK Shell Extension 2 ## 4 | ECHO ## ## 5 | ECHO ## http://www.apkshellext.com ## 6 | ECHO ####################################################### 7 | 8 | REM === check and get the UAC for administrator privilege === 9 | REM === code from https://sites.google.com/site/eneerge/scripts/batchgotadmin 10 | :: BatchGotAdmin 11 | :------------------------------------- 12 | REM --> Check for permissions 13 | >nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system" 14 | 15 | REM --> If error flag set, we do not have admin. 16 | if '%errorlevel%' NEQ '0' ( 17 | if '%1' EQU '1' ( 18 | echo Cannot elevate administrator privilege 19 | echo Please try again with "Run as Administrator" 20 | echo Installation failed. 21 | pause 22 | exit /B 23 | ) else ( 24 | echo Requesting administrative privileges... 25 | goto UACPrompt 26 | ) 27 | ) else ( goto gotAdmin ) 28 | 29 | :UACPrompt 30 | echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs" 31 | echo UAC.ShellExecute "%~s0", "1", "", "runas", 1 >> "%temp%\getadmin.vbs" 32 | 33 | "%temp%\getadmin.vbs" 34 | exit /B 35 | 36 | :gotAdmin 37 | if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" ) 38 | pushd "%CD%" 39 | CD /D "%~dp0" 40 | :-------------------------------------- 41 | 42 | REM SYSTEMINFO | FIND /i "x64-based pc" 43 | echo %PROCESSOR_IDENTIFIER% | FIND /i "x86" 44 | 45 | set FRAMEWORK=%windir%\Microsoft.NET\Framework 46 | set DOTNETVERSION=v4.0.30319 47 | IF %ERRORLEVEL%==1 ( 48 | set FRAMEWORK=%FRAMEWORK%64 49 | ) 50 | set REGASM="%FRAMEWORK%\%DOTNETVERSION%\regasm.exe" 51 | %REGASM% /codebase "%~dp0\apkshellext2.dll" 52 | 53 | ECHO Done! 54 | ECHO. 55 | ECHO /-------------------------------------------------------------------\ 56 | ECHO apkshellext is an open-source project, 57 | ECHO Please visit http://www.apkshellext.com for more information 58 | ECHO \-------------------------------------------------------------------/ 59 | 60 | TASKKILL /F /IM explorer.exe 61 | TASKKILL /F /IM dllhost.exe 62 | REM pause 63 | START %WINDIR%\explorer.exe 64 | @ECHO ON 65 | 66 | start C:\Users\guojin\Desktop\project\apk 67 | -------------------------------------------------------------------------------- /ApkShellext2.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.28803.352 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApkShellext2", "ApkShellext2\ApkShellext2.csproj", "{091659BA-A36B-45D5-AAF2-3CE764453FF2}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "apkShellextService", "apkShellextService\apkShellextService.csproj", "{3F77E975-68ED-4083-B8F8-56EB56372889}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "apkshellextTest", "apkshellextTest\apkshellextTest.csproj", "{6853DDBC-05EA-476A-B1CA-47F6E64FF795}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Debug2|Any CPU = Debug2|Any CPU 16 | Release|Any CPU = Release|Any CPU 17 | EndGlobalSection 18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 19 | {091659BA-A36B-45D5-AAF2-3CE764453FF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 20 | {091659BA-A36B-45D5-AAF2-3CE764453FF2}.Debug|Any CPU.Build.0 = Debug|Any CPU 21 | {091659BA-A36B-45D5-AAF2-3CE764453FF2}.Debug2|Any CPU.ActiveCfg = Debug2|Any CPU 22 | {091659BA-A36B-45D5-AAF2-3CE764453FF2}.Debug2|Any CPU.Build.0 = Debug2|Any CPU 23 | {091659BA-A36B-45D5-AAF2-3CE764453FF2}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {091659BA-A36B-45D5-AAF2-3CE764453FF2}.Release|Any CPU.Build.0 = Release|Any CPU 25 | {3F77E975-68ED-4083-B8F8-56EB56372889}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 26 | {3F77E975-68ED-4083-B8F8-56EB56372889}.Debug2|Any CPU.ActiveCfg = Debug2|Any CPU 27 | {3F77E975-68ED-4083-B8F8-56EB56372889}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {6853DDBC-05EA-476A-B1CA-47F6E64FF795}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {6853DDBC-05EA-476A-B1CA-47F6E64FF795}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {6853DDBC-05EA-476A-B1CA-47F6E64FF795}.Debug2|Any CPU.ActiveCfg = Debug2|Any CPU 31 | {6853DDBC-05EA-476A-B1CA-47F6E64FF795}.Debug2|Any CPU.Build.0 = Debug2|Any CPU 32 | {6853DDBC-05EA-476A-B1CA-47F6E64FF795}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {6853DDBC-05EA-476A-B1CA-47F6E64FF795}.Release|Any CPU.Build.0 = Release|Any CPU 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | GlobalSection(ExtensibilityGlobals) = postSolution 39 | SolutionGuid = {0A438C55-B459-43B6-999D-11D7A8991B0F} 40 | EndGlobalSection 41 | EndGlobal 42 | -------------------------------------------------------------------------------- /apkshellextTest/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace apkshellextTest.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("apkshellextTest.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /ApkShellext2/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | False 7 | 8 | 9 | True 10 | 11 | 12 | True 13 | 14 | 15 | False 16 | 17 | 18 | True 19 | 20 | 21 | True 22 | 23 | 24 | True 25 | 26 | 27 | True 28 | 29 | 30 | True 31 | 32 | 33 | True 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -1 43 | 44 | 45 | True 46 | 47 | 48 | 0 49 | 50 | 51 | 2014-12-31 52 | 53 | 54 | False 55 | 56 | 57 | 58 | 59 | 60 | True 61 | 62 | 63 | True 64 | 65 | 66 | True 67 | 68 | 69 | False 70 | 71 | 72 | -------------------------------------------------------------------------------- /ApkShellext2/ApkInfoTipHandler.cs: -------------------------------------------------------------------------------- 1 | using ApkQuickReader; 2 | using Microsoft.Win32; 3 | using SharpShell.Attributes; 4 | using SharpShell.Diagnostics; 5 | using SharpShell.Extensions; 6 | using SharpShell.ServerRegistration; 7 | using SharpShell.SharpInfoTipHandler; 8 | using System; 9 | using System.IO; 10 | using System.Linq; 11 | using System.Runtime.InteropServices; 12 | using ApkShellext2.Properties; 13 | 14 | namespace ApkShellext2 { 15 | 16 | [Guid("946435a5-fe96-416d-99db-e94ee9fb46c8")] 17 | [ComVisible(true)] 18 | [ClassInterface(ClassInterfaceType.None)] 19 | [COMServerAssociation(AssociationType.ClassOfExtension, ".apk")] 20 | [COMServerAssociation(AssociationType.ClassOfExtension, ".ipa")] 21 | [COMServerAssociation(AssociationType.ClassOfExtension, ".appxbundle")] 22 | [COMServerAssociation(AssociationType.ClassOfExtension, ".appx")] 23 | public class ApkInfoTipHandler : SharpInfoTipHandler { 24 | /// 25 | /// Gets info for the selected item (SelectedItemPath). 26 | /// 27 | /// Type of info to return. 28 | /// if set to true, put the info in a single line. 29 | /// 30 | /// Specified info for the selected file. 31 | /// 32 | protected override string GetInfo(RequestedInfoType infoType, bool singleLine) { 33 | try { 34 | Utility.Localize(); 35 | string TipPattern = Utility.GetSetting("ToolTipPattern", NonLocalizeResources.strInfoTipDefault); 36 | bool isapk = SelectedItemPath.EndsWith(".apk"); 37 | bool isipa = SelectedItemPath.EndsWith(".ipa"); 38 | 39 | using (AppPackageReader reader = AppPackageReader.Read(SelectedItemPath)) { 40 | return ApkContextMenu.ReplaceVariables(TipPattern, reader); 41 | } 42 | } catch (Exception ex) { 43 | Log("Error happend during GetInfo : " + ex.Message); 44 | return Properties.Resources.strReadFileFailed; 45 | } 46 | } 47 | 48 | [CustomRegisterFunction] 49 | public static void postDoRegister(Type type, RegistrationType registrationType) { 50 | Console.WriteLine("Registering " + type.FullName); 51 | 52 | #region Clean up older versions registry 53 | try { 54 | using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(@"\CLSID\" + 55 | type.GUID.ToRegistryString() + @"\InprocServer32")) { 56 | if (key != null && key.GetSubKeyNames().Count() != 0) { 57 | Console.WriteLine("Found old version in registry, cleaning up ..."); 58 | foreach (var k in key.GetSubKeyNames()) { 59 | if (k != type.Assembly.GetName().Version.ToString()) { 60 | Registry.ClassesRoot.DeleteSubKeyTree(@"\CLSID\" + 61 | type.GUID.ToRegistryString() + @"\InprocServer32\" + k); 62 | } 63 | } 64 | } 65 | } 66 | } catch (Exception e) { 67 | Logging.Error("Cleaning up older version but see exception. " 68 | + e.Message); 69 | } 70 | #endregion 71 | } 72 | 73 | protected override void Log(string message){ 74 | Utility.Log(this, Path.GetFileName(SelectedItemPath), message); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /ApkShellext2/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | False 12 | 13 | 14 | True 15 | 16 | 17 | True 18 | 19 | 20 | False 21 | 22 | 23 | True 24 | 25 | 26 | True 27 | 28 | 29 | True 30 | 31 | 32 | True 33 | 34 | 35 | True 36 | 37 | 38 | True 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -1 48 | 49 | 50 | True 51 | 52 | 53 | 0 54 | 55 | 56 | 2014-12-31 57 | 58 | 59 | False 60 | 61 | 62 | 63 | 64 | 65 | True 66 | 67 | 68 | True 69 | 70 | 71 | True 72 | 73 | 74 | False 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ApkShellext2![logo](https://github.com/kkguo/apkshellext/blob/ApkShellext2/ApkShellext2/Resources/Apkshellext_icons/apkshell_b64.png?raw=true) 2 | [![Crowdin](https://d322cqt584bo4o.cloudfront.net/apkshellext/localized.svg)](http://translate.apkshellext.com/) 3 | 4 | A Windows shell extension supporting icon for files of 5 | * .apk (android package) 6 | * .ipa (iOS app package) 7 | * .appx .appxbundle (Windows phone 8.1/10 app package, .xap is not supported) 8 | 9 | This is the code repository, please visit the project page http://apkshellext.com or go to [release](https://github.com/kkguo/apkshellext/releases) for download. 10 | 11 | #### Help this project 12 | * Become a Sponsor, I will be more glad to update your request. 13 | * Translators please read this first : [Translate Wiki page](https://github.com/kkguo/apkshellext/wiki/Translation-and-Multi-language-support#1-translate) 14 | * Project pages needs web people to maintain. 15 | * Become a beta testers, join [![telegram](https://github.com/kkguo/apkshellext/blob/ApkShellext2/ApkShellext2/Resources/telegram_s.png)Telegram group](https://t.me/ApkShellExt2) 16 | * Pull request is always welcome. 17 | 18 | #### Have issue? 19 | * Check the [Known issue list](https://github.com/kkguo/apkshellext/wiki/Known-issues-and-solution) first. 20 | * Look for help on [![telegram](https://github.com/kkguo/apkshellext/blob/ApkShellext2/ApkShellext2/Resources/telegram_s.png)Telegram group](https://t.me/ApkShellExt2) (Preferred) 21 | * Go raise [Issues](https://github.com/kkguo/apkshellext/issues) (Preferred) 22 | * Send to :email: issue@apkshellext.com 23 | 24 | #### [Features] 25 | - [x] Display app icon in Windows File Explorer with best resolution. __DOES NOT work with other file manager due to .NET restriction__ 26 | - [x] Customize-able Info-Tip for showing package information. 27 | - [x] Context menu for batch renaming, use customize-able patterns. 28 | - [x] Go to app store from context menu. 29 | - [x] Auto-check new version. 30 | - [x] Show overlay icon for different type of apps. 31 | - [x] Support multiple languages: Thanks to contributors on https://crowdin.com/project/apkshellext 32 | 33 | #### [Todo] 34 | - [X] Adaptive-icon support (Beta) 35 | - [ ] protobuf support 36 | - [ ] support .NET 4.0?? 37 | - [ ] QR code to download to phone 38 | - [ ] Hook up adb function with namespace extension. 39 | - [ ] drag-drop to install / uninstall to phone 40 | 41 | #### Check [Wiki](https://github.com/kkguo/apkshellext/wiki) for how to build from source code 42 | 43 | #### Credit : 44 | ||| 45 | | --- | --- | 46 | | [SharpShell](https://github.com/dwmkerr/sharpshell) | Shell extension library | 47 | | [SharpZip](https://github.com/icsharpcode/SharpZipLib) | Zip function implementation in C# | 48 | | [Iteedee.ApkReader](https://github.com/hylander0/Iteedee.ApkReader) | the original APK reader, not in use currently | 49 | | [PlistCS](https://github.com/animetrics/PlistCS) | iOS plist file reader | 50 | | [PNGDecrush](https://github.com/MikeWeller/PNGDecrush) | PNG decrush lib | 51 | | [Ionic.Zlib](https://github.com/jstedfast/Ionic.Zlib) | Another Zip implementation, used by PNGDecrush | 52 | | [QRCoder](https://github.com/codebude/QRCoder) | QR code generator | 53 | | [Ultimate Social](https://www.iconfinder.com/iconsets/ultimate-social) | A free icon set for social medias | 54 | | [SVG](https://github.com/vvvv/SVG) | SVG format renderer | 55 | | [WebP-Wrapper](https://github.com/JosePineiro/WebP-wrapper) | WebP format renderer 56 | | [Thanasis Georgiou](https://github.com/sakisds) | Project web page | 57 | -------------- 58 | Originally this project hosted on [GoogleCode](code.google.com/p/apkshellext), now moved to [:octocat:Github](https://github.com/kkguo/apkshellext) and fully re-writen with a native apk reader. The active developing code is on [ApkShellext2 branch](https://github.com/kkguo/apkshellext/tree/ApkShellext2). The obsolete code is on [master branch](https://github.com/kkguo/apkshellext/tree/master) 59 | -------------------------------------------------------------------------------- /apkshellextTest/Form1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.IO; 9 | using System.Threading.Tasks; 10 | using System.Windows.Forms; 11 | using ApkShellext2; 12 | using ApkQuickReader; 13 | using ICSharpCode.SharpZipLib.Zip; 14 | using ApkShellext2.ApkChunk; 15 | using System.Drawing.Drawing2D; 16 | using System.Text.RegularExpressions; 17 | 18 | namespace apkshellextTest 19 | { 20 | public partial class Form1 : Form 21 | { 22 | public Form1() 23 | { 24 | InitializeComponent(); 25 | } 26 | 27 | private void Button1_Click(object sender, EventArgs e) 28 | { 29 | OpenFileDialog dialog = new OpenFileDialog(); 30 | dialog.Filter = "apkfile|*.apk"; 31 | dialog.ShowDialog(); 32 | textBox1.Text = dialog.FileName; 33 | //parseapk(); 34 | } 35 | 36 | private void Button2_Click(object sender, EventArgs e) { 37 | 38 | //string TipPattern = @"Magisk Manager\r\ncom.topjohnwu.magisk\r\nVersion: 7.2.0 213\r\n%Attr(manifest/uses-sdk,minSdkVersion)%";// @"%Attr(mainifest/application,icon)%"; 39 | //textBox1.Text = TipPattern; 40 | string TipPattern = textBox1.Text; 41 | Regex rx = new Regex(textBox3.Text); 42 | Match m = rx.Match(TipPattern); 43 | textBox4.Text = m.Success.ToString(); 44 | if (m.Success) { 45 | foreach (Group c in m.Groups) { 46 | textBox4.Text = textBox4.Text + "||" + c.Value; 47 | } 48 | } 49 | 50 | //textBox4.Text = ApkContextMenu.ReplaceVariables(TipPattern, reader); 51 | 52 | return; 53 | AppPackageReader reader = AppPackageReader.Read(textBox1.Text); 54 | reader.setFlag("ImageSize", 48); 55 | pictureBox2.Image = reader.Icon; 56 | 57 | //parseapk(); 58 | 59 | Bitmap b = new Bitmap(1000, 1000); 60 | using (Graphics g = Graphics.FromImage(b)) { 61 | //g.DrawPath(new Pen(Color.Black,1), VectorDrawableRender.Convert2Path("M 100 100 L 300 100 L 200 300 z")); 62 | g.FillPath(new SolidBrush(Color.Brown), VectorDrawableRender.Convert2Path("M0,0h108v108h-108z")); 63 | //g.FillPath(new SolidBrush(Color.Green), VectorDrawableRender.Convert2Path("M100,200 C100,100 250,100 250,200S400,300 400,200")); 64 | //g.FillPath(new SolidBrush(Color.Red), VectorDrawableRender.Convert2Path("M200,300 Q400,50 600,300 T1000,300")); 65 | //g.DrawPath(new Pen(Color.Purple, 2), VectorDrawableRender.Convert2Path("M15.67,4H14V2h-4v2H8.33C7.6,4 7,4.6 7,5.33V9h4.93L13,7v2h4V5.33C17,4.6 16.4,4 15.67,4z")); 66 | //g.DrawPath(new Pen(Color.Purple, 2), VectorDrawableRender.Convert2Path("M600,350 l 50,-25 a25, 25 -30 0, 1 50, -25 l 50, -25 a25, 50 -30 0, 1 50, -25 l 50, -25 a25, 75 -30 0, 1 50, -25 l 50, -25 a25, 100 -30 0, 1 50, -25 l 50, -25")); 67 | if (textBox1.Text != "") { 68 | g.DrawPath(new Pen(Color.Brown, 2), 69 | VectorDrawableRender.Convert2Path(textBox1.Text)); 70 | } 71 | 72 | } 73 | pictureBox1.Size = b.Size; 74 | pictureBox1.Image = b; 75 | pictureBox1.Size = new Size(100, 100); 76 | } 77 | 78 | private void parseapk() { 79 | if (File.Exists(textBox1.Text.Trim())) { 80 | ZipFile zip = new ZipFile(textBox1.Text); 81 | ZipEntry en = zip.GetEntry("androidmanifest.xml"); 82 | BinaryReader s = new BinaryReader(zip.GetInputStream(en)); 83 | byte[] bytes = s.ReadBytes((int)en.Size); 84 | ApkXMLChunk ck = new ApkXMLChunk(bytes); 85 | textBox2.Text = ck.OutputXML(); 86 | 87 | //AppPackageReader reader = AppPackageReader.Read(textBox1.Text); 88 | s.Close(); 89 | zip.Close(); 90 | } 91 | } 92 | 93 | private void Form1_Load(object sender, EventArgs e) { 94 | 95 | } 96 | 97 | 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | #*.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # Build results 11 | [Dd]ebug/ 12 | [Dd]ebugPublic/ 13 | [Rr]elease/ 14 | [Rr]eleases/ 15 | x64/ 16 | x86/ 17 | build/ 18 | bld/ 19 | [Bb]in/ 20 | [Oo]bj/ 21 | 22 | # Roslyn cache directories 23 | *.ide/ 24 | 25 | # MSTest test Results 26 | [Tt]est[Rr]esult*/ 27 | [Bb]uild[Ll]og.* 28 | 29 | #NUNIT 30 | *.VisualState.xml 31 | TestResult.xml 32 | 33 | # Build Results of an ATL Project 34 | [Dd]ebugPS/ 35 | [Rr]eleasePS/ 36 | dlldata.c 37 | 38 | *_i.c 39 | *_p.c 40 | *_i.h 41 | *.ilk 42 | *.meta 43 | *.obj 44 | *.pch 45 | *.pdb 46 | *.pgc 47 | *.pgd 48 | *.rsp 49 | *.sbr 50 | *.tlb 51 | *.tli 52 | *.tlh 53 | *.tmp 54 | *.tmp_proj 55 | *.log 56 | *.vspscc 57 | *.vssscc 58 | .builds 59 | *.pidb 60 | *.svclog 61 | *.scc 62 | 63 | # Chutzpah Test files 64 | _Chutzpah* 65 | 66 | # Visual C++ cache files 67 | ipch/ 68 | *.aps 69 | *.ncb 70 | *.opensdf 71 | *.sdf 72 | *.cachefile 73 | 74 | # Visual Studio profiler 75 | *.psess 76 | *.vsp 77 | *.vspx 78 | 79 | # TFS 2012 Local Workspace 80 | $tf/ 81 | 82 | # Guidance Automation Toolkit 83 | *.gpState 84 | 85 | # ReSharper is a .NET coding add-in 86 | _ReSharper*/ 87 | *.[Rr]e[Ss]harper 88 | *.DotSettings.user 89 | 90 | # JustCode is a .NET coding addin-in 91 | .JustCode 92 | 93 | # TeamCity is a build add-in 94 | _TeamCity* 95 | 96 | # DotCover is a Code Coverage Tool 97 | *.dotCover 98 | 99 | # NCrunch 100 | _NCrunch_* 101 | .*crunch*.local.xml 102 | 103 | # MightyMoose 104 | *.mm.* 105 | AutoTest.Net/ 106 | 107 | # Web workbench (sass) 108 | .sass-cache/ 109 | 110 | # Installshield output folder 111 | [Ee]xpress/ 112 | 113 | # DocProject is a documentation generator add-in 114 | DocProject/buildhelp/ 115 | DocProject/Help/*.HxT 116 | DocProject/Help/*.HxC 117 | DocProject/Help/*.hhc 118 | DocProject/Help/*.hhk 119 | DocProject/Help/*.hhp 120 | DocProject/Help/Html2 121 | DocProject/Help/html 122 | 123 | # Click-Once directory 124 | publish/ 125 | 126 | # Publish Web Output 127 | *.[Pp]ublish.xml 128 | *.azurePubxml 129 | # TODO: Comment the next line if you want to checkin your web deploy settings 130 | # but database connection strings (with potential passwords) will be unencrypted 131 | *.pubxml 132 | *.publishproj 133 | 134 | # NuGet Packages 135 | *.nupkg 136 | # The packages folder can be ignored because of Package Restore 137 | **/packages/* 138 | # except build/, which is used as an MSBuild target. 139 | !**/packages/build/ 140 | # If using the old MSBuild-Integrated Package Restore, uncomment this: 141 | #!**/packages/repositories.config 142 | 143 | # Windows Azure Build Output 144 | csx/ 145 | *.build.csdef 146 | 147 | # Windows Store app package directory 148 | AppPackages/ 149 | 150 | # Others 151 | sql/ 152 | *.Cache 153 | ClientBin/ 154 | [Ss]tyle[Cc]op.* 155 | ~$* 156 | *~ 157 | *.dbmdl 158 | *.dbproj.schemaview 159 | *.pfx 160 | *.publishsettings 161 | node_modules/ 162 | 163 | # RIA/Silverlight projects 164 | Generated_Code/ 165 | 166 | # Backup & report files from converting an old project file 167 | # to a newer Visual Studio version. Backup files are not needed, 168 | # because we have git ;-) 169 | _UpgradeReport_Files/ 170 | Backup*/ 171 | UpgradeLog*.XML 172 | UpgradeLog*.htm 173 | 174 | # SQL Server files 175 | *.mdf 176 | *.ldf 177 | 178 | # Business Intelligence projects 179 | *.rdl.data 180 | *.bim.layout 181 | *.bim_*.settings 182 | 183 | # Microsoft Fakes 184 | FakesAssemblies/ 185 | 186 | # ========================= 187 | # Operating System Files 188 | # ========================= 189 | 190 | # OSX 191 | # ========================= 192 | 193 | .DS_Store 194 | .AppleDouble 195 | .LSOverride 196 | 197 | # Thumbnails 198 | ._* 199 | 200 | # Files that might appear on external disk 201 | .Spotlight-V100 202 | .Trashes 203 | 204 | # Directories potentially created on remote AFP share 205 | .AppleDB 206 | .AppleDesktop 207 | Network Trash Folder 208 | Temporary Items 209 | .apdisk 210 | 211 | # Windows 212 | # ========================= 213 | 214 | # Windows image file caches 215 | Thumbs.db 216 | ehthumbs.db 217 | 218 | # Folder config file 219 | Desktop.ini 220 | 221 | # Recycle Bin used on file shares 222 | $RECYCLE.BIN/ 223 | 224 | # Windows Installer files 225 | *.cab 226 | *.msi 227 | *.msm 228 | *.msp 229 | 230 | # Windows shortcuts 231 | *.lnk 232 | /.vs 233 | /ApkShellext2/Properties/apkshellext/mv.bat 234 | /ApkShellext2/Properties/apkshellext 235 | -------------------------------------------------------------------------------- /ApkShellext2/AppPackageReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Drawing; 7 | using System.Globalization; 8 | using ApkQuickReader; 9 | using System.IO; 10 | 11 | namespace ApkShellext2 { 12 | /// 13 | /// This is the base class for package reader 14 | /// defines common method a package reader should have 15 | /// for reusing and simplify in the code 16 | /// 17 | public class AppPackageReader : IDisposable{ 18 | public const string extAPK = ".apk"; 19 | public const string extIPA = ".ipa"; 20 | public const string extAPPX = ".appx"; 21 | public const string extAPPXBUNDLE = ".appxbundle"; 22 | 23 | public enum AppType { 24 | AndroidApp, 25 | iOSApp, 26 | WindowsPhoneAppBundle, 27 | WindowsPhoneApp 28 | } 29 | private Dictionary Flags; 30 | 31 | public virtual string FileName { get; protected set; } 32 | // App name 33 | public virtual string AppName { get { return ""; } } 34 | // Package Name 35 | public virtual string PackageName { get { return ""; } } 36 | 37 | // App version 38 | public virtual string Version { get { return ""; } } 39 | // Sub version 40 | public virtual string Revision { get { return ""; } } 41 | 42 | public virtual CultureInfo Culture { get; set; } 43 | 44 | // Publisher 45 | public virtual string Publisher { get { return ""; } } 46 | 47 | public virtual Bitmap Icon { get { return null; } } 48 | 49 | public virtual string AppID { get { return ""; } } 50 | 51 | public virtual AppType Type { get { return AppType.AndroidApp; } } 52 | 53 | // use for other information, or file type specific info 54 | public virtual void setFlag(string flag, object value) { 55 | if (Flags == null) 56 | Flags = new Dictionary(); 57 | Flags[flag] = value; 58 | } 59 | 60 | public virtual object getFlag(string flag) { 61 | if (Flags != null && Flags.ContainsKey(flag)) 62 | return Flags[flag]; 63 | else 64 | return null; 65 | } 66 | 67 | public virtual Bitmap getIcon(Size size) { 68 | return Utility.ResizeBitmap(Icon, size); 69 | } 70 | 71 | // Public implementation of Dispose pattern callable by consumers. 72 | public void Dispose() { 73 | Dispose(true); 74 | GC.SuppressFinalize(this); 75 | } 76 | 77 | bool disposed; 78 | // Protected implementation of Dispose pattern. 79 | protected virtual void Dispose(bool disposing) { 80 | if (disposed) 81 | return; 82 | if (Flags != null) 83 | Flags.Clear(); 84 | Flags = null; 85 | disposed = true; 86 | } 87 | 88 | public static AppType getAppType(string path) { 89 | string suffix = Path.GetExtension(path); 90 | if (suffix == extAPK) { 91 | return AppType.AndroidApp; 92 | } else if (suffix == extIPA) { 93 | return AppType.iOSApp; 94 | } else if (suffix == extAPPXBUNDLE) { 95 | return AppType.WindowsPhoneAppBundle; 96 | } else if (suffix == extAPPX) { 97 | return AppType.WindowsPhoneApp; 98 | } else { 99 | throw new NotSupportedException(suffix + " type is not supported."); 100 | } 101 | } 102 | 103 | public static AppPackageReader Read(string path) { 104 | switch (getAppType(path)) { 105 | case AppType.AndroidApp: 106 | return new ApkReader(path); 107 | case AppType.iOSApp: 108 | return new IpaReader(path); 109 | case AppType.WindowsPhoneAppBundle: 110 | return new AppxBundleReader(path); 111 | case AppType.WindowsPhoneApp: 112 | return new AppxReader(path); 113 | default : 114 | throw new NotSupportedException("File type is not supported."); 115 | } 116 | } 117 | 118 | protected void Log(string message) { 119 | Utility.Log(this, Path.GetFileName(FileName), message); 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ApkShellext2/AppxbundleReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using ICSharpCode.SharpZipLib.Zip; 7 | using System.Xml; 8 | using System.IO; 9 | using System.Drawing; 10 | 11 | namespace ApkShellext2 { 12 | /// 13 | /// Read AppxBundle 14 | /// 15 | public class AppxBundleReader :AppPackageReader { 16 | private ZipFile zip; 17 | private AppxReader appxReader= null; 18 | 19 | private const string AppxBundleManifestXml = @"AppxMetadata/AppxBundleManifest.xml"; 20 | private const string ElemIdentity = @"Identity"; 21 | //private const string ElemProperties = @"Properties"; 22 | //private const string ElemDisplayName = @"DisplayName"; 23 | private const string ElemPackage = @"Package"; 24 | //private const string AttrVersion = @"Version"; 25 | private const string AttrName = @"Name"; 26 | //private const string AttrPublisher = @"Publisher"; 27 | private const string AttrType = @"Type"; 28 | private const string ValApplication = @"application"; 29 | private const string AttrFileName = @"FileName"; 30 | 31 | public AppxBundleReader(Stream stream) { 32 | FileName = ""; 33 | openFile(stream); 34 | } 35 | 36 | public AppxBundleReader(string path) { 37 | FileName = path; 38 | openFile(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)); 39 | } 40 | 41 | private void openFile(Stream stream) { 42 | string appxFileName = ""; 43 | zip = new ZipFile(stream); 44 | ZipEntry en = zip.GetEntry(AppxBundleManifestXml); 45 | if (en == null) 46 | throw new EntryPointNotFoundException("cannot find " + AppxBundleManifestXml); 47 | 48 | using (XmlReader reader = XmlReader.Create(zip.GetInputStream(en))) { 49 | reader.ReadToFollowing(ElemIdentity); 50 | reader.MoveToAttribute(AttrName); 51 | 52 | do { 53 | reader.ReadToFollowing(ElemPackage); 54 | reader.MoveToAttribute(AttrType); 55 | } while (reader.Value != ValApplication || reader.EOF); 56 | 57 | if (reader.EOF) 58 | throw new Exception("Cannot find application in " + AppxBundleManifestXml); 59 | 60 | reader.MoveToAttribute(AttrFileName); 61 | appxFileName = reader.Value; 62 | } 63 | 64 | en = zip.GetEntry(appxFileName); 65 | if (en == null) 66 | throw new EntryPointNotFoundException("cannot find appx " + appxFileName); 67 | 68 | appxReader = new AppxReader(zip.GetInputStream(en)); 69 | } 70 | 71 | public override AppPackageReader.AppType Type { 72 | get { 73 | return AppType.WindowsPhoneAppBundle; 74 | } 75 | } 76 | 77 | public override Bitmap Icon { 78 | get { 79 | return appxReader.Icon; 80 | } 81 | } 82 | 83 | public override string AppName { 84 | get { 85 | return appxReader.AppName; 86 | } 87 | } 88 | 89 | public override string PackageName { 90 | get { 91 | return appxReader.PackageName; 92 | } 93 | } 94 | 95 | public override string Version { 96 | get { 97 | return appxReader.Version; 98 | } 99 | } 100 | 101 | public override string Publisher { 102 | get { 103 | return appxReader.Publisher; 104 | } 105 | } 106 | 107 | public override string AppID { 108 | get { 109 | return appxReader.AppID; 110 | } 111 | } 112 | private bool disposed = false; 113 | protected override void Dispose(bool disposing) { 114 | if (disposed) return; 115 | if (disposing) { 116 | if (appxReader != null) { 117 | appxReader.Close(); 118 | } 119 | if (zip != null) 120 | zip.Close(); 121 | } 122 | disposed = true; 123 | base.Dispose(disposing); 124 | } 125 | 126 | public void Close() { 127 | Dispose(true); 128 | } 129 | 130 | ~AppxBundleReader() { 131 | Dispose(true); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /ApkShellextService/apkShellextService.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3F77E975-68ED-4083-B8F8-56EB56372889} 8 | Exe 9 | Properties 10 | ApkShellext2 11 | apkShellextService 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | true 38 | bin\Debug2\ 39 | DEBUG;TRACE 40 | full 41 | AnyCPU 42 | prompt 43 | MinimumRecommendedRules.ruleset 44 | true 45 | 46 | 47 | 48 | ..\packages\Google.Protobuf.3.8.0\lib\net45\Google.Protobuf.dll 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | Component 65 | 66 | 67 | Component 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | net stop "apkshellext service" 77 | 78 | 79 | 80 | 81 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 82 | 83 | 84 | 85 | 92 | -------------------------------------------------------------------------------- /ApkShellext2/ApkThumbnailHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using SharpShell.Attributes; 3 | using SharpShell.Diagnostics; 4 | using SharpShell.SharpThumbnailHandler; 5 | using System; 6 | using System.Drawing; 7 | using System.Linq; 8 | using System.Runtime.InteropServices; 9 | using SharpShell.Extensions; 10 | using SharpShell.ServerRegistration; 11 | using System.IO; 12 | using ApkShellext2.Properties; 13 | using ApkQuickReader; 14 | using System.Configuration; 15 | 16 | namespace ApkShellext2 { 17 | [Guid("d747c5a7-2f66-4b7d-8301-8531838e4ed3")] 18 | [ComVisible(true)] 19 | [ClassInterface(ClassInterfaceType.None)] 20 | [COMServerAssociation(AssociationType.ClassOfExtension, ".apk")] 21 | public class ApkThumbnailHandler : SharpThumbnailHandler { 22 | protected override Bitmap GetThumbnailImage(uint width) { 23 | Bitmap m_icon = null; 24 | 25 | //Log("Thumbnail is using setting file from: " + ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath); 26 | 27 | //if (!Settings.Default.EnableThumbnail) { 28 | // return null; 29 | //} 30 | if (Utility.GetSetting("EnableThumbnail") != "True") { 31 | return null; 32 | } 33 | 34 | try { 35 | int outputSize = (int) width; 36 | using (AppPackageReader reader = new ApkReader(SelectedItemStream)) { 37 | Log("Reading stream from " + reader.AppName); 38 | m_icon = reader.Icon; 39 | } 40 | 41 | if (m_icon == null) 42 | throw new Exception("Cannot find Icon from Stream, draw default"); 43 | if (m_icon.Height < outputSize && 44 | //!Settings.Default.StretchThumbnail) 45 | (Utility.GetSetting("StretchThumbnail","True")!="True")) 46 | outputSize = m_icon.Height; 47 | 48 | Log("Got icon, resizing..."); 49 | //if (Settings.Default.ShowOverLayIcon) { 50 | if (Utility.GetSetting("ShowOverlayIcon")=="True") { 51 | Log("Draw overlay"); 52 | m_icon = Utility.CombineBitmap(m_icon, 53 | Utility.AppTypeIcon(AppPackageReader.AppType.AndroidApp), 54 | new Rectangle(0, 0, outputSize , outputSize), 55 | new Rectangle(0, (int)outputSize / 2, (int)outputSize / 2, (int)outputSize / 2), 56 | new Size(outputSize, outputSize)); 57 | } else { 58 | m_icon = Utility.ResizeBitmap(m_icon, outputSize); 59 | } 60 | #if DEBUG 61 | string p = Path.GetTempFileName(); 62 | m_icon.Save(p); 63 | Log("Save m_icon to " + p); 64 | #endif 65 | return m_icon; 66 | } catch (Exception ex){ 67 | Log("Error in reading icon from stream, draw default"); 68 | Log(ex.Message); 69 | // read error, draw the default icon 70 | //m_icon = Utility.AppTypeIcon(AppPackageReader.AppType.AndroidApp); 71 | return null; 72 | } 73 | } 74 | 75 | [CustomRegisterFunction] 76 | public static void postDoRegister(Type type, RegistrationType registrationType) { 77 | Console.WriteLine("Registering " + type.FullName ); 78 | 79 | using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(@"\CLSID\.apk")) { 80 | if (key != null) { 81 | // disable the shadow under thumbnail, make it more looks like an icon 82 | key.SetValue("Treatment", 0); 83 | } 84 | } 85 | 86 | #region Clean up older versions registry 87 | try { 88 | using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(@"\CLSID\" + 89 | type.GUID.ToRegistryString() + @"\InprocServer32")) { 90 | if (key != null && key.GetSubKeyNames().Count() != 0) { 91 | Console.WriteLine("Found old version in registry, cleaning up ..."); 92 | foreach (var k in key.GetSubKeyNames()) { 93 | if (k != type.Assembly.GetName().Version.ToString()) { 94 | Registry.ClassesRoot.DeleteSubKeyTree(@"\CLSID\" + 95 | type.GUID.ToRegistryString() + @"\InprocServer32\" + k); 96 | } 97 | } 98 | } 99 | } 100 | } catch (Exception e) { 101 | Logging.Error("Cleaning up older version but see exception. " 102 | + e.Message); 103 | } 104 | #endregion 105 | } 106 | 107 | protected override void Log(string message) { 108 | Utility.Log(this, "", message); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /apkshellextTest/apkshellextTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {6853DDBC-05EA-476A-B1CA-47F6E64FF795} 8 | WinExe 9 | apkshellextTest 10 | apkshellextTest 11 | v4.7.2 12 | 512 13 | true 14 | true 15 | 16 | 17 | 18 | 19 | AnyCPU 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | true 39 | bin\Debug2\ 40 | DEBUG;TRACE 41 | full 42 | AnyCPU 43 | prompt 44 | MinimumRecommendedRules.ruleset 45 | true 46 | 47 | 48 | 49 | ..\packages\Google.Protobuf.3.8.0\lib\net45\Google.Protobuf.dll 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | Form 66 | 67 | 68 | Form1.cs 69 | 70 | 71 | 72 | 73 | Form1.cs 74 | 75 | 76 | ResXFileCodeGenerator 77 | Resources.Designer.cs 78 | Designer 79 | 80 | 81 | True 82 | Resources.resx 83 | 84 | 85 | SettingsSingleFileGenerator 86 | Settings.Designer.cs 87 | 88 | 89 | True 90 | Settings.settings 91 | True 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | {091659ba-a36b-45d5-aaf2-3ce764453ff2} 100 | ApkShellext2 101 | 102 | 103 | 104 | 105 | 106 | 107 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /apkshellextTest/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /apkshellextTest/Form1.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ApkShellext2/AppxReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | using ICSharpCode.SharpZipLib.Zip; 8 | using System.Xml; 9 | using System.Drawing; 10 | using System.Text.RegularExpressions; 11 | 12 | namespace ApkShellext2 { 13 | /// 14 | /// 15 | /// 16 | public class AppxReader : AppPackageReader { 17 | private const string AppxManifestXml = @"AppxManifest.xml"; 18 | //private const string elemPackage = @"Package"; 19 | private const string elemIdentity = @"Identity"; 20 | private const string elemProperties = @"Properties"; 21 | private const string elemDisplayName = @"DisplayName"; 22 | private const string elemLogo = @"Logo"; 23 | private const string elemPhoneIdentity = @"mp:PhoneIdentity"; 24 | 25 | private const string attrVersion = @"Version"; 26 | private const string attrName = @"Name"; 27 | private const string attrPublisher = @"Publisher"; 28 | private const string attrPhoneProductID = @"PhoneProductId"; 29 | 30 | private ZipFile zip; 31 | private string iconPath; 32 | 33 | private string version; 34 | private string appname; 35 | private string packageName; 36 | private string publisher; 37 | private string productid; 38 | 39 | public AppxReader(Stream stream) { 40 | FileName = ""; 41 | zip = new ZipFile(stream); 42 | Extract(); 43 | } 44 | 45 | public AppxReader(string path) { 46 | FileName = path; 47 | zip = new ZipFile(FileName); 48 | Extract(); 49 | } 50 | 51 | public void Extract() { 52 | ZipEntry en = zip.GetEntry(AppxManifestXml); 53 | if (en == null) 54 | throw new EntryPointNotFoundException("cannot find " + AppxManifestXml); 55 | byte[] xmlbytes = new byte[en.Size]; 56 | zip.GetInputStream(en).Read(xmlbytes, 0, (int)en.Size); 57 | 58 | XmlDocument xml = new XmlDocument(); 59 | xml.XmlResolver = null; 60 | xml.Load(zip.GetInputStream(en)); 61 | 62 | XmlElement packageNode = xml.DocumentElement; 63 | XmlElement Identity = packageNode[elemIdentity]; 64 | version = Identity.Attributes[attrVersion].Value.ToString(); 65 | packageName = Identity.Attributes[attrName].Value.ToString(); 66 | publisher = Identity.Attributes[attrPublisher].Value.ToString(); 67 | Match m = Regex.Match(publisher,@"CN=([^,]*),?"); 68 | if (m.Success) { 69 | publisher = m.Groups[1].Value; 70 | } 71 | 72 | XmlElement DisplayName = packageNode[elemProperties][elemDisplayName]; 73 | appname = DisplayName.FirstChild.Value.ToString(); 74 | XmlElement Logo = packageNode[elemProperties][elemLogo]; 75 | iconPath = Logo.FirstChild.Value.ToString().Replace(@"\",@"/"); 76 | XmlElement PhoneIdentity = packageNode[elemPhoneIdentity]; 77 | productid = PhoneIdentity.Attributes[attrPhoneProductID].Value.ToString(); 78 | } 79 | 80 | public override AppPackageReader.AppType Type { 81 | get { 82 | return AppType.WindowsPhoneApp; 83 | } 84 | } 85 | 86 | public override string AppName { 87 | get { 88 | return appname; 89 | } 90 | } 91 | 92 | public override string Version { 93 | get { 94 | return version; 95 | } 96 | } 97 | 98 | public override string Publisher { 99 | get { 100 | return publisher; 101 | } 102 | } 103 | 104 | public override string PackageName { 105 | get { 106 | return packageName; 107 | } 108 | } 109 | 110 | public override string AppID { 111 | get { 112 | return productid; 113 | } 114 | } 115 | 116 | public override Bitmap Icon { 117 | get { 118 | if (iconPath == "") 119 | throw new Exception("Cannot find logo path"); 120 | int dot = iconPath.LastIndexOf("."); 121 | string name = iconPath.Substring(0, dot); 122 | string extension = iconPath.Substring(dot + 1); 123 | ZipEntry logo = null; 124 | int scale = -1; 125 | foreach (ZipEntry en in zip) { 126 | Match m = Regex.Match(en.Name, name + @"(\.scale\-(\d+))?" + @"\." + extension); 127 | if (m.Success) { 128 | if (m.Groups[1].Value == "") { // exactly matching, no scale 129 | logo = en; 130 | break; 131 | } else { // find the biggest scale 132 | int newScale = int.Parse(m.Groups[2].Value); if (newScale > scale) { 133 | logo = en; 134 | scale = newScale; 135 | } 136 | } 137 | } 138 | } 139 | if (logo != null) { 140 | //byte[] imageBytes = new byte[logo.Size]; 141 | //zip.GetInputStream(logo).Read(imageBytes, 0, (int)logo.Size); 142 | return new Bitmap(zip.GetInputStream(logo)); 143 | } else { 144 | throw new EntryPointNotFoundException("Cannot find Logo file: " + iconPath); 145 | } 146 | } 147 | } 148 | 149 | private bool disposed = false; 150 | protected override void Dispose(bool disposing) { 151 | if (disposed) return; 152 | if (disposing) { 153 | if (zip != null) 154 | zip.Close(); 155 | } 156 | disposed = true; 157 | base.Dispose(disposing); 158 | } 159 | 160 | public void Close() { 161 | Dispose(true); 162 | } 163 | 164 | ~AppxReader() { 165 | Dispose(true); 166 | } 167 | 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /ApkShellext2/Preferences.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 21, 16 122 | 123 | 124 | 118 125 | 126 | -------------------------------------------------------------------------------- /apkshellextTest/Form1.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace apkshellextTest 2 | { 3 | partial class Form1 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.pictureBox1 = new System.Windows.Forms.PictureBox(); 32 | this.textBox1 = new System.Windows.Forms.TextBox(); 33 | this.button1 = new System.Windows.Forms.Button(); 34 | this.textBox2 = new System.Windows.Forms.TextBox(); 35 | this.button2 = new System.Windows.Forms.Button(); 36 | this.pictureBox2 = new System.Windows.Forms.PictureBox(); 37 | this.textBox3 = new System.Windows.Forms.TextBox(); 38 | this.textBox4 = new System.Windows.Forms.TextBox(); 39 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); 40 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit(); 41 | this.SuspendLayout(); 42 | // 43 | // pictureBox1 44 | // 45 | this.pictureBox1.Location = new System.Drawing.Point(59, 321); 46 | this.pictureBox1.Name = "pictureBox1"; 47 | this.pictureBox1.Size = new System.Drawing.Size(72, 62); 48 | this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; 49 | this.pictureBox1.TabIndex = 0; 50 | this.pictureBox1.TabStop = false; 51 | // 52 | // textBox1 53 | // 54 | this.textBox1.Location = new System.Drawing.Point(59, 85); 55 | this.textBox1.Name = "textBox1"; 56 | this.textBox1.Size = new System.Drawing.Size(212, 20); 57 | this.textBox1.TabIndex = 1; 58 | // 59 | // button1 60 | // 61 | this.button1.Location = new System.Drawing.Point(277, 83); 62 | this.button1.Name = "button1"; 63 | this.button1.Size = new System.Drawing.Size(75, 23); 64 | this.button1.TabIndex = 2; 65 | this.button1.Text = "Browse"; 66 | this.button1.UseVisualStyleBackColor = true; 67 | this.button1.Click += new System.EventHandler(this.Button1_Click); 68 | // 69 | // textBox2 70 | // 71 | this.textBox2.Location = new System.Drawing.Point(381, 83); 72 | this.textBox2.Multiline = true; 73 | this.textBox2.Name = "textBox2"; 74 | this.textBox2.Size = new System.Drawing.Size(293, 50); 75 | this.textBox2.TabIndex = 3; 76 | // 77 | // button2 78 | // 79 | this.button2.Location = new System.Drawing.Point(59, 247); 80 | this.button2.Name = "button2"; 81 | this.button2.Size = new System.Drawing.Size(75, 23); 82 | this.button2.TabIndex = 4; 83 | this.button2.Text = "Test"; 84 | this.button2.UseVisualStyleBackColor = true; 85 | this.button2.Click += new System.EventHandler(this.Button2_Click); 86 | // 87 | // pictureBox2 88 | // 89 | this.pictureBox2.Location = new System.Drawing.Point(59, 153); 90 | this.pictureBox2.Name = "pictureBox2"; 91 | this.pictureBox2.Size = new System.Drawing.Size(85, 73); 92 | this.pictureBox2.TabIndex = 5; 93 | this.pictureBox2.TabStop = false; 94 | // 95 | // textBox3 96 | // 97 | this.textBox3.Location = new System.Drawing.Point(265, 166); 98 | this.textBox3.Name = "textBox3"; 99 | this.textBox3.Size = new System.Drawing.Size(359, 20); 100 | this.textBox3.TabIndex = 6; 101 | // 102 | // textBox4 103 | // 104 | this.textBox4.Location = new System.Drawing.Point(265, 206); 105 | this.textBox4.Name = "textBox4"; 106 | this.textBox4.Size = new System.Drawing.Size(359, 20); 107 | this.textBox4.TabIndex = 7; 108 | // 109 | // Form1 110 | // 111 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 112 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 113 | this.ClientSize = new System.Drawing.Size(710, 559); 114 | this.Controls.Add(this.textBox4); 115 | this.Controls.Add(this.textBox3); 116 | this.Controls.Add(this.pictureBox2); 117 | this.Controls.Add(this.button2); 118 | this.Controls.Add(this.textBox2); 119 | this.Controls.Add(this.button1); 120 | this.Controls.Add(this.textBox1); 121 | this.Controls.Add(this.pictureBox1); 122 | this.Name = "Form1"; 123 | this.Text = "Form1"; 124 | this.Load += new System.EventHandler(this.Form1_Load); 125 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); 126 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit(); 127 | this.ResumeLayout(false); 128 | this.PerformLayout(); 129 | 130 | } 131 | 132 | #endregion 133 | 134 | private System.Windows.Forms.PictureBox pictureBox1; 135 | private System.Windows.Forms.TextBox textBox1; 136 | private System.Windows.Forms.Button button1; 137 | private System.Windows.Forms.TextBox textBox2; 138 | private System.Windows.Forms.Button button2; 139 | private System.Windows.Forms.PictureBox pictureBox2; 140 | private System.Windows.Forms.TextBox textBox3; 141 | private System.Windows.Forms.TextBox textBox4; 142 | } 143 | } 144 | 145 | -------------------------------------------------------------------------------- /ApkShellext2/Properties/Resources.my-MM.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | အိုကေ 122 | 123 | 124 | GitHub ေပါ်ရှိ တရားဝင်စာမျက်နှာ 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /ApkShellextService/apkShellextService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using System; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Net; 6 | using System.ServiceProcess; 7 | using System.Threading; 8 | using System.Collections.Generic; 9 | 10 | namespace ApkShellext2 { 11 | class apkShellextService : ServiceBase { 12 | public apkShellextService() { 13 | ServiceName = "ApkShellext Service"; 14 | EventLog.Log = "Application"; 15 | 16 | CanHandlePowerEvent = false; 17 | CanHandleSessionChangeEvent = false; 18 | CanPauseAndContinue = false; 19 | CanShutdown = false; 20 | CanStop = true; 21 | } 22 | 23 | static void Main() { 24 | ServiceBase.Run(new apkShellextService()); 25 | } 26 | 27 | protected override void Dispose(bool disposing) { 28 | base.Dispose(disposing); 29 | } 30 | 31 | private WebServer ws; 32 | 33 | private static string LocalIPAddress() { 34 | var card = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0]; 35 | var str = card.GetIPProperties().GatewayAddresses; 36 | 37 | IPHostEntry host; 38 | string localIP = ""; 39 | host = Dns.GetHostEntry(Dns.GetHostName()); 40 | foreach (IPAddress ip in host.AddressList) { 41 | if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { 42 | localIP = ip.ToString(); 43 | break; 44 | } 45 | } 46 | return localIP; 47 | } 48 | 49 | protected override void OnStart(string[] args) { 50 | base.OnStart(args); 51 | 52 | string[] prefixes = new string[] { 53 | @"http://*:42728", 54 | @"http://localhost:42728/", 55 | @"http://"+LocalIPAddress()+@":42728/", 56 | @"http://127.0.0.1:42728/" 57 | }; 58 | 59 | ws = new WebServer(SendResponse, prefixes); 60 | ws.Run(); 61 | } 62 | 63 | protected override void OnStop() { 64 | base.OnStop(); 65 | ws.Stop(); 66 | } 67 | 68 | /// 69 | /// OnCustomCommand(): If you need to send a command to your 70 | /// service without the need for Remoting or Sockets, use 71 | /// this method to do custom methods. 72 | /// 73 | /// Arbitrary Integer between 128 & 256 74 | protected override void OnCustomCommand(int command) { 75 | // A custom command can be sent to a service by using this method: 76 | //# int command = 128; //Some Arbitrary number between 128 & 256 77 | //# ServiceController sc = new ServiceController("NameOfService"); 78 | //# sc.ExecuteCommand(command); 79 | 80 | base.OnCustomCommand(command); 81 | } 82 | 83 | Dictionary pathList = new Dictionary(); 84 | 85 | public string SendResponse(HttpListenerRequest request) { 86 | if (request.QueryString["md5"] != null) { 87 | if (!pathList.ContainsKey(request.QueryString["md5"])) { 88 | pathList.Add(request.QueryString["md5"], request.QueryString["path"]); 89 | } 90 | return ""; 91 | } else { 92 | string md5 = request.RawUrl.Replace(@"/", ""); 93 | if (pathList.ContainsKey(md5)) 94 | return pathList[md5]; 95 | return ""; 96 | } 97 | } 98 | } 99 | 100 | 101 | public class WebServer 102 | { 103 | private readonly HttpListener _listener = new HttpListener(); 104 | private readonly Func _responderMethod; 105 | 106 | public WebServer(string[] prefixes, Func method) 107 | { 108 | if (!HttpListener.IsSupported) 109 | throw new NotSupportedException( 110 | "Needs Windows XP SP2, Server 2003 or later."); 111 | 112 | if (prefixes == null || prefixes.Length == 0) 113 | throw new ArgumentException("prefixes"); 114 | 115 | // A responder method is required 116 | if (method == null) 117 | throw new ArgumentException("method"); 118 | 119 | foreach (string s in prefixes) 120 | _listener.Prefixes.Add(s); 121 | 122 | _responderMethod = method; 123 | _listener.Start(); 124 | } 125 | 126 | public WebServer(Func method, params string[] prefixes) 127 | : this(prefixes, method) { } 128 | 129 | public void Run() 130 | { 131 | ThreadPool.QueueUserWorkItem((o) => 132 | { 133 | Console.WriteLine("Webserver running..."); 134 | try 135 | { 136 | while (_listener.IsListening) 137 | { 138 | ThreadPool.QueueUserWorkItem((c) => 139 | { 140 | var ctx = c as HttpListenerContext; 141 | try 142 | { 143 | string rstr = _responderMethod(ctx.Request); 144 | if (rstr != "") { 145 | string filename = Path.GetFileName(rstr); 146 | using (FileStream fs = new FileStream(rstr, FileMode.Open)) { 147 | using (BinaryReader sr = new BinaryReader(fs)) { 148 | byte[] buf = sr.ReadBytes((int)sr.BaseStream.Length); 149 | ctx.Response.ContentType = "application/octet-stream"; 150 | ctx.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); 151 | ctx.Response.ContentLength64 = buf.Length; 152 | ctx.Response.OutputStream.Write(buf, 0, buf.Length); 153 | } 154 | } 155 | } 156 | } 157 | catch (Exception ex){ 158 | EventLog log = new EventLog(); 159 | log.WriteEntry(ex.Message); 160 | } // suppress any exceptions 161 | finally 162 | { 163 | // always close the stream 164 | ctx.Response.OutputStream.Close(); 165 | } 166 | }, _listener.GetContext()); 167 | } 168 | } 169 | catch { } // suppress any exceptions 170 | }); 171 | } 172 | 173 | public void Stop() 174 | { 175 | _listener.Stop(); 176 | _listener.Close(); 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /ApkShellext2/Properties/Resources.he-IL.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | 123 | עדכון 124 | 125 | 126 | לך לאתר הפרוייקט כדי לעדכן 127 | 128 | 129 | החלף דפוס 130 | 131 | 132 | 133 | 134 | בדוק ב-GooglePlay 135 | 136 | 137 | 138 | הרחבת מעטפת APK 139 | 140 | 141 | העדפות ועדכון 142 | 143 | 144 | שינוי שם ל {0} 145 | 146 | 147 | 148 | 149 | בדיקת גירסה חדשה... 150 | 151 | 152 | 153 | הגירסה הנוכחית: {0} 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | -------------------------------------------------------------------------------- /ApkShellext2/Properties/Resources.el-GR.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | ΟΚ 122 | 123 | 124 | Επίσημη σελίδα στο GitHub 125 | 126 | 127 | 128 | Πηγαίνετε στην σελίδα του project για ενημέρωση 129 | 130 | 131 | 132 | Δείτε το {0} στο Amazon Appstore 133 | 134 | 135 | Δείτε το {0} στο Appstore της Apple 136 | 137 | 138 | Δείτε το {0} στο Google Play 139 | 140 | 141 | Δείτε το {0} στο Microsoft Store 142 | 143 | 144 | APK Shell Extension 145 | 146 | 147 | Προτιμήσεις && Ενημέρωση 148 | 149 | 150 | Μετονομάστε σε {0} 151 | 152 | 153 | Εμφάνιση συντομέυσεων για app stores όταν έχουν επιλεχθεί πολλά αρχεία 154 | 155 | 156 | 157 | Έλεγχος για νέα έκδοση... 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | Μεγέθυνση εικονιδίου αν τα Windows ζητήσουν για μεγαλύτερο μέγεθος 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | -------------------------------------------------------------------------------- /ApkShellext2/ApkIconHandler.cs: -------------------------------------------------------------------------------- 1 | using ApkQuickReader; 2 | using Microsoft.Win32; 3 | using SharpShell.Attributes; 4 | using SharpShell.Diagnostics; 5 | using SharpShell.Extensions; 6 | using SharpShell.ServerRegistration; 7 | using SharpShell.SharpIconHandler; 8 | using System; 9 | using System.Drawing; 10 | using System.IO; 11 | using System.Linq; 12 | using System.Runtime.InteropServices; 13 | using ApkShellext2.Properties; 14 | using System.Threading; 15 | using System.Text.RegularExpressions; 16 | 17 | namespace ApkShellext2 { 18 | /// 19 | /// This is the icon handler, not only supporting apk, but also other type of apps. 20 | /// 21 | [Guid("1F869CEE-4FDA-35D9-896F-43975A87D1F6")] 22 | [ComVisible(true)] 23 | [ClassInterface(ClassInterfaceType.None)] 24 | [COMServerAssociation(AssociationType.ClassOfExtension, ".apk")] 25 | [COMServerAssociation(AssociationType.ClassOfExtension, ".ipa")] 26 | [COMServerAssociation(AssociationType.ClassOfExtension, ".appxbundle")] 27 | [COMServerAssociation(AssociationType.ClassOfExtension, ".appx")] 28 | public class ApkIconHandler : SharpIconHandler { 29 | private Bitmap m_icon = null; 30 | protected override Icon GetIcon(bool smallIcon, uint iconSize) { 31 | if (m_icon == null) { 32 | try { 33 | using (AppPackageReader reader = AppPackageReader.Read(SelectedItemPath)) { 34 | if (reader.Type == AppPackageReader.AppType.iOSApp && Utility.GetSetting("ShowIpaIcon", "True") != "True") { 35 | m_icon = Utility.AppTypeIcon(reader.Type); 36 | } else if ((reader.Type == AppPackageReader.AppType.WindowsPhoneApp || 37 | reader.Type == AppPackageReader.AppType.WindowsPhoneAppBundle) && 38 | Utility.GetSetting("ShowAppxIcon", "False") != "True") { 39 | m_icon = Utility.AppTypeIcon(reader.Type); 40 | } else { 41 | m_icon = reader.getIcon(new Size((int)iconSize, (int)iconSize)); 42 | } 43 | if (m_icon == null) 44 | throw new Exception("Cannot find Icon for " + Path.GetFileName(SelectedItemPath) + ", draw default"); 45 | } 46 | if (Utility.GetSetting("ShowOverLayIcon") == "True") 47 | m_icon = Utility.CombineBitmap(m_icon, 48 | Utility.AppTypeIcon(AppPackageReader.getAppType(SelectedItemPath)), 49 | new Rectangle((int)(m_icon.Width * 0.05), 0, (int)(m_icon.Width * 0.95), (int)(m_icon.Height * 0.95)), 50 | new Rectangle(0, (int)m_icon.Height / 2, (int)m_icon.Width / 2, (int)m_icon.Height / 2), 51 | new Size((int)m_icon.Width, (int)m_icon.Height)); 52 | } catch (Exception ex) { 53 | Log("Error in reading icon for " + Path.GetFileName(SelectedItemPath) + ", draw default : " + ex.Message); 54 | // read error, draw the default icon 55 | m_icon = Utility.AppTypeIcon(AppPackageReader.getAppType(SelectedItemPath)); 56 | } 57 | } 58 | 59 | return Icon.FromHandle(Utility.ResizeBitmap(m_icon, new Size((int)iconSize, (int)iconSize)).GetHicon()); 60 | } 61 | 62 | [CustomRegisterFunction] 63 | public static void postDoRegister(Type type, RegistrationType registrationType) { 64 | Console.WriteLine("Registering " + type.FullName + " Version " + type.Assembly.GetName().Version.ToString()); 65 | 66 | // Todo: clean other icon handler as they were integrated 67 | //"d5ff6172-1ae5-4c4a-a207-5a2dd100891e" 68 | //"a0ac4758-12d3-4dcf-9d12-03faaa3c0a9d" 69 | 70 | #region Clean up apkshellext registry 71 | try { 72 | string oldVersionClassName = @"KKHomeProj.ApkShellExt.ApkShellExt"; 73 | string oldVersionCLID = ""; 74 | using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(oldVersionClassName + @"\CLSID")) { 75 | if (key != null) { 76 | Console.WriteLine("Found old version in registry, cleaning up ..."); 77 | oldVersionCLID = (string)key.GetValue(null); 78 | key.Close(); 79 | Registry.ClassesRoot.DeleteSubKeyTree(oldVersionClassName); 80 | } 81 | } 82 | if (oldVersionCLID != "") { 83 | using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\CLSID\" + oldVersionCLID)) { 84 | if (key != null) { 85 | key.Close(); 86 | Registry.LocalMachine.DeleteSubKeyTree(@"SOFTWARE\Classes\CLSID\" + oldVersionCLID); 87 | } 88 | } 89 | using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved\" + oldVersionCLID)) { 90 | if (key != null) { 91 | key.Close(); 92 | Registry.LocalMachine.DeleteSubKeyTree(@"Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved\" + oldVersionCLID); 93 | } 94 | } 95 | } 96 | } catch (Exception e) { 97 | Logging.Error("Cleaning up apkshellext remaining registry items but see exception" + 98 | e.Message); 99 | } 100 | #endregion 101 | 102 | #region Clean up older versions registry 103 | try { 104 | using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(@"\CLSID\" + 105 | type.GUID.ToRegistryString() + @"\InprocServer32")) { 106 | if (key != null && key.GetSubKeyNames().Count() != 0) { 107 | Console.WriteLine("Found old version in registry, cleaning up ..."); 108 | foreach (var k in key.GetSubKeyNames()) { 109 | if (k != type.Assembly.GetName().Version.ToString()) { 110 | Registry.ClassesRoot.DeleteSubKeyTree(@"\CLSID\" + 111 | type.GUID.ToRegistryString() + @"\InprocServer32\" + k); 112 | } 113 | } 114 | } 115 | } 116 | } catch (Exception e) { 117 | Logging.Error("Cleaning up older version but see exception. " 118 | + e.Message); 119 | } 120 | 121 | #endregion 122 | 123 | #region restore the old settings from registry 124 | // This is not possible as at this time, the user is admin, which is different when running explorer, so comment this out for now. 125 | //Settings.Default.ShowAppStoreWhenMultiSelected = Utility.getRegistrySetting(Utility.keyMultiSelectShowStore) == 1; 126 | //Settings.Default.ShowGooglePlay = Utility.getRegistrySetting(Utility.keyShowGooglePlay) == 1; 127 | //Settings.Default.ShowOverLayIcon = Utility.getRegistrySetting(Utility.keyShowOverlay) == 1; 128 | //Settings.Default.ShowIpaIcon = Utility.getRegistrySetting(Utility.keyShowIpaIcon) == 1; 129 | //Settings.Default.ShowAppxIcon = Utility.getRegistrySetting(Utility.keyShowAppxIcon) == 1; 130 | //Settings.Default.ShowMenuIcon = Utility.getRegistrySetting(Utility.keyShowMenuIcon) == 1; 131 | 132 | //if (Utility.getRegistrySetting(Utility.keyRenameWithVersionCode) == 1) { 133 | // Settings.Default.RenamePattern = Resources.strRenamePatternDefault + "_" + Resources.varRevision; 134 | //} 135 | 136 | //int lang = Utility.getRegistrySetting(Utility.keyLanguage, -1); 137 | //if (lang != -1) { 138 | // Settings.Default.Language = lang; 139 | //} 140 | //Settings.Default.Save(); 141 | #endregion 142 | 143 | #region Enable debug log 144 | #if DEBUG 145 | using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE", true).CreateSubKey(@"SharpShell", RegistryKeyPermissionCheck.ReadWriteSubTree)) { 146 | key.SetValue("LoggingMode", 4); 147 | key.SetValue("LogPath", @"%AppData%\apkshellext.log",RegistryValueKind.ExpandString); 148 | } 149 | #endif 150 | #endregion 151 | } 152 | 153 | protected override void Log(string message) { 154 | Utility.Log(this, Path.GetFileName(SelectedItemPath), message); 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /ApkShellext2/IpaReader.cs: -------------------------------------------------------------------------------- 1 | using PlistCS; 2 | using PNGDecrush; 3 | using SharpShell.Attributes; 4 | using SharpShell.Extensions; 5 | using SharpShell.Diagnostics; 6 | using SharpShell.Exceptions; 7 | using SharpShell.ServerRegistration; 8 | using SharpShell.SharpIconHandler; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Drawing; 12 | using System.IO; 13 | using System.Linq; 14 | using System.Runtime.InteropServices; 15 | using System.Text; 16 | using System.Threading.Tasks; 17 | using ICSharpCode.SharpZipLib.Zip; 18 | using Microsoft.Win32; 19 | using System.Text.RegularExpressions; 20 | using Ionic.Zlib; 21 | 22 | namespace ApkShellext2 23 | { 24 | public class IpaReader : AppPackageReader 25 | { 26 | private string strAppRoot; 27 | private Dictionary infoPlistDic; 28 | private Dictionary itunesMetadataDic; 29 | private ZipFile zip; 30 | 31 | private const string iTunesMetadataPath = @"iTunesMetadata.plist"; 32 | private const string infoPlistPath = @"(Payload/.*\.app/)Info\.plist"; 33 | private const string CFBundleIcons = @"CFBundleIcons"; 34 | private const string CFBundlePrimaryIcon = @"CFBundlePrimaryIcon"; 35 | private const string CFBundleIconFile = @"CFBundleIconFile"; 36 | private const string CFBundleIconFiles = @"CFBundleIconFiles"; 37 | private const string CFBundleDisplayName = @"CFBundleDisplayName"; 38 | private const string FacebookDisplayName = @"FacebookDisplayName"; 39 | private const string CFBundleIdentifier = @"CFBundleIdentifier"; 40 | private const string CFBundleShortVersionString = @"CFBundleShortVersionString"; 41 | private const string CFBundleVersion = @"CFBundleVersion"; 42 | private const string CFBundleResourceSpecification = @"CFBundleResourceSpecification"; 43 | 44 | public const string flagAppId = @"itemId"; 45 | public const string flagCopyright = @"copyright"; 46 | 47 | public IpaReader(string path) { 48 | FileName = path; 49 | openStream(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)); 50 | } 51 | 52 | public IpaReader(Stream stream) { 53 | openStream(stream); 54 | } 55 | 56 | private void openStream(Stream stream) { 57 | zip = new ZipFile(stream); 58 | ZipEntry infoPlist = null; 59 | foreach (ZipEntry en in zip) { 60 | Match m = Regex.Match(en.Name, infoPlistPath); 61 | if (m.Success) { 62 | strAppRoot = m.Groups[1].Value; 63 | infoPlist = en; 64 | break; 65 | } 66 | } 67 | 68 | if (infoPlist == null) { 69 | throw new EntryPointNotFoundException("cannot find info.plist"); 70 | } 71 | 72 | byte[] infoBytes = new byte[infoPlist.Size]; 73 | zip.GetInputStream(infoPlist).Read(infoBytes, 0, (int)infoPlist.Size); 74 | 75 | infoPlistDic = (Dictionary)Plist.readPlist(infoBytes); 76 | } 77 | 78 | public string[] getStrings(Dictionary dic, string[] keys) { 79 | for (int i = 0; i < keys.Length - 1; i++) { 80 | if (dic.ContainsKey(keys[i])) { 81 | dic = (Dictionary)dic[keys[i]]; 82 | } else { 83 | return new string[] { }; 84 | //throw new Exception("Given ID is not valid"); 85 | } 86 | } 87 | if (dic.ContainsKey(keys[keys.Length - 1])) { 88 | if (dic[keys[keys.Length - 1]] is string) { 89 | return new string[] { dic[keys[keys.Length - 1]] as string }; 90 | } 91 | if (dic[keys[keys.Length - 1]] is int) { 92 | return new string[] { dic[keys[keys.Length - 1]].ToString() }; 93 | } else { // is list 94 | object[] arr = ((List)dic[keys[keys.Length - 1]]).ToArray(); 95 | return Array.ConvertAll(arr, x => x.ToString()); 96 | } 97 | } else { 98 | return new string[] { }; 99 | } 100 | } 101 | 102 | public Bitmap getImage(string[] keys) { 103 | string[] images = getStrings(infoPlistDic, keys); 104 | if (images.Count() > 0) { 105 | return getImage(images[0]); 106 | } 107 | return null; 108 | } 109 | 110 | public Bitmap getImage(string name) { 111 | string fullname = name; 112 | ZipEntry image; 113 | if (!name.EndsWith(".png")) { 114 | fullname = name + @"@3x" + ".png"; 115 | image = zip.GetEntry(strAppRoot + fullname); 116 | if (image == null) { 117 | fullname = name + @"@2x" + ".png"; 118 | image = zip.GetEntry(strAppRoot + fullname); 119 | } 120 | if (image == null) { 121 | fullname = name + ".png"; 122 | image = zip.GetEntry(strAppRoot + fullname); 123 | } 124 | } else { 125 | image = zip.GetEntry(strAppRoot + name); 126 | } 127 | 128 | if (image == null) { 129 | return null; 130 | } 131 | byte[] imageBytes = new byte[image.Size]; 132 | zip.GetInputStream(image).Read(imageBytes, 0, (int)image.Size); 133 | try { 134 | MemoryStream imageOut = new MemoryStream(); 135 | PNGDecrusher.Decrush(new MemoryStream(imageBytes), imageOut); 136 | return new Bitmap(imageOut); 137 | } catch (InvalidDataException) { // image is not crushed 138 | return new Bitmap(new MemoryStream(imageBytes)); 139 | } 140 | } 141 | 142 | public override AppPackageReader.AppType Type { 143 | get { 144 | return AppType.iOSApp; 145 | } 146 | } 147 | 148 | public override string AppName { 149 | get { 150 | try { 151 | string[] n = getStrings(infoPlistDic, new string[] { 152 | CFBundleDisplayName}); 153 | if (n.Count() == 0) { 154 | n = getStrings(infoPlistDic, new string[] { 155 | FacebookDisplayName }); 156 | } 157 | return n[0]; 158 | } catch { 159 | return ""; 160 | } 161 | } 162 | } 163 | 164 | public override string Version { 165 | get { 166 | try { 167 | return getStrings(infoPlistDic, new string[] { 168 | CFBundleShortVersionString})[0]; 169 | } catch { 170 | return ""; 171 | } 172 | } 173 | } 174 | 175 | public override string Revision { 176 | get { 177 | try { 178 | return getStrings(infoPlistDic, new string[] { 179 | CFBundleVersion})[0]; 180 | } catch { 181 | return ""; 182 | } 183 | } 184 | } 185 | 186 | public override string PackageName { 187 | get { 188 | try { 189 | return getStrings(infoPlistDic, new string[] { 190 | CFBundleIdentifier})[0]; 191 | } catch { 192 | return ""; 193 | } 194 | } 195 | } 196 | public override Bitmap Icon { 197 | get { 198 | try { 199 | Bitmap icon = getImage(new string[] { 200 | CFBundleIcons, 201 | CFBundlePrimaryIcon, 202 | CFBundleIconFiles }); ; 203 | if (icon == null) { 204 | icon = getImage(new string[] { 205 | CFBundleIcons, 206 | CFBundlePrimaryIcon, 207 | CFBundleIconFile }); ; 208 | } 209 | if (icon == null) { 210 | icon = getImage(new string[] { 211 | CFBundleIconFiles }); 212 | } 213 | if (icon == null) { 214 | icon = getImage(new string[] { 215 | CFBundleIconFile}); 216 | } 217 | if (icon == null) { 218 | icon = getImage("AppIcon"); 219 | } 220 | if (icon == null) { 221 | icon = getImage("Icon"); 222 | } 223 | return icon; 224 | } catch { 225 | return null; 226 | } 227 | } 228 | } 229 | 230 | public override string Publisher { 231 | get { 232 | try { 233 | ZipEntry itunesMetadata = zip.GetEntry(iTunesMetadataPath); 234 | if (itunesMetadata == null) 235 | return ""; 236 | byte[] itunesMetadataBytes = new byte[itunesMetadata.Size]; 237 | zip.GetInputStream(itunesMetadata).Read(itunesMetadataBytes, 0, (int)itunesMetadata.Size); 238 | itunesMetadataDic = (Dictionary)Plist.readPlist(itunesMetadataBytes); 239 | return getStrings(itunesMetadataDic, new string[] { flagCopyright })[0]; 240 | } catch { 241 | return ""; 242 | } 243 | } 244 | } 245 | 246 | public override string AppID { 247 | get { 248 | try { 249 | ZipEntry itunesMetadata = zip.GetEntry(iTunesMetadataPath); 250 | if (itunesMetadata == null) 251 | return ""; 252 | byte[] itunesMetadataBytes = new byte[itunesMetadata.Size]; 253 | zip.GetInputStream(itunesMetadata).Read(itunesMetadataBytes, 0, (int)itunesMetadata.Size); 254 | itunesMetadataDic = (Dictionary)Plist.readPlist(itunesMetadataBytes); 255 | return getStrings(itunesMetadataDic, new string[] { flagAppId })[0]; 256 | } catch { 257 | return ""; 258 | } 259 | } 260 | } 261 | 262 | 263 | private bool disposed = false; 264 | protected override void Dispose(bool disposing) { 265 | if (disposed) return; 266 | if (disposing) { 267 | if (zip != null) 268 | zip.Close(); 269 | } 270 | disposed = true; 271 | base.Dispose(disposing); 272 | } 273 | 274 | public void Close() { 275 | Dispose(true); 276 | } 277 | 278 | ~IpaReader() { 279 | Dispose(true); 280 | } 281 | } 282 | } 283 | -------------------------------------------------------------------------------- /ApkShellext2/Properties/Resources.ko-KR.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | 123 | 업데이트 124 | 125 | 126 | 프로젝트 웹 사이트에서 업데이트하기 127 | 128 | 129 | 이름변경 패턴 130 | 131 | 132 | 아마존 앱스토어에서 {0} 찾기 133 | 134 | 135 | 애플 앱스토어에서 {0} 찾기 136 | 137 | 138 | 구글 플레이스토어에서 {0} 찾기 139 | 140 | 141 | Windows 스토어에서 {0} 확인 142 | 143 | 144 | APK 쉘 확장 145 | 146 | 147 | 설정 및 업데이트 확인 148 | 149 | 150 | 파일 이름을 {0}(으)로 바꾸기 151 | 152 | 153 | 여러개의 파일을 선택했을 때에도 앱 스토어 메뉴 표시 154 | 155 | 156 | 이 옵션을 체크하면, 여러 개의 앱 파일을 선택해도 "앱 스토어로 이동하기" 메뉴가 보입니다. 157 | 다만, 선택한 파일만큼 많은 브라우저 창이 뜨기 때문에 컴퓨터가 느려질 수 있습니다. 158 | 기본적으로, 한 파일을 선택할 때에만 이 메뉴가 나옵니다. 159 | 160 | 161 | 업데이트 확인 중 … 162 | 163 | 164 | 프로젝트 웹 사이트에서 업데이트 확인하기 165 | 166 | 167 | 현재 버전: {0} 168 | 169 | 170 | 현재 최신버전입니다. 171 | 172 | 173 | ApkShellext2의 프로젝트 웹 사이트로 이동하기 174 | 175 | 176 | 언어 선택: 177 | 178 | 179 | 해당 기능을 사용하려면 ApkShellextService가 필요합니다. 해당 서비스가 실행 중인지 확인해 주십시오. 180 | 181 | 182 | 새 버전 {0}을 사용할 수 있습니다. 183 | 184 | 185 | ApkShellext2 설정 186 | 187 | 188 | 파일을 읽지 못했습니다. 189 | 190 | 191 | 변수의 사용법은 위키를 참조하십시오. 192 | 193 | 194 | 일부 안드로이드 앱에서 버전은 같은데 리비전(세부 버전)이 다른 경우가 있습니다. 195 | 이 옵션을 설정하면 파일 이름을 바꿀 때 이름을 %AppName%_%Version%_%Revision% 형식을 사용합니다. 196 | 해제하면 %AppName%_%Version% 을 사용합니다. 197 | 198 | 199 | QR코드를 스캔해서 다운로드하기 200 | 201 | 202 | Windows Phone 앱(appx, appxbundle)의 아이콘을 보여줍니다. 203 | 204 | 205 | iOS 앱(ipa)의 아이콘을 보여줍니다. 206 | 207 | 208 | 오버레이 아이콘을 보여줍니다. 209 | 210 | 211 | 파일 형식에 따른 오버레이 아이콘 표시 212 | 213 | 214 | 215 | 216 | 아니오 217 | 218 | 219 | 220 | 파일 이름을 {0} (으)로 바꾸시겠습니까? 221 | 222 | 223 | 이름 바꾸기 패턴: (확장자 없음) 224 | 225 | 226 | 우클릭 메뉴 227 | 228 | 229 | 230 | 231 | 232 | 233 | ApkMirror.com에서 {0} 찾기 234 | 235 | 236 | 237 | 우클릭 메뉴에서 아마존 앱 스토어 링크를 표시하기 238 | 239 | 240 | 우클릭 메뉴에서 ApkMirror 링크를 표시하기 241 | 242 | 243 | (ipa 파일) 우클릭 메뉴에서 애플 앱 스토어 메뉴에 표시하기 244 | 245 | 246 | 247 | (appx/appxbundle 파일) 우클릭 메뉴에서 마이크로소프트 스토어 링크 표시하기 248 | 249 | 250 | 251 | 252 | 253 | adb.exe의 경로를 지정해 주십시오. 254 | 255 | 256 | 257 | 새 버전 알리기 258 | 259 | 260 | 썸네일 261 | 262 | 263 | 264 | 이 프로젝트의 번역을 도와주세요. 265 | 266 | 267 | 268 | 열려 있는 모든 탐색기 창이 닫힙니다. 계속하시겠습니까? 269 | 270 | 271 | 272 | 아이콘 및 미리 보기 이미지를 올바르게 표시하려면 캐시를 삭제해야 합니다. 지금 삭제하시겠습니까? 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | -------------------------------------------------------------------------------- /ApkShellext2/Properties/Resources.ja-JP.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | OK 122 | 123 | 124 | 公式GitHubページ 125 | 126 | 127 | 128 | 更新のためプロジェクトサイトへ移動 129 | 130 | 131 | 名前変更パターン 132 | 133 | 134 | Amazon Appstore で {0} をチェック 135 | 136 | 137 | Apple App Store で {0} をチェック 138 | 139 | 140 | Google Play で {0} をチェック 141 | 142 | 143 | Microsoft Storeで {0} をチェック 144 | 145 | 146 | 147 | 148 | 名前を {0} に変更 149 | 150 | 151 | 複数のファイルを選択したときアプリストアメニューを表示する 152 | 153 | 154 | チェックした場合、複数のapkファイルを選択した時でもアプリストアメニューが表示されます。 155 | 注意: ブラウザのウインドウが大量に開かれてパフォーマンスに影響する可能性があります。 156 | デフォルトでは、一つのファイルを選択したときだけ表示します。 157 | 158 | 159 | 新しいバージョンを確認しています ... 160 | 161 | 162 | プロジェクトサイトで更新を確認します。 163 | 164 | 165 | 166 | 素晴らしい! 最新バージョンを使用中です。 167 | 168 | 169 | ApkShellext2 プロジェクトサイトへ 170 | 171 | 172 | 使用する言語: 173 | 174 | 175 | この機能は ApkShellextService を必要としています。サービスが開始されているか確認してください。 176 | 177 | 178 | 新しいバージョン {0} があります 179 | 180 | 181 | 182 | ファイルを読み取れません 183 | 184 | 185 | 変数の使用方法は、プロジェクトのWikiを参照してください。 186 | 187 | 188 | Android アプリでよく起きる、同じバージョンで異なるリビジョン番号、といった状況を回避します。 189 | チェックすると、アプリファイルを %AppName%_%Version%_%Revision% 、または %AppName%_%Version% に変更します。 190 | 191 | 192 | QR コードをスキャンするとダウンロード出来ます 193 | 194 | 195 | Windows Phone アプリ (appx, appxbundle) のアイコンを表示する 196 | 197 | 198 | iOS アプリ (ipa) のアイコンを表示する 199 | 200 | 201 | オーバーレイアイコンを表示する 202 | 203 | 204 | ファイルタイプのオーバーレイアイコンを表示します。 205 | 206 | 207 | コンテキストメニューアイコンの表示 208 | 209 | 210 | 211 | 212 | はい 213 | 214 | 215 | このファイルの名前を {0} に変更しますか? 216 | 217 | 218 | 名前の変更パターン: (拡張子除く) 219 | 220 | 221 | コンテキストメニュー 222 | 223 | 224 | 基本設定 225 | 226 | 227 | 228 | 名前の変更 229 | 230 | 231 | 232 | CheckApkMirror.comで {0} をチェックする 233 | 234 | 235 | 最後に保存したパターンを使う 236 | 237 | 238 | Amazonアプリストアリンクをコンテキストメニューに表示する 239 | 240 | 241 | ApkMirrorリンクをコンテキストメニューに表示する 242 | 243 | 244 | Apple storeリンク (ipa用) をコンテキストメニューに表示する 245 | 246 | 247 | Google Playストアリンクをコンテキストメニューに表示する 248 | 249 | 250 | Microsoft Storeリンク (appx/appxbundle) をコンテキストメニューに表示する 251 | 252 | 253 | 254 | 参照 255 | 256 | 257 | 258 | adb.exeのパスを指定してください。 259 | 260 | 261 | 262 | アプリの更新をコンテキストメニューで知らせる 263 | 264 | 265 | 266 | Windowsが大きいサイズのサムネイルを要求したとき、拡大する 267 | 268 | 269 | このプロジェクトの翻訳を助けてください。 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | -------------------------------------------------------------------------------- /ApkShellext2/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ApkShellext2.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.1.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | 26 | [global::System.Configuration.UserScopedSettingAttribute()] 27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 29 | public bool ShowAppStoreWhenMultiSelected { 30 | get { 31 | return ((bool)(this["ShowAppStoreWhenMultiSelected"])); 32 | } 33 | set { 34 | this["ShowAppStoreWhenMultiSelected"] = value; 35 | } 36 | } 37 | 38 | [global::System.Configuration.UserScopedSettingAttribute()] 39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 40 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 41 | public bool ShowGooglePlay { 42 | get { 43 | return ((bool)(this["ShowGooglePlay"])); 44 | } 45 | set { 46 | this["ShowGooglePlay"] = value; 47 | } 48 | } 49 | 50 | [global::System.Configuration.UserScopedSettingAttribute()] 51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 52 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 53 | public bool ShowAmazonStore { 54 | get { 55 | return ((bool)(this["ShowAmazonStore"])); 56 | } 57 | set { 58 | this["ShowAmazonStore"] = value; 59 | } 60 | } 61 | 62 | [global::System.Configuration.UserScopedSettingAttribute()] 63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 64 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 65 | public bool ShowApkMirror { 66 | get { 67 | return ((bool)(this["ShowApkMirror"])); 68 | } 69 | set { 70 | this["ShowApkMirror"] = value; 71 | } 72 | } 73 | 74 | [global::System.Configuration.UserScopedSettingAttribute()] 75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 76 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 77 | public bool ShowAppleStore { 78 | get { 79 | return ((bool)(this["ShowAppleStore"])); 80 | } 81 | set { 82 | this["ShowAppleStore"] = value; 83 | } 84 | } 85 | 86 | [global::System.Configuration.UserScopedSettingAttribute()] 87 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 88 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 89 | public bool ShowMSStore { 90 | get { 91 | return ((bool)(this["ShowMSStore"])); 92 | } 93 | set { 94 | this["ShowMSStore"] = value; 95 | } 96 | } 97 | 98 | [global::System.Configuration.UserScopedSettingAttribute()] 99 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 100 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 101 | public bool ShowOverLayIcon { 102 | get { 103 | return ((bool)(this["ShowOverLayIcon"])); 104 | } 105 | set { 106 | this["ShowOverLayIcon"] = value; 107 | } 108 | } 109 | 110 | [global::System.Configuration.UserScopedSettingAttribute()] 111 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 112 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 113 | public bool ShowIpaIcon { 114 | get { 115 | return ((bool)(this["ShowIpaIcon"])); 116 | } 117 | set { 118 | this["ShowIpaIcon"] = value; 119 | } 120 | } 121 | 122 | [global::System.Configuration.UserScopedSettingAttribute()] 123 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 124 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 125 | public bool ShowAppxIcon { 126 | get { 127 | return ((bool)(this["ShowAppxIcon"])); 128 | } 129 | set { 130 | this["ShowAppxIcon"] = value; 131 | } 132 | } 133 | 134 | [global::System.Configuration.UserScopedSettingAttribute()] 135 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 136 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 137 | public bool ShowMenuIcon { 138 | get { 139 | return ((bool)(this["ShowMenuIcon"])); 140 | } 141 | set { 142 | this["ShowMenuIcon"] = value; 143 | } 144 | } 145 | 146 | [global::System.Configuration.UserScopedSettingAttribute()] 147 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 148 | [global::System.Configuration.DefaultSettingValueAttribute("")] 149 | public string RenamePattern { 150 | get { 151 | return ((string)(this["RenamePattern"])); 152 | } 153 | set { 154 | this["RenamePattern"] = value; 155 | } 156 | } 157 | 158 | [global::System.Configuration.UserScopedSettingAttribute()] 159 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 160 | [global::System.Configuration.DefaultSettingValueAttribute("")] 161 | public string ToolTipPattern { 162 | get { 163 | return ((string)(this["ToolTipPattern"])); 164 | } 165 | set { 166 | this["ToolTipPattern"] = value; 167 | } 168 | } 169 | 170 | [global::System.Configuration.UserScopedSettingAttribute()] 171 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 172 | [global::System.Configuration.DefaultSettingValueAttribute("-1")] 173 | public int Language { 174 | get { 175 | return ((int)(this["Language"])); 176 | } 177 | set { 178 | this["Language"] = value; 179 | } 180 | } 181 | 182 | [global::System.Configuration.UserScopedSettingAttribute()] 183 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 184 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 185 | public bool ShowApkIcon { 186 | get { 187 | return ((bool)(this["ShowApkIcon"])); 188 | } 189 | set { 190 | this["ShowApkIcon"] = value; 191 | } 192 | } 193 | 194 | [global::System.Configuration.UserScopedSettingAttribute()] 195 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 196 | [global::System.Configuration.DefaultSettingValueAttribute("0")] 197 | public int LastPanel { 198 | get { 199 | return ((int)(this["LastPanel"])); 200 | } 201 | set { 202 | this["LastPanel"] = value; 203 | } 204 | } 205 | 206 | [global::System.Configuration.UserScopedSettingAttribute()] 207 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 208 | [global::System.Configuration.DefaultSettingValueAttribute("2014-12-31")] 209 | public global::System.DateTime LastCheckUpdateTime { 210 | get { 211 | return ((global::System.DateTime)(this["LastCheckUpdateTime"])); 212 | } 213 | set { 214 | this["LastCheckUpdateTime"] = value; 215 | } 216 | } 217 | 218 | [global::System.Configuration.UserScopedSettingAttribute()] 219 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 220 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 221 | public bool CheckingUpdate { 222 | get { 223 | return ((bool)(this["CheckingUpdate"])); 224 | } 225 | set { 226 | this["CheckingUpdate"] = value; 227 | } 228 | } 229 | 230 | [global::System.Configuration.UserScopedSettingAttribute()] 231 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 232 | [global::System.Configuration.DefaultSettingValueAttribute("")] 233 | public string LatestVersion { 234 | get { 235 | return ((string)(this["LatestVersion"])); 236 | } 237 | set { 238 | this["LatestVersion"] = value; 239 | } 240 | } 241 | 242 | [global::System.Configuration.UserScopedSettingAttribute()] 243 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 244 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 245 | public bool ReplaceSpace { 246 | get { 247 | return ((bool)(this["ReplaceSpace"])); 248 | } 249 | set { 250 | this["ReplaceSpace"] = value; 251 | } 252 | } 253 | 254 | [global::System.Configuration.UserScopedSettingAttribute()] 255 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 256 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 257 | public bool ShowNewVersion { 258 | get { 259 | return ((bool)(this["ShowNewVersion"])); 260 | } 261 | set { 262 | this["ShowNewVersion"] = value; 263 | } 264 | } 265 | 266 | [global::System.Configuration.UserScopedSettingAttribute()] 267 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 268 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 269 | public bool StretchThumbnail { 270 | get { 271 | return ((bool)(this["StretchThumbnail"])); 272 | } 273 | set { 274 | this["StretchThumbnail"] = value; 275 | } 276 | } 277 | 278 | [global::System.Configuration.UserScopedSettingAttribute()] 279 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 280 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 281 | public bool EnableThumbnail { 282 | get { 283 | return ((bool)(this["EnableThumbnail"])); 284 | } 285 | set { 286 | this["EnableThumbnail"] = value; 287 | } 288 | } 289 | } 290 | } 291 | -------------------------------------------------------------------------------- /ApkShellext2/Properties/Resources.zh-TW.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | 123 | 124 | 在 GitHub 上的官方頁面 125 | 126 | 127 | 更新 128 | 129 | 130 | 轉到專案網站以更新 131 | 132 | 133 | 重命名模式 134 | 135 | 136 | 在亞馬遜應用商店檢查 {0} 137 | 138 | 139 | 在蘋果應用商店上檢查 {0} 140 | 141 | 142 | 在 GooglePlay 檢查 {0} 143 | 144 | 145 | 在微軟商店檢查 {0} 146 | 147 | 148 | APK 助手 149 | 150 | 151 | 偏好設置 & & 更新 152 | 153 | 154 | 重命名為 {0} 155 | 156 | 157 | 當選定多個檔案時顯示應用程式商店功能表 158 | 159 | 160 | 如果選中此選項,當多個apk選中時仍然應用程式商店功能表 161 | 請注意,您可能打開大量的瀏覽器視窗並顯著影響性能。 162 | 預設情況下,僅選擇一個檔時顯示功能表 163 | 164 | 165 | 正在檢查新版本... 166 | 167 | 168 | 通過網站檢查更新。 169 | 170 | 171 | 當前版本: {0} 172 | 173 | 174 | 太好了! 你有最新版本 175 | 176 | 177 | 轉到 ApkShellext2 專案網站 178 | 179 | 180 | 語言: 181 | 182 | 183 | 此功能需要 ApkShellextService,請確保服務已啟動。 184 | 185 | 186 | 有新版本 {0} 187 | 188 | 189 | ApkShellext2 首選項 190 | 191 | 192 | 未能讀取檔案 193 | 194 | 195 | 變數用法請參照專案 Wiki 196 | 197 | 198 | 为避免情況的版本相同,但不同的版本號,這最喜歡發生在 android 應用程式檔。 199 | 通過檢查這,否則作為 %Appname%_%Version%_ %Revision %,重命名應用程式檔,使用 %Appname%_ %Version%。 200 | 201 | 202 | 掃描二維碼下載 203 | 204 | 205 | 顯示 WindowsPhone (appx,appxbundle) 的應用程式圖示。 206 | 207 | 208 | 顯示 iOS 應用程式 (ipa) 圖示。 209 | 210 | 211 | 顯示疊加圖示表示不同的作業系統 212 | 213 | 214 | 顯示疊加圖示表示不同的作業系統 215 | 216 | 217 | 顯示內容功能表圖示 218 | 219 | 220 | 取消 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 確認重命名此檔作為 {0} 嗎? 230 | 231 | 232 | 重命名模式: (不帶副檔名) 233 | 234 | 235 | 內容功能表 236 | 237 | 238 | 一般設定 239 | 240 | 241 | 圖示 242 | 243 | 244 | 重命名 245 | 246 | 247 | 資訊提示 248 | 249 | 250 | 在ApkMirror.com檢查 {0} 251 | 252 | 253 | 使用最後保存的模式 254 | 255 | 256 | 在內容功能表中顯示Amazon app store連結 257 | 258 | 259 | 在內容功能表中顯示 ApkMirror 連結 260 | 261 | 262 | 在內容功能表中顯示Apple Store的連結 (ipa) 263 | 264 | 265 | 在內容功能表中顯示GooglePlay連結 266 | 267 | 268 | 在內容功能表中顯示 Microsoft Store 連結 (為 appx/appxbundle) 269 | 270 | 271 | 資訊提示模式: 272 | 273 | 274 | 瀏覽 275 | 276 | 277 | 搜索 278 | 279 | 280 | 請指定的adb.exe路徑 281 | 282 | 283 | 284 | 在內容功能表中提醒新版本 285 | 286 | 287 | 縮略圖 288 | 289 | 290 | 如果 Windows 要求更大的大小拉伸的縮略圖 291 | 292 | 293 | 请幫忙翻譯一下這個專案。 294 | 295 | 296 | 清除圖示和縮略圖的緩存 297 | 298 | 299 | 所有打開的檔瀏覽器將會封閉,是否繼續? 300 | 301 | 302 | 顯示縮略圖而不是圖示。 303 | 304 | 305 | 為了正確顯示圖示和縮略圖,緩存需要被清除,現在清除嗎? 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | -------------------------------------------------------------------------------- /ApkShellext2/Properties/NonLocalizeResources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | taskkill /f /im explorer.exe & cd /d %USERPROFILE%\AppData\Local\Microsoft\Windows\Explorer & attrib -h *.db & del thumbcache_*.db iconcache_*.db & cd /d %USERPROFILE%\AppData\Local & del IconCache.db & start explorer.exe 122 | command for deleting iconcache, force windows to rebuild it 123 | 124 | 125 | %AppName%_%Version% 126 | 127 | 128 | Search in Stores 129 | 130 | 131 | http://www.amazon.com/s?k={0}&i=mobile-apps 132 | 133 | 134 | http://www.apkmirror.com/?s={0}&searchtype=apk 135 | 136 | 137 | http://itunes.apple.com/app/id{0} 138 | 139 | 140 | https://kkguo.github.io/apkshellext 141 | 142 | 143 | https://kkguo.github.io/apkshellext/latest 144 | 145 | 146 | https://kkguo.github.io/apkshellext/index.html?version={0} 147 | 148 | 149 | https://play.google.com/store/search?q={0}&c=apps 150 | 151 | 152 | https://www.windowsphone.com/s?appid={0} 153 | 154 | 155 | https://github.com/kkguo/apkshellext/wiki/Package-information-Pattern-variables 156 | 157 | 158 | https://crowdin.com/project/apkshellext 159 | 160 | 161 | AppID 162 | 163 | 164 | AppName 165 | 166 | 167 | Debuggable 168 | 169 | 170 | FileSize 171 | 172 | 173 | LastModify 174 | 175 | 176 | OS 177 | 178 | 179 | Package 180 | 181 | 182 | Publisher 183 | 184 | 185 | Revision 186 | 187 | 188 | Version 189 | 190 | 191 | 192 | ..\Resources\amazon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 193 | 194 | 195 | ..\Resources\android.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 196 | 197 | 198 | ..\Resources\apkm.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 199 | 200 | 201 | ..\Resources\Apple.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 202 | 203 | 204 | ..\Resources\App-store-icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 205 | 206 | 207 | ..\Resources\GitHub.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 208 | 209 | 210 | ..\Resources\play.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 211 | 212 | 213 | ..\Resources\msft store icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 214 | 215 | 216 | ..\Resources\rename.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 217 | 218 | 219 | ..\Resources\udpate.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 220 | 221 | 222 | ..\Resources\logo.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 223 | 224 | 225 | ..\Resources\QR-Scan.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 226 | 227 | 228 | ..\Resources\windows.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 229 | 230 | 231 | %AppName% 232 | %Package% 233 | Version: %Version% %Revision% 234 | 235 | 236 | Attr\((.*),(.*)\) 237 | 238 | 239 | ..\resources\output.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 240 | 241 | 242 | https://www.patreon.com/apkshellext 243 | 244 | 245 | ..\resources\patreon_mark_coral.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 246 | 247 | --------------------------------------------------------------------------------