10 Commits

Author SHA1 Message Date
AndnixSH 10a1dfed68 Fix keyboard shortcut 2026-06-01 20:16:26 +02:00
AndnixSH 2687452ee7 Remove "full info" string 2026-05-31 20:35:18 +02:00
AndnixSH 5a8e485923 [Vibe coding] Improve icon parsing
No longer connect to web to fetch icon
Parse icon directly from APK without extracting
2026-05-31 20:03:00 +02:00
AndnixSH 5d9d4e21d0 Fixing flags & refactor
Replaced -m with --match-original
Replaced -nc with --no-crunch (#52)
Replaced -k with --keep-broken-res
Replaced -c with --copy-original

All flags are backward compatible
2026-05-31 17:42:29 +02:00
AndnixSH fd7398667e Reduce margin 2026-05-31 16:34:17 +02:00
AndnixSH 59ef98b315 Removed --enable-native-access=ALL-UNNAMED
It's not available on Java 1.8
2026-05-31 16:24:46 +02:00
AndnixSH 351c7887c4 Update README.md 2026-05-31 15:46:50 +02:00
AndnixSH 183c0e584c Move hardcoded string to Language 2026-05-31 15:41:36 +02:00
AndnixSH 725197f615 [Vibe coding] Ported WinForm to WPF
WPF has better theming and performance.
Removed DarkNet package
Merged languages from WinForm to resx
I used AI to port faster.
2026-05-31 12:01:46 +02:00
AndnixSH cc27270d98 Bump version to 3.3.2.3 2026-05-17 22:18:46 +02:00
68 changed files with 8813 additions and 23022 deletions
+37 -78
View File
@@ -8,6 +8,10 @@
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{AA2C8BC1-ED99-463A-9363-F6A87FB2CF38}</ProjectGuid>
<!-- WPF project type GUID first, then C#. Enables XAML markup compilation
(via Microsoft.WinFX.targets) alongside the existing WinForms UI during
the staged WinForms->WPF conversion. -->
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>APKToolGUI</RootNamespace>
@@ -81,9 +85,6 @@
<HintPath>..\packages\Costura.Fody.6.0.0\lib\netstandard2.0\Costura.dll</HintPath>
</Reference>
<Reference Include="CustomMarshalers" />
<Reference Include="DarkNet, Version=2.3.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\DarkNet.2.3.0\lib\net452\DarkNet.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.HashCode, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.HashCode.6.0.0\lib\net462\Microsoft.Bcl.HashCode.dll</HintPath>
</Reference>
@@ -314,44 +315,45 @@
</Compile>
<Compile Include="ApkTool\Adb.cs" />
<Compile Include="ApkTool\Zipalign.cs" />
<Compile Include="Handlers\AdbControlEventHandlers.cs" />
<Compile Include="Handlers\ApkinfoControlEventHandlers.cs" />
<Compile Include="Handlers\BaksmaliControlEventHandlers.cs" />
<Compile Include="Handlers\BuildControlEventHandlers.cs" />
<Compile Include="Handlers\DecodeControlEventHandlers.cs" />
<Compile Include="Handlers\DragDropHandlers.cs" />
<Compile Include="Handlers\FrameworkControlEventHandlers.cs" />
<Compile Include="Handlers\MainWindowEventHandlers.cs" />
<Compile Include="Handlers\MenuItemHandlers.cs" />
<Compile Include="Handlers\SignControlEventHandlers.cs" />
<Compile Include="Handlers\SmaliControlEventHandlers.cs" />
<Compile Include="Handlers\ZipalignControlEventHandlers.cs" />
<Compile Include="Controls\DarkTheme.cs" />
<Compile Include="Controls\NativeDarkMode.cs" />
<Compile Include="Controls\WpfTheme.cs" />
<Compile Include="Controls\NumericUpDown.cs" />
<Compile Include="Controls\LogView.cs" />
<Compile Include="Utils\AdminUtils.cs" />
<Compile Include="Utils\ApkIconExtractor.cs" />
<Compile Include="Utils\BitmapUtils.cs" />
<Compile Include="Utils\CMD.cs" />
<Compile Include="Utils\CommonUtils.cs" />
<Compile Include="Utils\DirectoryUtils.cs" />
<Compile Include="Utils\DragDropUtils.cs" />
<Compile Include="Utils\ExplorerContextMenu.cs" />
<Compile Include="Forms\FormAboutBox.cs">
<SubType>Form</SubType>
<Page Include="Forms\AboutWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="Forms\AboutWindow.xaml.cs">
<DependentUpon>AboutWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\FormAboutBox.Designer.cs">
<DependentUpon>FormAboutBox.cs</DependentUpon>
<Page Include="Forms\SettingsWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="Forms\SettingsWindow.xaml.cs">
<DependentUpon>SettingsWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\FormMain.cs">
<SubType>Form</SubType>
<Page Include="Forms\MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="Forms\MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\FormMain.Designer.cs">
<DependentUpon>FormMain.cs</DependentUpon>
</Compile>
<Compile Include="Forms\FormSettings.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\FormSettings.Designer.cs">
<DependentUpon>FormSettings.cs</DependentUpon>
<Compile Include="Forms\MainWindow.Logic.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
</Compile>
<Page Include="Themes\Controls.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="Java\JarProcess.cs">
<SubType>Component</SubType>
</Compile>
@@ -372,52 +374,6 @@
<Compile Include="Web\WebDownload.cs">
<SubType>Component</SubType>
</Compile>
<EmbeddedResource Include="Forms\FormAboutBox.de.resx">
<DependentUpon>FormAboutBox.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Forms\FormAboutBox.resx">
<DependentUpon>FormAboutBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\FormAboutBox.ru.resx">
<DependentUpon>FormAboutBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\FormAboutBox.zh-CN.resx">
<DependentUpon>FormAboutBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\FormAboutBox.vi-VN.resx">
<DependentUpon>FormAboutBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\FormMain.de.resx">
<DependentUpon>FormMain.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\FormMain.resx">
<DependentUpon>FormMain.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\FormMain.ru.resx">
<DependentUpon>FormMain.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\FormMain.zh-CN.resx">
<DependentUpon>FormMain.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\FormMain.vi-VN.resx">
<DependentUpon>FormMain.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\FormSettings.de.resx">
<DependentUpon>FormSettings.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\FormSettings.resx">
<DependentUpon>FormSettings.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\FormSettings.ru.resx">
<DependentUpon>FormSettings.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\FormSettings.zh-CN.resx">
<DependentUpon>FormSettings.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\FormSettings.vi-VN.resx">
<DependentUpon>FormSettings.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Languages\Language.de.resx" />
<EmbeddedResource Include="Languages\Language.hu.resx" />
<EmbeddedResource Include="Languages\Language.pt-BR.resx" />
@@ -460,7 +416,7 @@
<None Include="Resources\Error.png" />
<None Include="Resources\android-thin.ico" />
<None Include="Resources\Done.png" />
<None Include="Resources\android.png" />
<Resource Include="Resources\android.png" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client">
@@ -486,6 +442,9 @@
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- NOTE: WPF XAML markup compilation (Microsoft.WinFX.targets, for Page / Resource
items) is pulled in automatically because ProjectTypeGuids includes the WPF GUID. -->
<PropertyGroup>
<PreBuildEvent>if not exist "$(ProjectDir)\$(OutDir)\Resources" xcopy "$(SolutionDir)\Tools" "$(ProjectDir)\$(OutDir)\Resources" /Y /I /S</PreBuildEvent>
</PropertyGroup>
+116 -65
View File
@@ -1,4 +1,5 @@
using APKToolGUI.Web;
using Ionic.Zip;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -195,86 +196,136 @@ namespace APKToolGUI.Utils
return apkinfo;
}
public string GetIcon(string apkPath)
// mipmap/drawable density folders to probe when the manifest points at an adaptive XML icon.
private static readonly string[] IconPngFolders =
{
string[] png = { "mipmap-xxxhdpi-v4", "mipmap-xxhdpi-v4", "mipmap-xhdpi-v4", "mipmap-hdpi-v4", "mipmap-mdpi-v4", "mipmap-xhdpi", "mipmap-hdpi", "drawable-xxxhdpi-v4", "drawable-xxhdpi-v4", "drawable-xhdpi-v4", "drawable-hdpi-v4", "drawable-mdpi-v4" };
string icon = "";
"mipmap-xxxhdpi-v4", "mipmap-xxhdpi-v4", "mipmap-xhdpi-v4", "mipmap-hdpi-v4", "mipmap-mdpi-v4",
"mipmap-xhdpi", "mipmap-hdpi",
"drawable-xxxhdpi-v4", "drawable-xxhdpi-v4", "drawable-xhdpi-v4", "drawable-hdpi-v4", "drawable-mdpi-v4"
};
if (!string.IsNullOrEmpty(AppIcon65534))
icon = AppIcon65534;
else if (!string.IsNullOrEmpty(AppIcon640))
icon = AppIcon640;
else if (!string.IsNullOrEmpty(AppIcon480))
icon = AppIcon480;
else if (!string.IsNullOrEmpty(AppIcon320))
icon = AppIcon320;
else if (!string.IsNullOrEmpty(AppIcon240))
icon = AppIcon240;
else if (!string.IsNullOrEmpty(AppIcon160))
icon = AppIcon160;
else if (!string.IsNullOrEmpty(AppIcon120))
icon = AppIcon120;
// Resolves the launcher icon to raw image bytes in memory — nothing is written to disk.
// Resolution order:
// 1) Direct raster lookup inside the (base) APK using the aapt-reported icon path.
// 2) resources.arsc parse — handles optimized/obfuscated resource names and adaptive
// icons (falls back to the foreground-layer raster).
// 3) Split-APK fallback — density resources (incl. the launcher icon) usually live in
// the config.*dpi.apk splits, not base.apk. When a split folder is supplied, scan it.
// Returns the PNG/WebP bytes, or null when no icon could be found.
public byte[] GetIconBytes(string apkPath, string splitSearchFolder = null)
{
try
{
// Pick the largest-density icon aapt reported (precedence: 65534 → 120).
string icon = PickPreferredIcon();
icon = icon.Replace(".xml", ".png");
// Adaptive icons are declared as XML; the real raster lives next to it as a PNG.
if (Path.GetExtension(icon).Equals(".xml", StringComparison.OrdinalIgnoreCase))
icon = icon.Replace(".xml", ".png");
Debug.WriteLine("Icon: " + icon);
Debug.WriteLine("Icon: " + icon);
string cacheDir = Path.Combine(Program.TEMP_PATH, PackageName);
string iconLocation = Path.Combine(cacheDir, Path.GetFileName(icon));
Directory.CreateDirectory(cacheDir);
string[] candidates = BuildIconCandidates(icon);
// 1) Direct raster lookup inside the (base) APK.
byte[] iconBytes = ReadIconFromApk(apkPath, candidates);
// 2) resources.arsc fallback.
if (iconBytes == null)
{
Debug.WriteLine("Falling back to resources.arsc extraction method");
iconBytes = ApkIconExtractor.ExtractIcon(apkPath);
}
// 3) Split-APK fallback: density resources (incl. the launcher icon) usually live
// in config.*dpi.apk splits, not base.apk. Scan the extracted splits.
if (iconBytes == null && !String.IsNullOrEmpty(splitSearchFolder) && Directory.Exists(splitSearchFolder))
{
foreach (string split in Directory.GetFiles(splitSearchFolder, "*.apk", SearchOption.AllDirectories))
{
if (String.Equals(split, apkPath, StringComparison.OrdinalIgnoreCase))
continue; // base.apk already tried above
iconBytes = ReadIconFromApk(split, candidates) ?? ApkIconExtractor.ExtractIcon(split);
if (iconBytes != null)
{
Debug.WriteLine("Icon resolved from split: " + Path.GetFileName(split));
break;
}
}
}
if (iconBytes == null)
Debug.WriteLine("Icon not found in " + Path.GetFileName(apkPath));
return iconBytes;
}
catch (Exception ex)
{
Debug.WriteLine("GetIconBytes failed: " + ex.Message);
return null;
}
}
// Highest-density icon wins; fall back through the precedence chain.
private string PickPreferredIcon()
{
foreach (var candidate in new[] { AppIcon65534, AppIcon640, AppIcon480, AppIcon320, AppIcon240, AppIcon160, AppIcon120 })
{
if (!String.IsNullOrEmpty(candidate))
return candidate;
}
return "";
}
// Expand the chosen icon path into the set of ZIP entries to probe, resolving
// adaptive (v26) icons to their density-specific PNG forms.
private static string[] BuildIconCandidates(string icon)
{
if (String.IsNullOrEmpty(icon))
return new string[0];
if (icon.Contains("anydpi-v26"))
return IconPngFolders
.Select(p => icon.Replace("mipmap-anydpi-v26", p).Replace("drawable-anydpi-v26", p))
.ToArray();
if (icon.Contains("v26"))
return new[] { icon.Replace("v26", "v4"), icon.Replace("-v26", "") };
return new[] { icon };
}
// Reads the first matching candidate entry from an APK/ZIP into a byte[], or null if none.
private static byte[] ReadIconFromApk(string apkFile, string[] candidates)
{
if (String.IsNullOrEmpty(apkFile) || candidates == null || candidates.Length == 0 || !File.Exists(apkFile))
return null;
try
{
foreach (string Png in png)
using (ZipFile zip = ZipFile.Read(apkFile))
{
string icon2 = icon.Replace("mipmap-anydpi-v26", Png).Replace("drawable-anydpi-v26", Png);
ZipUtils.ExtractFile(apkPath, icon2, cacheDir);
if (File.Exists(iconLocation))
foreach (var candidate in candidates)
{
break;
if (String.IsNullOrEmpty(candidate)) continue;
var entry = zip[candidate.Replace('\\', '/')];
if (entry == null) continue;
Debug.WriteLine("Icon stream: " + candidate + " from " + Path.GetFileName(apkFile));
using (var ms = new MemoryStream())
{
entry.Extract(ms);
return ms.ToArray();
}
}
}
}
else if (icon.Contains("v26"))
catch (Exception ex)
{
string icon2 = icon.Replace("v26", "v4");
ZipUtils.ExtractFile(apkPath, icon2, cacheDir);
icon2 = icon.Replace("-v26", "");
ZipUtils.ExtractFile(apkPath, icon2, cacheDir);
Debug.WriteLine("Icon read failed from " + apkFile + ": " + ex.Message);
}
else
{
ZipUtils.ExtractFile(apkPath, icon, cacheDir);
}
if (!File.Exists(iconLocation))
{
try
{
WebDownload w = new WebDownload();
string ps = w.DownloadString("https://play.google.com/store/apps/details?id=" + PackageName);
//File.WriteAllText("R:\\t.txt", ps);
string icondl = Path.Combine(cacheDir, "icon.png");
Directory.CreateDirectory(cacheDir);
w.DownloadFile(StringExt.RegexExtract(@"(?<=\""image\"":\"")(.*?)(?=\"",\"")", ps), icondl);
iconLocation = icondl;
}
catch (System.Net.WebException ex)
{
Debug.WriteLine($"[AaptParser] Failed to download icon from web: {ex.Message}");
// Icon download failure is not critical, use default value
}
catch (IOException ex)
{
Debug.WriteLine($"[AaptParser] Failed to save icon file: {ex.Message}");
}
catch (Exception ex)
{
Debug.WriteLine($"[AaptParser] Unexpected error getting icon: {ex.Message}");
}
}
return iconLocation;
return null;
}
//https://apilevels.com/
+29 -29
View File
@@ -39,93 +39,93 @@ namespace APKToolGUI
static class DecompileKeys
{
//Do not decode sources.
public const string NoSource = " -s";
public const string NoSource = "-s";
//Do not decode resources.
public const string NoResource = " -r";
public const string NoResource = "-r";
//don't write out debug info (.local, .param, .line, etc.)
//The -b flag has been removed from APKtool 3.0.1 and later versions,
//but the --no-debug-info flag is supported in all versions.
public const string NoDebugInfo = " --no-debug-info";
public const string NoDebugInfo = "--no-debug-info";
//Skip changes detection and build all files.
public const string Force = " -f";
public const string Force = "-f";
//Uses framework files located in <dir>.
public const string FrameworkPath = " -p";
public const string FrameworkPath = "-p";
//Use if there was an error and some resources were dropped
public const string KeepBrokenResource = " -k";
public const string KeepBrokenResource = "--keep-broken-res";
//Keeps files to closest to original as possible. Prevents rebuild.
public const string MatchOriginal = " -m";
public const string MatchOriginal = "--match-original";
//The name of folder that gets written. Default is apk.out
public const string OutputDir = " -o";
public const string OutputDir = "-o";
//Only disassemble the main dex classes (classes[0-9]*.dex) in the root.
public const string OnlyMainClasses = " --only-main-classes";
public const string OnlyMainClasses = "--only-main-classes";
//The numeric api-level of the file to generate, e.g. 14 for ICS.
public const string ApiLevel = " -api";
public const string ApiLevel = "-api";
// Sets the number of threads to use.
public const string Jobs = " -j";
public const string Jobs = "-j";
}
static class BuildKeys
{
//Skip changes detection and build all files.
public const string ForceAll = " -f";
public const string ForceAll = "-f";
//opies original AndroidManifest.xml and META-INF. See project page for more info.
public const string CopyOriginal = " -c";
public const string CopyOriginal = "--copy-original";
//Loads aapt from specified location.
public const string Aapt = " -a";
public const string Aapt = "-a";
//Uses framework files located in <dir>.
public const string FrameworkPath = " -p";
public const string FrameworkPath = "-p";
// The name of apk that gets written. Default is dist/name.apk
public const string OutputAppPath = " -o";
public const string OutputAppPath = "-o";
// Disable crunching of resource files during the build step.
public const string NoCrunch = " -nc";
public const string NoCrunch = "--no-crunch";
//The numeric api-level of the file to generate, e.g. 14 for ICS.
public const string ApiLevel = " -api";
public const string ApiLevel = "-api";
//Upgrades apktool to use experimental aapt2 binary.
public const string UseAapt2 = " --use-aapt2";
public const string UseAapt2 = "--use-aapt2";
//Add a generic Network Security Configuration file in the output APK
public const string NetSecConf = " --net-sec-conf";
public const string NetSecConf = "--net-sec-conf";
// Sets the number of threads to use.
public const string Jobs = " -j";
public const string Jobs = "-j";
}
static class InstallFrameworkKeys
{
//Stores framework files into <dir>.
public const string FrameDir = " -p";
public const string FrameDir = "-p";
//Tag frameworks using <tag>.
public const string Tag = " -t";
public const string Tag = "-t";
}
static class EmptyFrameworkKeys
{
//Stores framework files into <dir>.
public const string FrameDir = " -p";
public const string FrameDir = "-p";
//Force delete destination directory.
public const string ForceDelete = " -f";
public const string ForceDelete = "-f";
//Include all framework files regardless of tag. (3.0.1+)
public const string All = " -a";
public const string All = "-a";
}
ApktoolDataReceivedEventHandler onApktoolOutputDataRecieved;
@@ -200,7 +200,7 @@ namespace APKToolGUI
jobs = String.Format("{0} {1}", DecompileKeys.Jobs, Settings.Default.Decode_Jobs);
keyOutputDir = String.Format("{0} \"{1}\"", DecompileKeys.OutputDir, outputDir);
string args = String.Format($"d{keyNoSrc}{keyNoRes}{keyForce}{onlyMainClasses}{noDebugInfo}{keyMatchOriginal}{keyFramePath}{keyKeepBrokenRes}{apiLevel}{jobs}{keyOutputDir} \"{inputPath}\"");
string args = String.Format($"d {keyNoSrc} {keyNoRes} {keyForce} {onlyMainClasses} {noDebugInfo} {keyMatchOriginal} {keyFramePath} {keyKeepBrokenRes} {apiLevel} {jobs} {keyOutputDir} \"{inputPath}\"");
Log.d("Apktool CMD: " + JarPath + " " + args);
@@ -237,7 +237,7 @@ namespace APKToolGUI
netSecConf = BuildKeys.NetSecConf;
keyOutputAppPath = String.Format("{0} \"{1}\"", BuildKeys.OutputAppPath, outputFile);
string args = String.Format($"b{keyForceAll}{keyAapt}{keyCopyOriginal}{noCrunch}{keyFramePath}{apiLevel}{jobs}{useAapt2}{netSecConf}{keyOutputAppPath} \"{inputFolder}\"");
string args = String.Format($"b {keyForceAll} {keyAapt} {keyCopyOriginal} {noCrunch} {keyFramePath} {apiLevel} {jobs} {useAapt2} {netSecConf} {keyOutputAppPath} \"{inputFolder}\"");
Log.d("Apktool CMD: " + JarPath + " " + args);
@@ -258,7 +258,7 @@ namespace APKToolGUI
if (Settings.Default.InstallFramework_UseTag)
keyTag = String.Format("{0} \"{1}\"", InstallFrameworkKeys.Tag, Settings.Default.InstallFramework_Tag);
string args = String.Format($"if{keyFrameDir}{keyTag} \"{inputPath}\"");
string args = String.Format($"if {keyFrameDir} {keyTag} \"{inputPath}\"");
Log.d("Apktool CMD: " + JarPath + " " + args);
-257
View File
@@ -1,257 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls.Primitives;
using System.Windows.Forms;
namespace APKToolGUI.Controls
{
internal class DarkTheme
{
public static Color bgColor = Color.FromArgb(32, 32, 32);
public static Color txtBoxColor = Color.FromArgb(64, 64, 64);
public static Color btnColor = Color.FromArgb(51, 51, 51);
public static Color btnBorderColor = Color.FromArgb(155, 155, 155);
public static Color tabBorderColor = Color.FromArgb(45, 45, 45);
public static Color menuItemHoverColor = Color.FromArgb(51, 51, 51);
public static Color menuItemSelectedColor = Color.FromArgb(41, 41, 41);
public static Color separatorColor = Color.FromArgb(62, 62, 62);
public static void SetTheme(Control.ControlCollection container, Form form)
{
form.BackColor = bgColor;
form.ForeColor = Color.White;
foreach (Control component in container)
{
Debug.WriteLine(component.GetType());
component.BackColor = bgColor;
component.ForeColor = Color.White;
SetThemeTabControl(component, container);
}
}
public static void SetThemeTabControl(Control component, Control.ControlCollection container)
{
if (component is SplitContainer)
{
foreach (Control control in component.Controls)
{
SetThemeTabControl(control, container);
}
}
if (component is TabControl)
{
((TabControl)component).DrawMode = TabDrawMode.OwnerDrawFixed;
foreach (Control tabControl in component.Controls)
{
SetThemeTabControl(tabControl, container);
//Debug.WriteLine("tabPage " + tabControl.GetType());
((TabControl)component).DrawItem += (sender, e) =>
{
// Set Border header
e.Graphics.FillRectangle(new SolidBrush(tabBorderColor), e.Bounds);
Rectangle paddedBounds = e.Bounds;
paddedBounds.Inflate(0, 0);
// Set the rectangle for the tab button
Rectangle tabRect = ((TabControl)component).GetTabRect(e.Index);
// Draw the border color
using (Pen borderPen = new Pen(tabBorderColor, 7))
{
e.Graphics.DrawRectangle(borderPen, tabRect);
}
StringFormat stringFlags = new StringFormat();
stringFlags.Alignment = StringAlignment.Center;
stringFlags.LineAlignment = StringAlignment.Center;
e.Graphics.DrawString(((TabControl)component).TabPages[e.Index].Text, FormMain.Instance.Font, SystemBrushes.HighlightText, tabRect, stringFlags);
//set Tabcontrol border
Graphics g = e.Graphics;
Pen p = new Pen(tabBorderColor, 8);
g.DrawRectangle(p, tabControl.Bounds.X, tabControl.Bounds.Y, tabControl.Bounds.Width, tabControl.Bounds.Height);
SolidBrush fillbrush = new SolidBrush(bgColor);
//draw rectangle behind the tabs
Rectangle lasttabrect = ((TabControl)component).GetTabRect(((TabControl)component).TabPages.Count - 1);
Rectangle background = new Rectangle();
background.Location = new Point(lasttabrect.Right, 0);
//pad the rectangle to cover the 1 pixel line between the top of the tabpage and the start of the tabs
background.Size = new Size(((TabControl)component).Right - background.Left, lasttabrect.Height + 1);
e.Graphics.FillRectangle(fillbrush, background);
};
foreach (Control tabPage in tabControl.Controls)
{
SetThemeTabControl(tabPage, container);
}
}
}
else if (component is Panel)
{
foreach (Control control in component.Controls)
{
SetThemeTabControl(control, container);
}
component.BackColor = bgColor;
component.ForeColor = Color.White;
}
if (component is MenuStrip menuStrip)
{
((MenuStrip)component).Renderer = new ToolStripProfessionalRenderer(new MenuItemColorTable());
foreach (ToolStripItem item in menuStrip.Items)
{
if (item is ToolStripMenuItem toolStripMenuItem)
{
foreach (ToolStripMenuItem dditem in toolStripMenuItem.DropDownItems.OfType<ToolStripMenuItem>())
{
dditem.BackColor = bgColor;
dditem.ForeColor = Color.White;
//Debug.WriteLine(dditem.Text);
}
foreach (ToolStripSeparator toolStripSeparator in toolStripMenuItem.DropDownItems.OfType<ToolStripSeparator>())
{
toolStripSeparator.BackColor = Color.Blue;
toolStripSeparator.ForeColor = Color.Blue;
Debug.WriteLine(toolStripSeparator.Name);
}
toolStripMenuItem.BackColor = bgColor;
toolStripMenuItem.ForeColor = Color.White;
}
}
}
else if (component is GroupBox)
{
foreach (Control control in component.Controls)
{
SetThemeTabControl(control, container);
}
component.BackColor = bgColor;
component.ForeColor = Color.White;
}
else if (component is ComboBox)
{
component.BackColor = bgColor;
component.ForeColor = Color.White;
((ComboBox)component).FlatStyle = FlatStyle.Flat;
}
else if (component is Button)
{
component.BackColor = btnColor;
component.ForeColor = Color.White;
((Button)component).FlatStyle = FlatStyle.Flat;
((Button)component).FlatAppearance.BorderColor = btnBorderColor;
}
else if (component is TextBox)
{
component.BackColor = txtBoxColor;
component.ForeColor = Color.White;
((TextBox)component).BorderStyle = BorderStyle.FixedSingle;
}
else if (component is RichTextBox)
{
if (component.Name == "logTxtBox")
((RichTextBox)component).BorderStyle = BorderStyle.None;
component.BackColor = bgColor;
component.ForeColor = Color.White;
}
else
{
component.BackColor = bgColor;
component.ForeColor = Color.White;
}
}
public class MenuItemColorTable : ProfessionalColorTable
{
/// <summary>
/// Gets the starting color of the gradient used when
/// a top-level System.Windows.Forms.ToolStripMenuItem is pressed.
/// </summary>
public override Color MenuItemPressedGradientBegin => menuItemSelectedColor;
/// <summary>
/// Gets the end color of the gradient used when a top-level
/// System.Windows.Forms.ToolStripMenuItem is pressed.
/// </summary>
public override Color MenuItemPressedGradientEnd => menuItemSelectedColor;
/// <summary>
/// Gets the border color to use with a
/// System.Windows.Forms.ToolStripMenuItem.
/// </summary>
public override Color MenuItemBorder => menuItemSelectedColor;
/// <summary>
/// Gets the starting color of the gradient used when the
/// System.Windows.Forms.ToolStripMenuItem is selected.
/// </summary>
public override Color MenuItemSelectedGradientBegin => menuItemSelectedColor;
/// <summary>
/// Gets the end color of the gradient used when the
/// System.Windows.Forms.ToolStripMenuItem is selected.
/// </summary>
public override Color MenuItemSelectedGradientEnd => menuItemSelectedColor;
/// <summary>
/// Gets the border color to use with a
/// System.Windows.Forms.ToolStripMenuItem.
/// </summary>
public override Color MenuItemSelected => menuItemHoverColor;
/// <summary>
/// Gets the solid background color of the
/// System.Windows.Forms.ToolStripDropDown.
/// </summary>
public override Color ToolStripDropDownBackground => bgColor;
/// <summary>
/// Gets the starting color of the gradient used in the image
/// margin of a System.Windows.Forms.ToolStripDropDownMenu.
/// </summary>
public override Color ImageMarginGradientBegin => bgColor;
/// <summary>
/// Gets the middle color of the gradient used in the image
/// margin of a System.Windows.Forms.ToolStripDropDownMenu.
/// </summary>
public override Color ImageMarginGradientMiddle => bgColor;
/// <summary>
/// Gets the end color of the gradient used in the image
/// margin of a System.Windows.Forms.ToolStripDropDownMenu.
/// </summary>
public override Color ImageMarginGradientEnd => bgColor;
/// <summary>
/// Gets the color to use to for shadow effects on
/// the System.Windows.Forms.ToolStripSeparator.
/// </summary>
public override Color SeparatorDark => separatorColor;
/// <summary>
/// Gets the color that is the border color to use
/// on a System.Windows.Forms.MenuStrip.
/// </summary>
public override Color MenuBorder => menuItemHoverColor;
}
}
}
+989
View File
@@ -0,0 +1,989 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
namespace APKToolGUI.Controls
{
/// <summary>
/// A virtualized, monospace, console-style log view that replaces the old <see cref="RichTextBox"/>.
///
/// Why it exists: RichTextBox renders a FlowDocument, which is NOT UI-virtualized — every line is a live
/// layout element and any change re-measures the whole document on the UI thread (O(total lines)), which
/// froze the GUI once the log held thousands of lines. This control keeps lines in a ring buffer and only
/// draws the visual rows currently on screen (OnRender + FormattedText), so cost is O(visible).
///
/// Monospace (Consolas) makes the geometry trivial: column = (x - padding) / charWidth, and the word-wrap
/// column is just viewportWidth / charWidth. Word wrap turns one logical line into several "visual rows";
/// selection is stored in logical (line, column) coordinates so it survives re-wrapping on resize.
///
/// It implements <see cref="IScrollInfo"/> so a host <see cref="ScrollViewer"/> (CanContentScroll=True)
/// drives scrolling and the scrollbars.
/// </summary>
public sealed class LogView : FrameworkElement, IScrollInfo
{
/// <summary>One coloured (optionally clickable) run of text within a line.</summary>
public sealed class Segment
{
public string Text;
public Brush Foreground;
public bool Bold;
public Action OnClick; // null => plain text; non-null => hyperlink
public Segment(string text, Brush foreground = null, bool bold = false, Action onClick = null)
{
Text = text ?? string.Empty;
Foreground = foreground;
Bold = bold;
OnClick = onClick;
}
}
private sealed class Line
{
public readonly Segment[] Segments;
public readonly int Length; // total character count across segments
// Wrap cache: start column of each visual row, for the wrap width it was computed at.
public int[] RowStarts;
public int WrapCols = int.MinValue;
public Line(Segment[] segments)
{
Segments = segments;
int len = 0;
for (int i = 0; i < segments.Length; i++)
len += segments[i].Text.Length;
Length = len;
}
public string GetText()
{
if (Segments.Length == 1)
return Segments[0].Text;
StringBuilder sb = new StringBuilder(Length);
for (int i = 0; i < Segments.Length; i++)
sb.Append(Segments[i].Text);
return sb.ToString();
}
}
// Bounded scrollback. Lines are trimmed from the front once the buffer grows past MaxLines + TrimSlack,
// in one bulk RemoveRange so trimming is amortised O(1) per line.
public const int MaxLines = 32767;
private const int TrimSlack = 4096;
// Tab stop width in characters. Tabs are expanded to spaces on input so the buffer is truly fixed-width
// (a raw '\t' renders as a wide gap that desyncs the charWidth-based geometry). 8 matches the tab stops
// the existing log strings were authored for (e.g. AaptParser's "App name:\t\t" → column 24).
private const int TabSize = 8;
private const double LeftPadding = 3.0;
private static readonly int[] SingleRow = new int[] { 0 };
private readonly List<Line> _lines = new List<Line>();
// Wrap/visual-row layout (rebuilt lazily; kept live incrementally on append).
private bool _wrapText = true;
private readonly List<int> _rowOffsets = new List<int>(); // _rowOffsets[i] = visual rows before line i
private int _totalRows;
private int _maxLineLen;
private bool _layoutBuilt;
private bool _layoutDirty;
private int _layoutWrapCols = int.MinValue;
private readonly List<int> _wrapScratch = new List<int>();
// Cached font metrics (recomputed when font/dpi changes). Monospace => one char width fits all.
private Typeface _typeface;
private Typeface _boldTypeface;
private double _charWidth;
private double _lineHeight;
private double _pixelsPerDip = 1.0;
private bool _metricsValid;
// Selection, expressed as (line, column) caret positions. Anchor is where the drag began.
private struct Pos
{
public int Line;
public int Col;
public Pos(int line, int col) { Line = line; Col = col; }
public int CompareTo(Pos o)
{
if (Line != o.Line) return Line < o.Line ? -1 : 1;
if (Col != o.Col) return Col < o.Col ? -1 : 1;
return 0;
}
}
private Pos _selAnchor;
private Pos _selCaret;
private bool _hasSelection;
private bool _selecting; // mouse drag in progress
private Point _mouseDownPoint; // to distinguish click from drag (hyperlinks)
// One active search highlight (logical line/col/length), or _searchLine < 0 for none.
private int _searchLine = -1;
private int _searchCol;
private int _searchLen;
// Auto-scroll: stay pinned to the bottom unless the user scrolls up.
private bool _stickToBottom = true;
private static readonly Brush SelectionBrush = new SolidColorBrush(Color.FromArgb(120, 51, 153, 255));
private static readonly Brush SearchBrush = new SolidColorBrush(Color.FromRgb(38, 79, 120));
private static readonly Brush LinkBrush = new SolidColorBrush(Color.FromRgb(60, 166, 255)); // old #FF3CA6FF
static LogView()
{
SelectionBrush.Freeze();
SearchBrush.Freeze();
LinkBrush.Freeze();
}
public LogView()
{
Focusable = true;
ClipToBounds = true;
Cursor = Cursors.IBeam;
TextOptions.SetTextFormattingMode(this, TextFormattingMode.Display);
SnapsToDevicePixels = true;
FocusVisualStyle = null;
// Routed commands so Ctrl+C / Ctrl+A work via the command system (in addition to OnKeyDown),
// and so the context menu items can bind to them and show their gestures.
CommandBindings.Add(new CommandBinding(ApplicationCommands.Copy,
(s, e) => { CopySelection(); e.Handled = true; },
(s, e) => { e.CanExecute = HasSelection; }));
CommandBindings.Add(new CommandBinding(ApplicationCommands.SelectAll,
(s, e) => { SelectAll(); e.Handled = true; },
(s, e) => { e.CanExecute = _lines.Count > 0; }));
BuildContextMenu();
}
private void BuildContextMenu()
{
ContextMenu menu = new ContextMenu();
MenuItem copy = new MenuItem { Header = "Copy", Command = ApplicationCommands.Copy, CommandTarget = this };
MenuItem copyAll = new MenuItem { Header = "Copy all" };
copyAll.Click += (s, e) => CopyAll();
MenuItem selectAll = new MenuItem { Header = "Select all", Command = ApplicationCommands.SelectAll, CommandTarget = this };
menu.Items.Add(copy);
menu.Items.Add(copyAll);
menu.Items.Add(new Separator());
menu.Items.Add(selectAll);
ContextMenu = menu;
}
/// <summary>When true (default), long lines wrap to the viewport width; when false they're one row each.</summary>
public bool WrapText
{
get { return _wrapText; }
set
{
if (_wrapText == value) return;
_wrapText = value;
_canHScroll = !value;
_layoutDirty = true;
InvalidateMeasure();
InvalidateVisual();
}
}
#region Appearance dependency properties
public static readonly DependencyProperty FontFamilyProperty = DependencyProperty.Register(
nameof(FontFamily), typeof(FontFamily), typeof(LogView),
new FrameworkPropertyMetadata(new FontFamily("Consolas"),
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
OnFontChanged));
public static readonly DependencyProperty FontSizeProperty = DependencyProperty.Register(
nameof(FontSize), typeof(double), typeof(LogView),
new FrameworkPropertyMetadata(13.0,
FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender,
OnFontChanged));
public static readonly DependencyProperty ForegroundProperty = DependencyProperty.Register(
nameof(Foreground), typeof(Brush), typeof(LogView),
new FrameworkPropertyMetadata(Brushes.White, FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty BackgroundProperty = DependencyProperty.Register(
nameof(Background), typeof(Brush), typeof(LogView),
new FrameworkPropertyMetadata(Brushes.Transparent, FrameworkPropertyMetadataOptions.AffectsRender));
public FontFamily FontFamily { get { return (FontFamily)GetValue(FontFamilyProperty); } set { SetValue(FontFamilyProperty, value); } }
public double FontSize { get { return (double)GetValue(FontSizeProperty); } set { SetValue(FontSizeProperty, value); } }
public Brush Foreground { get { return (Brush)GetValue(ForegroundProperty); } set { SetValue(ForegroundProperty, value); } }
public Brush Background { get { return (Brush)GetValue(BackgroundProperty); } set { SetValue(BackgroundProperty, value); } }
private static void OnFontChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
LogView v = (LogView)d;
v._metricsValid = false;
v._layoutDirty = true;
}
#endregion
#region Metrics
private void EnsureMetrics()
{
if (_metricsValid)
return;
FontFamily family = FontFamily ?? new FontFamily("Consolas");
_typeface = new Typeface(family, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);
_boldTypeface = new Typeface(family, FontStyles.Normal, FontWeights.Bold, FontStretches.Normal);
try { _pixelsPerDip = VisualTreeHelper.GetDpi(this).PixelsPerDip; }
catch { _pixelsPerDip = 1.0; }
FormattedText probe = MakeText("0", _typeface, Brushes.White);
_charWidth = probe.WidthIncludingTrailingWhitespace;
if (_charWidth <= 0) _charWidth = FontSize * 0.6;
_lineHeight = Math.Ceiling(probe.Height);
if (_lineHeight <= 0) _lineHeight = Math.Ceiling(FontSize * 1.4);
_metricsValid = true;
}
private FormattedText MakeText(string text, Typeface tf, Brush brush)
{
return new FormattedText(text, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight,
tf, FontSize, brush ?? Foreground ?? Brushes.White, _pixelsPerDip);
}
#endregion
#region Wrap / visual-row layout
private int ComputeWrapCols()
{
if (!_wrapText || _charWidth <= 0)
return int.MaxValue; // one row per line
double avail = _viewport.Width - LeftPadding * 2;
if (avail < _charWidth)
return _viewport.Width <= 0 ? int.MaxValue : 1;
return Math.Max(1, (int)Math.Floor(avail / _charWidth));
}
private int[] WrapLine(Line line, int wrapCols)
{
if (wrapCols <= 0 || line.Length <= wrapCols)
return SingleRow;
string t = line.GetText();
int n = t.Length;
List<int> rows = _wrapScratch;
rows.Clear();
rows.Add(0);
int pos = 0;
while (pos + wrapCols < n)
{
int limit = pos + wrapCols;
int br = -1;
for (int k = limit; k > pos; k--)
if (t[k] == ' ') { br = k; break; }
int next = (br > pos) ? br + 1 : limit; // break after the space, else hard break
if (next <= pos) next = pos + 1;
rows.Add(next);
pos = next;
}
return rows.ToArray();
}
private void EnsureWrapped(Line line, int wrapCols)
{
if (line.RowStarts != null && line.WrapCols == wrapCols)
return;
line.RowStarts = WrapLine(line, wrapCols);
line.WrapCols = wrapCols;
}
private void EnsureLayout()
{
EnsureMetrics();
int wrapCols = ComputeWrapCols();
if (_layoutBuilt && !_layoutDirty && wrapCols == _layoutWrapCols)
return;
_rowOffsets.Clear();
int total = 0;
int maxLen = 0;
for (int i = 0; i < _lines.Count; i++)
{
_rowOffsets.Add(total);
Line ln = _lines[i];
EnsureWrapped(ln, wrapCols);
total += ln.RowStarts.Length;
if (ln.Length > maxLen) maxLen = ln.Length;
}
_totalRows = total;
_maxLineLen = maxLen;
_layoutWrapCols = wrapCols;
_layoutDirty = false;
_layoutBuilt = true;
}
private void RowToLine(int visualRow, out int line, out int rowInLine)
{
int count = _lines.Count;
int lo = 0, hi = count - 1, ans = 0;
while (lo <= hi)
{
int mid = (lo + hi) >> 1;
if (_rowOffsets[mid] <= visualRow) { ans = mid; lo = mid + 1; }
else hi = mid - 1;
}
line = ans;
rowInLine = visualRow - _rowOffsets[ans];
}
private static void RowRange(Line line, int rowInLine, out int start, out int end)
{
start = line.RowStarts[rowInLine];
end = (rowInLine + 1 < line.RowStarts.Length) ? line.RowStarts[rowInLine + 1] : line.Length;
}
private double ExtentWidthValue
{
get { return _wrapText ? _viewport.Width : (LeftPadding * 2 + _maxLineLen * _charWidth); }
}
#endregion
#region Public log API
public void AppendLine(string text, Brush color = null, bool bold = false)
{
AddSegments(new[] { new Segment(text ?? string.Empty, color, bold) });
}
public void AppendSegments(IList<Segment> segments)
{
if (segments == null || segments.Count == 0) { AddSegments(new[] { new Segment(string.Empty) }); return; }
Segment[] arr = new Segment[segments.Count];
for (int i = 0; i < segments.Count; i++) arr[i] = segments[i];
AddSegments(arr);
}
public void SetText(string text)
{
Clear();
AppendLine(text);
}
public void Clear()
{
_lines.Clear();
_rowOffsets.Clear();
_totalRows = 0;
_maxLineLen = 0;
_layoutBuilt = false;
_layoutDirty = true;
_hasSelection = false;
_selecting = false;
_searchLine = -1;
_stickToBottom = true;
_offset = new Vector(0, 0);
InvalidateMeasure();
InvalidateVisual();
if (ScrollOwner != null) ScrollOwner.InvalidateScrollInfo();
}
public string GetText()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < _lines.Count; i++)
{
if (i > 0) sb.Append("\r\n");
sb.Append(_lines[i].GetText());
}
return sb.ToString();
}
public int LineCount { get { return _lines.Count; } }
public string GetLineText(int index)
{
return (index >= 0 && index < _lines.Count) ? _lines[index].GetText() : string.Empty;
}
private static string StripCr(string s)
{
return s.IndexOf('\r') >= 0 ? s.Replace("\r", string.Empty) : s;
}
// Single normalization point for ALL appends (plain text, bold, and hyperlink lines, whether they
// arrive via the batched RichBox pipeline or directly). Splits embedded '\n' into separate visual
// lines (otherwise FormattedText would draw several lines stacked inside one row's height — the
// "overlapping text" bug), strips '\r', and expands tabs.
private void AddSegments(Segment[] segments)
{
bool hasNl = false;
for (int i = 0; i < segments.Length; i++)
if (segments[i].Text.IndexOf('\n') >= 0) { hasNl = true; break; }
if (!hasNl)
{
AddLine(new Line(ExpandTabs(StripCrSegments(segments))));
return;
}
List<Segment> cur = new List<Segment>();
for (int i = 0; i < segments.Length; i++)
{
Segment s = segments[i];
string[] parts = s.Text.Split('\n');
for (int p = 0; p < parts.Length; p++)
{
if (p > 0)
{
AddLine(new Line(ExpandTabs(cur.ToArray())));
cur.Clear();
}
string piece = StripCr(parts[p]);
if (piece.Length > 0)
cur.Add(new Segment(piece, s.Foreground, s.Bold, s.OnClick));
}
}
AddLine(new Line(ExpandTabs(cur.ToArray())));
}
private static Segment[] StripCrSegments(Segment[] segments)
{
bool hasCr = false;
for (int i = 0; i < segments.Length; i++)
if (segments[i].Text.IndexOf('\r') >= 0) { hasCr = true; break; }
if (!hasCr) return segments;
Segment[] result = new Segment[segments.Length];
for (int i = 0; i < segments.Length; i++)
{
Segment s = segments[i];
result[i] = s.Text.IndexOf('\r') >= 0
? new Segment(StripCr(s.Text), s.Foreground, s.Bold, s.OnClick)
: s;
}
return result;
}
private static Segment[] ExpandTabs(Segment[] segments)
{
bool hasTab = false;
for (int i = 0; i < segments.Length; i++)
if (segments[i].Text.IndexOf('\t') >= 0) { hasTab = true; break; }
if (!hasTab) return segments;
Segment[] result = new Segment[segments.Length];
int col = 0;
for (int i = 0; i < segments.Length; i++)
{
Segment s = segments[i];
if (s.Text.IndexOf('\t') < 0) { result[i] = s; col += s.Text.Length; continue; }
StringBuilder sb = new StringBuilder(s.Text.Length + 8);
for (int c = 0; c < s.Text.Length; c++)
{
char ch = s.Text[c];
if (ch == '\t')
{
int spaces = TabSize - (col % TabSize);
sb.Append(' ', spaces);
col += spaces;
}
else { sb.Append(ch); col++; }
}
result[i] = new Segment(sb.ToString(), s.Foreground, s.Bold, s.OnClick);
}
return result;
}
private void AddLine(Line line)
{
_lines.Add(line);
if (_lines.Count > MaxLines + TrimSlack)
{
int remove = _lines.Count - MaxLines;
_lines.RemoveRange(0, remove);
ShiftAfterTrim(remove);
_layoutDirty = true; // front removed: rebuild prefix table
}
if (line.Length > _maxLineLen) _maxLineLen = line.Length;
// Keep the visual-row layout live incrementally when it's valid, so autoscroll and the scrollbar
// stay correct without an O(n) rebuild per line. Otherwise mark it for a lazy rebuild.
if (_layoutBuilt && !_layoutDirty)
{
_rowOffsets.Add(_totalRows);
EnsureWrapped(line, _layoutWrapCols);
_totalRows += line.RowStarts.Length;
}
else
{
_layoutDirty = true;
}
InvalidateMeasure();
InvalidateVisual();
if (ScrollOwner != null) ScrollOwner.InvalidateScrollInfo();
// Pin to the bottom immediately using the live row count.
if (_stickToBottom && !HasSelection && _viewport.Height > 0 && _lineHeight > 0)
{
EnsureLayout();
double maxY = Math.Max(0, _totalRows * _lineHeight - _viewport.Height);
if (Math.Abs(maxY - _offset.Y) > 0.001)
{
_offset.Y = maxY;
if (ScrollOwner != null) ScrollOwner.InvalidateScrollInfo();
InvalidateVisual();
}
}
}
private void ShiftAfterTrim(int removedLines)
{
if (_searchLine >= 0)
{
_searchLine -= removedLines;
if (_searchLine < 0) _searchLine = -1;
}
if (_hasSelection)
{
_selAnchor.Line -= removedLines;
_selCaret.Line -= removedLines;
if (_selAnchor.Line < 0 || _selCaret.Line < 0)
_hasSelection = false;
}
}
#endregion
#region Search support
public void SetSearchHighlight(int line, int col, int length)
{
_searchLine = line;
_searchCol = col;
_searchLen = length;
InvalidateVisual();
}
public void ClearSearchHighlight()
{
_searchLine = -1;
InvalidateVisual();
}
/// <summary>Scroll so the given logical line sits roughly in the middle of the viewport.</summary>
public void ScrollLineIntoView(int line)
{
if (line < 0) return;
EnsureLayout();
if (line >= _rowOffsets.Count) return;
double target = _rowOffsets[line] * _lineHeight - _viewport.Height / 2;
SetVerticalOffset(target);
}
#endregion
#region Rendering
protected override void OnRender(DrawingContext dc)
{
EnsureLayout();
double w = RenderSize.Width, h = RenderSize.Height;
dc.DrawRectangle(Background ?? Brushes.Transparent, null, new Rect(0, 0, w, h));
if (_lines.Count == 0 || _lineHeight <= 0 || _totalRows == 0)
return;
int firstRow = (int)Math.Floor(_offset.Y / _lineHeight);
int lastRow = (int)Math.Ceiling((_offset.Y + h) / _lineHeight);
if (firstRow < 0) firstRow = 0;
if (lastRow > _totalRows) lastRow = _totalRows;
Pos selLo = default(Pos), selHi = default(Pos);
bool hasSel = _hasSelection && _selAnchor.CompareTo(_selCaret) != 0;
if (hasSel)
{
if (_selAnchor.CompareTo(_selCaret) <= 0) { selLo = _selAnchor; selHi = _selCaret; }
else { selLo = _selCaret; selHi = _selAnchor; }
}
double baseX = LeftPadding - _offset.X;
int line, rowInLine;
RowToLine(firstRow, out line, out rowInLine);
for (int vr = firstRow; vr < lastRow; vr++)
{
// Advance to the line owning this visual row.
while (line < _lines.Count - 1 && vr >= _rowOffsets[line] + _lines[line].RowStarts.Length)
{
line++;
rowInLine = 0;
}
rowInLine = vr - _rowOffsets[line];
Line ln = _lines[line];
int rs, re;
RowRange(ln, rowInLine, out rs, out re);
double y = vr * _lineHeight - _offset.Y;
// Selection highlight (logical columns intersected with this row).
if (hasSel && line >= selLo.Line && line <= selHi.Line)
{
int from = (line == selLo.Line) ? selLo.Col : 0;
int to = (line == selHi.Line) ? selHi.Col : ln.Length;
int a = Math.Max(from, rs), b = Math.Min(to, re);
if (b > a)
dc.DrawRectangle(SelectionBrush, null,
new Rect(baseX + (a - rs) * _charWidth, y, (b - a) * _charWidth, _lineHeight));
}
// Search highlight.
if (_searchLine == line && _searchLen > 0)
{
int a = Math.Max(_searchCol, rs), b = Math.Min(_searchCol + _searchLen, re);
if (b > a)
dc.DrawRectangle(SearchBrush, null,
new Rect(baseX + (a - rs) * _charWidth, y, (b - a) * _charWidth, _lineHeight));
}
// Text: draw each segment piece that overlaps this row's [rs, re).
Segment[] segs = ln.Segments;
int segCol = 0;
for (int s = 0; s < segs.Length; s++)
{
Segment seg = segs[s];
int segStart = segCol;
int segEnd = segCol + seg.Text.Length;
segCol = segEnd;
int a = Math.Max(segStart, rs), b = Math.Min(segEnd, re);
if (b <= a) continue;
string sub = seg.Text.Substring(a - segStart, b - a);
bool isLink = seg.OnClick != null;
Brush brush = isLink ? LinkBrush : (seg.Foreground ?? Foreground ?? Brushes.White);
Typeface tf = seg.Bold ? _boldTypeface : _typeface;
double x = baseX + (a - rs) * _charWidth;
dc.DrawText(MakeText(sub, tf, brush), new Point(x, y));
if (isLink)
{
double uy = y + _lineHeight - 1.5;
dc.DrawLine(new Pen(brush, 1.0), new Point(x, uy), new Point(x + (b - a) * _charWidth, uy));
}
}
}
}
protected override Size MeasureOverride(Size availableSize)
{
EnsureMetrics();
double vw = double.IsInfinity(availableSize.Width) ? 0 : availableSize.Width;
double vh = double.IsInfinity(availableSize.Height) ? 0 : availableSize.Height;
_viewport = new Size(vw, vh);
EnsureLayout();
VerifyScrollData(_viewport, new Size(ExtentWidthValue, _totalRows * _lineHeight));
return new Size(vw, vh);
}
protected override Size ArrangeOverride(Size finalSize)
{
EnsureMetrics();
_viewport = finalSize;
EnsureLayout();
VerifyScrollData(finalSize, new Size(ExtentWidthValue, _totalRows * _lineHeight));
return finalSize;
}
#endregion
#region Mouse / keyboard interaction
private bool PointToLineCol(Point p, out int line, out int col)
{
line = 0; col = 0;
EnsureLayout();
if (_lines.Count == 0 || _lineHeight <= 0 || _totalRows == 0)
return false;
int vr = (int)Math.Floor((p.Y + _offset.Y) / _lineHeight);
if (vr < 0) vr = 0;
if (vr >= _totalRows) vr = _totalRows - 1;
int rowInLine;
RowToLine(vr, out line, out rowInLine);
int rs, re;
RowRange(_lines[line], rowInLine, out rs, out re);
int colInRow = (int)Math.Round((p.X - LeftPadding + _offset.X) / _charWidth);
if (colInRow < 0) colInRow = 0;
col = rs + colInRow;
if (col > re) col = re;
if (col > _lines[line].Length) col = _lines[line].Length;
return true;
}
private Pos PointToPos(Point p)
{
int line, col;
PointToLineCol(p, out line, out col);
return new Pos(line, col);
}
private Action HitTestLink(Point p)
{
EnsureLayout();
if (_lines.Count == 0 || _lineHeight <= 0 || _totalRows == 0)
return null;
int vr = (int)Math.Floor((p.Y + _offset.Y) / _lineHeight);
if (vr < 0 || vr >= _totalRows) return null;
int line, rowInLine;
RowToLine(vr, out line, out rowInLine);
int rs, re;
RowRange(_lines[line], rowInLine, out rs, out re);
int colInRow = (int)Math.Floor((p.X - LeftPadding + _offset.X) / _charWidth);
if (colInRow < 0) return null;
int col = rs + colInRow;
if (col >= re || col >= _lines[line].Length) return null;
int segCol = 0;
Segment[] segs = _lines[line].Segments;
for (int s = 0; s < segs.Length; s++)
{
int len = segs[s].Text.Length;
if (col >= segCol && col < segCol + len)
return segs[s].OnClick;
segCol += len;
}
return null;
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
Point p = e.GetPosition(this);
if (_selecting && e.LeftButton == MouseButtonState.Pressed)
{
_selCaret = PointToPos(p);
_hasSelection = true;
if (p.Y < 0) SetVerticalOffset(_offset.Y - _lineHeight);
else if (p.Y > RenderSize.Height) SetVerticalOffset(_offset.Y + _lineHeight);
InvalidateVisual();
return;
}
Cursor = HitTestLink(p) != null ? Cursors.Hand : Cursors.IBeam;
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
Keyboard.Focus(this);
_mouseDownPoint = e.GetPosition(this);
_selAnchor = _selCaret = PointToPos(_mouseDownPoint);
_hasSelection = false;
_selecting = true;
CaptureMouse();
InvalidateVisual();
}
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonUp(e);
_selecting = false;
ReleaseMouseCapture();
Point p = e.GetPosition(this);
double moved = Math.Abs(p.X - _mouseDownPoint.X) + Math.Abs(p.Y - _mouseDownPoint.Y);
if (moved < 3)
{
Action onClick = HitTestLink(p);
if (onClick != null)
{
try { onClick(); }
catch (Exception ex) { Debug.WriteLine("LogView link click error: " + ex); }
}
}
}
protected override void OnMouseWheel(MouseWheelEventArgs e)
{
base.OnMouseWheel(e);
double lines = e.Delta / 120.0 * 3.0;
SetVerticalOffset(_offset.Y - lines * _lineHeight);
e.Handled = true;
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
bool ctrl = (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control;
if (ctrl && e.Key == Key.C) { CopySelection(); e.Handled = true; }
else if (ctrl && e.Key == Key.A) { SelectAll(); e.Handled = true; }
else if (e.Key == Key.PageDown) { PageDown(); e.Handled = true; }
else if (e.Key == Key.PageUp) { PageUp(); e.Handled = true; }
else if (e.Key == Key.Home && ctrl) { ScrollToHome(); e.Handled = true; }
else if (e.Key == Key.End && ctrl) { ScrollToEnd(); e.Handled = true; }
}
public void SelectAll()
{
if (_lines.Count == 0) return;
_selAnchor = new Pos(0, 0);
_selCaret = new Pos(_lines.Count - 1, _lines[_lines.Count - 1].Length);
_hasSelection = true;
InvalidateVisual();
}
public bool HasSelection { get { return _hasSelection && _selAnchor.CompareTo(_selCaret) != 0; } }
public void CopySelection()
{
string text = GetSelectedText();
if (string.IsNullOrEmpty(text)) return;
try { Clipboard.SetText(text); }
catch (Exception ex) { Debug.WriteLine("LogView copy error: " + ex); }
}
/// <summary>Copy the entire log to the clipboard (regardless of selection).</summary>
public void CopyAll()
{
string text = GetText();
if (string.IsNullOrEmpty(text)) return;
try { Clipboard.SetText(text); }
catch (Exception ex) { Debug.WriteLine("LogView copy-all error: " + ex); }
}
private string GetSelectedText()
{
if (!HasSelection) return string.Empty;
Pos lo, hi;
if (_selAnchor.CompareTo(_selCaret) <= 0) { lo = _selAnchor; hi = _selCaret; }
else { lo = _selCaret; hi = _selAnchor; }
StringBuilder sb = new StringBuilder();
for (int i = lo.Line; i <= hi.Line && i < _lines.Count; i++)
{
string t = _lines[i].GetText();
int from = (i == lo.Line) ? Math.Min(lo.Col, t.Length) : 0;
int to = (i == hi.Line) ? Math.Min(hi.Col, t.Length) : t.Length;
if (to > from) sb.Append(t.Substring(from, to - from));
if (i != hi.Line) sb.Append("\r\n");
}
return sb.ToString();
}
#endregion
#region IScrollInfo
private Vector _offset;
private Size _viewport;
private Size _extent;
private bool _canHScroll;
private bool _canVScroll = true;
public bool CanVerticallyScroll { get { return _canVScroll; } set { _canVScroll = value; } }
public bool CanHorizontallyScroll { get { return _canHScroll; } set { _canHScroll = value; } }
public double ExtentWidth { get { return _extent.Width; } }
public double ExtentHeight { get { return _extent.Height; } }
public double ViewportWidth { get { return _viewport.Width; } }
public double ViewportHeight { get { return _viewport.Height; } }
public double HorizontalOffset { get { return _offset.X; } }
public double VerticalOffset { get { return _offset.Y; } }
public ScrollViewer ScrollOwner { get; set; }
private void VerifyScrollData(Size viewport, Size extent)
{
bool changed = viewport != _viewport || extent != _extent;
_viewport = viewport;
_extent = extent;
double maxY = Math.Max(0, _extent.Height - _viewport.Height);
double maxX = Math.Max(0, _extent.Width - _viewport.Width);
// Stay pinned to the bottom as new rows extend the document — unless the user scrolled up or is
// holding a selection (don't yank content out from under a drag-select).
bool pin = _stickToBottom && !HasSelection;
double cy = pin ? maxY : Math.Min(Math.Max(0, _offset.Y), maxY);
double cx = Math.Min(Math.Max(0, _offset.X), maxX);
if (cy != _offset.Y || cx != _offset.X) { _offset.X = cx; _offset.Y = cy; changed = true; }
if (changed && ScrollOwner != null)
ScrollOwner.InvalidateScrollInfo();
}
public void SetVerticalOffset(double offset)
{
double maxY = Math.Max(0, _extent.Height - _viewport.Height);
if (offset > maxY) offset = maxY;
if (offset < 0) offset = 0;
_stickToBottom = offset >= maxY - 0.5;
if (Math.Abs(offset - _offset.Y) < 0.001) return;
_offset.Y = offset;
if (ScrollOwner != null) ScrollOwner.InvalidateScrollInfo();
InvalidateVisual();
}
public void SetHorizontalOffset(double offset)
{
double maxX = Math.Max(0, _extent.Width - _viewport.Width);
if (offset > maxX) offset = maxX;
if (offset < 0) offset = 0;
if (Math.Abs(offset - _offset.X) < 0.001) return;
_offset.X = offset;
if (ScrollOwner != null) ScrollOwner.InvalidateScrollInfo();
InvalidateVisual();
}
public void LineUp() { SetVerticalOffset(_offset.Y - _lineHeight); }
public void LineDown() { SetVerticalOffset(_offset.Y + _lineHeight); }
public void LineLeft() { SetHorizontalOffset(_offset.X - _charWidth); }
public void LineRight() { SetHorizontalOffset(_offset.X + _charWidth); }
public void PageUp() { SetVerticalOffset(_offset.Y - _viewport.Height); }
public void PageDown() { SetVerticalOffset(_offset.Y + _viewport.Height); }
public void PageLeft() { SetHorizontalOffset(_offset.X - _viewport.Width); }
public void PageRight() { SetHorizontalOffset(_offset.X + _viewport.Width); }
public void MouseWheelUp() { SetVerticalOffset(_offset.Y - 3 * _lineHeight); }
public void MouseWheelDown() { SetVerticalOffset(_offset.Y + 3 * _lineHeight); }
public void MouseWheelLeft() { SetHorizontalOffset(_offset.X - 3 * _charWidth); }
public void MouseWheelRight() { SetHorizontalOffset(_offset.X + 3 * _charWidth); }
public Rect MakeVisible(Visual visual, Rect rectangle) { return rectangle; }
#endregion
#region Scroll helpers (RichTextBox-compatible names)
public void ScrollToEnd() { SetVerticalOffset(double.MaxValue); }
public void ScrollToHome() { SetVerticalOffset(0); }
public void ScrollToVerticalOffset(double offset) { SetVerticalOffset(offset); }
#endregion
}
}
+278
View File
@@ -0,0 +1,278 @@
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.Win32;
namespace APKToolGUI.Controls
{
/// <summary>
/// Application theme selection.
/// <para>
/// The integer values intentionally match the stored <c>Settings.Default.Theme</c>
/// values and the order of the theme combo box (0 = Auto, 1 = Light, 2 = Dark),
/// so existing config files keep working. This is a drop-in replacement for the
/// former <c>Dark.Net.Theme</c> enum.
/// </para>
/// </summary>
public enum Theme
{
Auto = 0,
Light = 1,
Dark = 2
}
/// <summary>
/// Self-contained dark mode support for Windows 10 (1809 / build 17763 and newer)
/// and Windows 11, written from scratch to replace the external <c>DarkNet</c> package.
///
/// <list type="bullet">
/// <item>Immersive dark title bars via <c>DwmSetWindowAttribute</c>.</item>
/// <item>Dark Win32 popup/menu rendering via the undocumented uxtheme app-mode ordinals.</item>
/// <item>Dark scroll bars and combo box drop-downs via <c>SetWindowTheme</c>.</item>
/// </list>
///
/// All methods are safe no-ops on operating systems that do not support these APIs,
/// so callers do not need to guard them with an OS-version check.
/// </summary>
public static class NativeDarkMode
{
#region Native interop
[DllImport("dwmapi.dll")]
private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attribute, ref int pvAttribute, int cbAttribute);
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
private static extern int SetWindowTheme(IntPtr hWnd, string pszSubAppName, string pszSubIdList);
// uxtheme.dll ordinal #135:
// Windows 10 1809 -> AllowDarkModeForApp(bool)
// Windows 10 1903+ -> SetPreferredAppMode(PreferredAppMode)
[DllImport("uxtheme.dll", EntryPoint = "#135")]
private static extern int SetPreferredAppMode(int preferredAppMode);
[DllImport("uxtheme.dll", EntryPoint = "#135")]
private static extern bool AllowDarkModeForApp(bool allow);
// uxtheme.dll ordinal #136: FlushMenuThemes()
[DllImport("uxtheme.dll", EntryPoint = "#136")]
private static extern void FlushMenuThemes();
// RtlGetVersion always returns the true OS version, unlike Environment.OSVersion
// / GetVersionEx which "lie" (report Windows 8 / 6.2) when the app has no manifest
// declaring Windows 10 compatibility - which is exactly this project's case.
[DllImport("ntdll.dll")]
private static extern int RtlGetVersion(ref RTL_OSVERSIONINFOEX versionInfo);
[StructLayout(LayoutKind.Sequential)]
private struct RTL_OSVERSIONINFOEX
{
internal uint dwOSVersionInfoSize;
internal uint dwMajorVersion;
internal uint dwMinorVersion;
internal uint dwBuildNumber;
internal uint dwPlatformId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
internal string szCSDVersion;
}
// DwmSetWindowAttribute "use immersive dark mode" attribute id.
// It moved from 19 to 20 in Windows 10 build 19041 (20H1); we try the new
// one first and fall back to the old one for 1809 / 1903 / 1909.
private const int DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19;
private const int DWMWA_USE_IMMERSIVE_DARK_MODE = 20;
private enum PreferredAppMode
{
Default = 0,
AllowDark = 1,
ForceDark = 2,
ForceLight = 3
}
private const int BUILD_1809 = 17763; // earliest build exposing the dark mode ordinals
private const int BUILD_1903 = 18362; // ordinal #135 becomes SetPreferredAppMode(int)
private const int BUILD_20H1 = 19041; // DWM immersive dark mode attribute becomes 20
#endregion
/// <summary>
/// The true OS version, queried once via <c>RtlGetVersion</c> so it is correct
/// even though this app has no Windows 10 compatibility manifest embedded.
/// </summary>
private static readonly Version _osVersion = GetRealOSVersion();
private static Version GetRealOSVersion()
{
try
{
var info = new RTL_OSVERSIONINFOEX
{
dwOSVersionInfoSize = (uint)Marshal.SizeOf(typeof(RTL_OSVERSIONINFOEX))
};
if (RtlGetVersion(ref info) == 0) // STATUS_SUCCESS
return new Version((int)info.dwMajorVersion, (int)info.dwMinorVersion, (int)info.dwBuildNumber);
}
catch
{
// ntdll unavailable - fall back to the (possibly lying) framework value.
}
return Environment.OSVersion.Version;
}
private static int WindowsBuild => _osVersion.Build;
/// <summary>
/// True when the running OS is Windows 10 1809 or newer, where the dark mode
/// APIs used here exist.
/// </summary>
public static bool IsSupported =>
_osVersion.Major >= 10 &&
WindowsBuild >= BUILD_1809;
/// <summary>
/// Sets the process-wide app mode so that Win32 popup menus, context menus and
/// common controls render dark. Call this once, before any window is created.
/// Mirrors <c>DarkNet.SetCurrentProcessTheme</c>.
/// </summary>
public static void SetProcessTheme(Theme theme)
{
if (!IsSupported)
return;
try
{
bool dark = EffectiveIsDark(theme);
if (WindowsBuild >= BUILD_1903)
SetPreferredAppMode((int)(dark ? PreferredAppMode.ForceDark : PreferredAppMode.ForceLight));
else
AllowDarkModeForApp(dark);
FlushMenuThemes();
}
catch
{
// These ordinals are undocumented; ignore failures on unexpected builds.
}
}
/// <summary>
/// Applies (or removes) the immersive dark title bar on a form. Safe to call
/// before the window handle exists - it is applied as soon as the handle is
/// created and re-applied once the window is shown. Mirrors
/// <c>DarkNet.SetWindowThemeForms</c>.
/// </summary>
public static void ApplyTheme(Form form, Theme theme)
{
if (form == null || !IsSupported)
return;
bool dark = EffectiveIsDark(theme);
if (form.IsHandleCreated)
UseImmersiveDarkTitleBar(form.Handle, dark);
else
form.HandleCreated += (s, e) => UseImmersiveDarkTitleBar(form.Handle, dark);
// Some builds only honour the attribute once the window is actually visible.
form.Shown += (s, e) => UseImmersiveDarkTitleBar(form.Handle, dark);
}
/// <summary>
/// Applies (or removes) the immersive dark title bar on a WPF window. Safe to
/// call before the native handle exists - it is applied on
/// <c>SourceInitialized</c>, which fires before the window is shown.
/// </summary>
public static void ApplyTheme(System.Windows.Window window, Theme theme)
{
if (window == null || !IsSupported)
return;
bool dark = EffectiveIsDark(theme);
var helper = new System.Windows.Interop.WindowInteropHelper(window);
if (helper.Handle != IntPtr.Zero)
UseImmersiveDarkTitleBar(helper.Handle, dark);
else
window.SourceInitialized += (s, e) =>
UseImmersiveDarkTitleBar(new System.Windows.Interop.WindowInteropHelper(window).Handle, dark);
}
/// <summary>
/// Toggles the immersive dark mode title bar for an arbitrary window handle.
/// </summary>
public static void UseImmersiveDarkTitleBar(IntPtr handle, bool enabled)
{
if (handle == IntPtr.Zero || !IsSupported)
return;
int useImmersiveDarkMode = enabled ? 1 : 0;
int attribute = WindowsBuild >= BUILD_20H1
? DWMWA_USE_IMMERSIVE_DARK_MODE
: DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1;
if (DwmSetWindowAttribute(handle, attribute, ref useImmersiveDarkMode, sizeof(int)) != 0)
{
// Fall back to the other attribute id if the first one was not accepted.
int fallback = attribute == DWMWA_USE_IMMERSIVE_DARK_MODE
? DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1
: DWMWA_USE_IMMERSIVE_DARK_MODE;
DwmSetWindowAttribute(handle, fallback, ref useImmersiveDarkMode, sizeof(int));
}
}
/// <summary>
/// Gives a control dark-themed scroll bars / drop-downs. Use
/// <c>"DarkMode_Explorer"</c> for scroll bars and lists, <c>"DarkMode_CFD"</c>
/// for combo boxes. Safe to call before the handle exists.
/// </summary>
public static void UseDarkControlTheme(Control control, string subAppName = "DarkMode_Explorer")
{
if (control == null || !IsSupported)
return;
if (control.IsHandleCreated)
SetWindowTheme(control.Handle, subAppName, null);
else
control.HandleCreated += (s, e) => SetWindowTheme(control.Handle, subAppName, null);
}
/// <summary>
/// Resolves a <see cref="Theme"/> to an effective dark/light decision,
/// reading the Windows personalization setting for <see cref="Theme.Auto"/>.
/// Mirrors <c>DarkNet.EffectiveCurrentProcessThemeIsDark</c>.
/// </summary>
public static bool EffectiveIsDark(Theme theme)
{
switch (theme)
{
case Theme.Dark:
return true;
case Theme.Light:
return false;
default:
return IsSystemUsingDarkMode();
}
}
/// <summary>
/// Reads whether the current user has selected the dark app theme in Windows.
/// </summary>
public static bool IsSystemUsingDarkMode()
{
try
{
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(
@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"))
{
// AppsUseLightTheme: 0 = dark, 1 = light (absent means light).
if (key?.GetValue("AppsUseLightTheme") is int appsUseLightTheme)
return appsUseLightTheme == 0;
}
}
catch
{
// Registry unavailable - assume light.
}
return false;
}
}
}
+92
View File
@@ -0,0 +1,92 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
namespace APKToolGUI.Controls
{
/// <summary>
/// Small themed numeric up/down control (WPF has no built-in equivalent of the
/// WinForms NumericUpDown). Templated in Themes/Controls.xaml.
/// </summary>
[TemplatePart(Name = "PART_TextBox", Type = typeof(TextBox))]
[TemplatePart(Name = "PART_Up", Type = typeof(RepeatButton))]
[TemplatePart(Name = "PART_Down", Type = typeof(RepeatButton))]
public class NumericUpDown : Control
{
private TextBox _textBox;
private bool _updating;
static NumericUpDown()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(NumericUpDown),
new FrameworkPropertyMetadata(typeof(NumericUpDown)));
}
public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register(
"Minimum", typeof(int), typeof(NumericUpDown), new PropertyMetadata(0, OnRangeChanged));
public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register(
"Maximum", typeof(int), typeof(NumericUpDown), new PropertyMetadata(100, OnRangeChanged));
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
"Value", typeof(int), typeof(NumericUpDown),
new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValueChanged));
public int Minimum { get { return (int)GetValue(MinimumProperty); } set { SetValue(MinimumProperty, value); } }
public int Maximum { get { return (int)GetValue(MaximumProperty); } set { SetValue(MaximumProperty, value); } }
public int Value { get { return (int)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } }
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var n = (NumericUpDown)d;
int clamped = n.Clamp((int)e.NewValue);
if (clamped != (int)e.NewValue) { n.Value = clamped; return; }
n.UpdateText();
}
private static void OnRangeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var n = (NumericUpDown)d;
n.Value = n.Clamp(n.Value);
}
private int Clamp(int v)
{
if (v < Minimum) return Minimum;
if (v > Maximum) return Maximum;
return v;
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
if (_textBox != null) _textBox.TextChanged -= TextBox_TextChanged;
_textBox = GetTemplateChild("PART_TextBox") as TextBox;
if (_textBox != null) _textBox.TextChanged += TextBox_TextChanged;
var up = GetTemplateChild("PART_Up") as RepeatButton;
var down = GetTemplateChild("PART_Down") as RepeatButton;
if (up != null) up.Click += (s, e) => Value = Clamp(Value + 1);
if (down != null) down.Click += (s, e) => Value = Clamp(Value - 1);
UpdateText();
}
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (_updating) return;
int v;
if (int.TryParse(_textBox.Text, out v))
Value = Clamp(v);
}
private void UpdateText()
{
if (_textBox == null) return;
_updating = true;
_textBox.Text = Value.ToString();
_updating = false;
}
}
}
+73
View File
@@ -0,0 +1,73 @@
using System.Windows;
using System.Windows.Media;
namespace APKToolGUI.Controls
{
/// <summary>
/// Shared dark/light palette for the WPF windows. Fills the <c>DynamicResource</c>
/// brush keys consumed by <c>Themes/Controls.xaml</c> and the window XAML, so every
/// converted window themes consistently. The dark palette mirrors the WinForms
/// <see cref="DarkTheme"/> colors used by the not-yet-converted forms.
/// </summary>
public static class WpfTheme
{
/// <summary>
/// Applies the dark or light palette to a window/element's resource dictionary.
/// The merged <c>Themes/Controls.xaml</c> styles pick these up via DynamicResource.
/// </summary>
public static void Apply(FrameworkElement target, bool dark)
{
if (dark)
{
Set(target, "WindowBackground", 32, 32, 32);
Set(target, "PrimaryText", 255, 255, 255);
Set(target, "SecondaryText", 160, 160, 160);
Set(target, "PanelBackground", 64, 64, 64); // text input background
Set(target, "ControlBackground", 51, 51, 51); // combo / checkbox box
Set(target, "PanelBorder", 90, 90, 90);
Set(target, "Accent", 0, 120, 215);
Set(target, "LinkText", 30, 144, 255); // DodgerBlue
Set(target, "ButtonBackground", 51, 51, 51);
Set(target, "ButtonBorder", 155, 155, 155);
Set(target, "ButtonHover", 61, 61, 61);
Set(target, "ButtonPressed", 42, 42, 42);
Set(target, "ScrollTrack", 45, 45, 45);
Set(target, "ScrollThumb", 85, 85, 85);
Set(target, "TabBackground", 45, 45, 45); // unselected tab
Set(target, "MenuBar", 32, 32, 32);
Set(target, "MenuPopup", 43, 43, 43);
Set(target, "MenuHighlight", 61, 61, 61);
Set(target, "LogBackground", 30, 30, 30);
}
else
{
Set(target, "WindowBackground", 240, 240, 240);
Set(target, "PrimaryText", 0, 0, 0);
Set(target, "SecondaryText", 105, 105, 105); // DimGray
Set(target, "PanelBackground", 255, 255, 255);
Set(target, "ControlBackground", 255, 255, 255);
Set(target, "PanelBorder", 171, 173, 179);
Set(target, "Accent", 0, 120, 215);
Set(target, "LinkText", 30, 144, 255);
Set(target, "ButtonBackground", 225, 225, 225);
Set(target, "ButtonBorder", 173, 173, 173);
Set(target, "ButtonHover", 229, 241, 251);
Set(target, "ButtonPressed", 204, 228, 247);
Set(target, "ScrollTrack", 240, 240, 240);
Set(target, "ScrollThumb", 180, 180, 180);
Set(target, "TabBackground", 224, 224, 224);
Set(target, "MenuBar", 240, 240, 240);
Set(target, "MenuPopup", 250, 250, 250);
Set(target, "MenuHighlight", 204, 228, 247);
Set(target, "LogBackground", 255, 255, 255);
}
}
private static void Set(FrameworkElement target, string key, byte r, byte g, byte b)
{
var brush = new SolidColorBrush(Color.FromRgb(r, g, b));
brush.Freeze();
target.Resources[key] = brush;
}
}
}
+78
View File
@@ -0,0 +1,78 @@
<Window x:Class="APKToolGUI.Forms.AboutWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="About"
Width="528" Height="320"
MinWidth="420" MinHeight="260"
ResizeMode="NoResize"
ShowInTaskbar="False"
WindowStartupLocation="CenterScreen"
UseLayoutRounding="True"
TextOptions.TextFormattingMode="Display"
FontFamily="Segoe UI" FontSize="12"
Background="{DynamicResource WindowBackground}"
Foreground="{DynamicResource PrimaryText}">
<!--
WPF replacement for the former WinForms FormAboutBox.
Shared dark/light control styles are merged from Themes/Controls.xaml; the
actual colours are filled in by WpfTheme.Apply(this, dark) in the code-behind.
-->
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Themes/Controls.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid Margin="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Width="219" Height="259"
VerticalAlignment="Top"
Stretch="Uniform"
Margin="0,0,12,0"
Source="pack://application:,,,/Resources/android.png"/>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="productNameText" Grid.Row="0"
FontSize="16" FontWeight="SemiBold"
TextWrapping="Wrap" Margin="0,4"/>
<TextBlock x:Name="versionText" Grid.Row="1" TextWrapping="Wrap" Margin="0,4"/>
<TextBlock x:Name="copyrightText" Grid.Row="2" TextWrapping="Wrap" Margin="0,4"/>
<TextBlock Grid.Row="3" Margin="0,4">
<Hyperlink x:Name="repoLink" Click="RepoLink_Click"
Foreground="{DynamicResource LinkText}">
<Run x:Name="repoLinkText"/>
</Hyperlink>
</TextBlock>
<TextBox x:Name="descriptionText" Grid.Row="4" Margin="0,6"
IsReadOnly="True" TextWrapping="Wrap" IsTabStop="False"
Padding="4"
VerticalScrollBarVisibility="Auto"
Background="{DynamicResource PanelBackground}"
Foreground="{DynamicResource PrimaryText}"
BorderBrush="{DynamicResource PanelBorder}"/>
<Button x:Name="okButton" Grid.Row="5"
HorizontalAlignment="Right" MinWidth="84" Margin="0,4,0,0"
IsDefault="True" IsCancel="True"
Click="OkButton_Click"/>
</Grid>
</Grid>
</Window>
+115
View File
@@ -0,0 +1,115 @@
using System;
using System.Reflection;
using System.Windows;
using APKToolGUI.Controls;
using APKToolGUI.Properties;
// Alias the resource class: a bare "Language" would otherwise bind to the inherited
// FrameworkElement.Language property (System.Windows.Markup.XmlLanguage).
using Lang = APKToolGUI.Languages.Language;
namespace APKToolGUI.Forms
{
/// <summary>
/// WPF replacement for the former WinForms <c>FormAboutBox</c>. Behaviour is kept
/// identical: the product name, version, copyright and description come from the
/// assembly attributes, the title / version / copyright / link captions are
/// localised, and the title bar follows the app's dark/light theme.
/// </summary>
public partial class AboutWindow : Window
{
private const string RepoUrl = "https://github.com/AndnixSH/APKToolGUI";
public AboutWindow()
{
InitializeComponent();
Theme theme = (Theme)Settings.Default.Theme;
WpfTheme.Apply(this, Program.IsDarkTheme());
// Our own immersive dark title bar (replaces DarkNet), now for WPF windows.
NativeDarkMode.ApplyTheme(this, theme);
ApplyLocalizedText();
}
private void ApplyLocalizedText()
{
var rm = Lang.ResourceManager;
Title = String.Format("{0} {1}", Lang.About, AssemblyTitle);
productNameText.Text = AssemblyProduct;
versionText.Text = String.Format("{0} {1}", rm.GetString("AboutVersion"), AssemblyVersion);
copyrightText.Text = String.Format("{0} {1}", rm.GetString("AboutCopyright"), AssemblyCopyright);
repoLinkText.Text = rm.GetString("AboutGithubRepo");
descriptionText.Text = AssemblyDescription;
okButton.Content = rm.GetString("AboutOK");
}
private void RepoLink_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Process.Start(RepoUrl);
}
private void OkButton_Click(object sender, RoutedEventArgs e)
{
Close();
}
#region Assembly attribute accessors
public string AssemblyTitle
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
if (attributes.Length > 0)
{
AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
if (titleAttribute.Title != "")
return titleAttribute.Title;
}
return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
}
}
public string AssemblyVersion
{
get { return Assembly.GetExecutingAssembly().GetName().Version.ToString(); }
}
public string AssemblyDescription
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
if (attributes.Length == 0)
return "";
return ((AssemblyDescriptionAttribute)attributes[0]).Description;
}
}
public string AssemblyProduct
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
if (attributes.Length == 0)
return "";
return ((AssemblyProductAttribute)attributes[0]).Product;
}
}
public string AssemblyCopyright
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
if (attributes.Length == 0)
return "";
return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
}
}
#endregion
}
}
-128
View File
@@ -1,128 +0,0 @@
namespace APKToolGUI
{
partial class FormAboutBox
{
/// <summary>
/// Требуется переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором форм Windows
/// <summary>
/// Обязательный метод для поддержки конструктора - не изменяйте
/// содержимое данного метода при помощи редактора кода.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormAboutBox));
this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
this.logoPictureBox = new System.Windows.Forms.PictureBox();
this.labelProductName = new System.Windows.Forms.Label();
this.labelVersion = new System.Windows.Forms.Label();
this.labelCopyright = new System.Windows.Forms.Label();
this.okButton = new System.Windows.Forms.Button();
this.textBoxDescription = new System.Windows.Forms.TextBox();
this.linkLabel1 = new System.Windows.Forms.LinkLabel();
this.tableLayoutPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit();
this.SuspendLayout();
//
// tableLayoutPanel
//
resources.ApplyResources(this.tableLayoutPanel, "tableLayoutPanel");
this.tableLayoutPanel.Controls.Add(this.logoPictureBox, 0, 0);
this.tableLayoutPanel.Controls.Add(this.labelProductName, 1, 0);
this.tableLayoutPanel.Controls.Add(this.labelVersion, 1, 1);
this.tableLayoutPanel.Controls.Add(this.labelCopyright, 1, 2);
this.tableLayoutPanel.Controls.Add(this.okButton, 1, 5);
this.tableLayoutPanel.Controls.Add(this.textBoxDescription, 1, 4);
this.tableLayoutPanel.Controls.Add(this.linkLabel1, 1, 3);
this.tableLayoutPanel.Name = "tableLayoutPanel";
//
// logoPictureBox
//
resources.ApplyResources(this.logoPictureBox, "logoPictureBox");
this.logoPictureBox.Name = "logoPictureBox";
this.tableLayoutPanel.SetRowSpan(this.logoPictureBox, 6);
this.logoPictureBox.TabStop = false;
//
// labelProductName
//
resources.ApplyResources(this.labelProductName, "labelProductName");
this.labelProductName.Name = "labelProductName";
//
// labelVersion
//
resources.ApplyResources(this.labelVersion, "labelVersion");
this.labelVersion.Name = "labelVersion";
//
// labelCopyright
//
resources.ApplyResources(this.labelCopyright, "labelCopyright");
this.labelCopyright.Name = "labelCopyright";
//
// okButton
//
resources.ApplyResources(this.okButton, "okButton");
this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.okButton.Name = "okButton";
//
// textBoxDescription
//
resources.ApplyResources(this.textBoxDescription, "textBoxDescription");
this.textBoxDescription.Name = "textBoxDescription";
this.textBoxDescription.ReadOnly = true;
this.textBoxDescription.TabStop = false;
//
// linkLabel1
//
resources.ApplyResources(this.linkLabel1, "linkLabel1");
this.linkLabel1.LinkColor = System.Drawing.Color.DodgerBlue;
this.linkLabel1.Name = "linkLabel1";
this.linkLabel1.TabStop = true;
this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
//
// FormAboutBox
//
this.AcceptButton = this.okButton;
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tableLayoutPanel);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "FormAboutBox";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.tableLayoutPanel.ResumeLayout(false);
this.tableLayoutPanel.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
private System.Windows.Forms.PictureBox logoPictureBox;
private System.Windows.Forms.Label labelProductName;
private System.Windows.Forms.Label labelVersion;
private System.Windows.Forms.Label labelCopyright;
private System.Windows.Forms.TextBox textBoxDescription;
private System.Windows.Forms.Button okButton;
private System.Windows.Forms.LinkLabel linkLabel1;
}
}
-114
View File
@@ -1,114 +0,0 @@
using APKToolGUI.Controls;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
namespace APKToolGUI
{
partial class FormAboutBox : Form
{
public FormAboutBox()
{
InitializeComponent();
if (Program.IsDarkTheme())
DarkTheme.SetTheme(Controls, this);
this.Text = String.Format("{0} {1}", this.Text, AssemblyTitle);
this.labelProductName.Text = AssemblyProduct;
this.labelVersion.Text = String.Format("{0} {1}", labelVersion.Text, AssemblyVersion);
this.labelCopyright.Text = String.Format("{0} {1}", this.labelCopyright.Text, AssemblyCopyright);// AssemblyCopyright;
//this.labelCompanyName.Text = AssemblyCompany;
this.textBoxDescription.Text = AssemblyDescription;
}
#region Методы доступа к атрибутам сборки
public string AssemblyTitle
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
if (attributes.Length > 0)
{
AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
if (titleAttribute.Title != "")
{
return titleAttribute.Title;
}
}
return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
}
}
public string AssemblyVersion
{
get
{
return Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
}
public string AssemblyDescription
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
if (attributes.Length == 0)
{
return "";
}
return ((AssemblyDescriptionAttribute)attributes[0]).Description;
}
}
public string AssemblyProduct
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
if (attributes.Length == 0)
{
return "";
}
return ((AssemblyProductAttribute)attributes[0]).Product;
}
}
public string AssemblyCopyright
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
if (attributes.Length == 0)
{
return "";
}
return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
}
}
public string AssemblyCompany
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
if (attributes.Length == 0)
{
return "";
}
return ((AssemblyCompanyAttribute)attributes[0]).Company;
}
}
#endregion
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("https://github.com/AndnixSH/APKToolGUI");
}
}
}
-144
View File
@@ -1,144 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Text" xml:space="preserve">
<value>Über</value>
</data>
<data name="labelCopyright.Text" xml:space="preserve">
<value>Copyright</value>
</data>
<data name="labelProductName.Text" xml:space="preserve">
<value>Produktname</value>
</data>
<data name="labelVersion.Text" xml:space="preserve">
<value>Version</value>
</data>
<data name="linkLabel1.Text" xml:space="preserve">
<value>Github Repo</value>
</data>
<data name="okButton.Text" xml:space="preserve">
<value>&amp;ОК</value>
</data>
<data name="textBoxDescription.Text" xml:space="preserve">
<value>Beschreibung</value>
</data>
</root>
-627
View File
@@ -1,627 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="tableLayoutPanel.ColumnCount" type="System.Int32, mscorlib">
<value>2</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="logoPictureBox.BackgroundImageLayout" type="System.Windows.Forms.ImageLayout, System.Windows.Forms">
<value>Center</value>
</data>
<data name="logoPictureBox.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="logoPictureBox.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAMAAAADACAYAAABS3GwHAAAABGdBTUEAALGPC/xhBQAAMeRJREFUeF7t
XQd4VMUWXnkmEHpCkwDSAgTSe9tAVJ4oClIMUqT33ntLozwFfc8CIooFQbpKEekiSDGht5AEkBbpKC1A
SObNP/fO5ma5C0nY7N7dzPm+/1s+cvfuvTP/f+acM3Pn6oQJEyZMmDBhwoQJEyZMmDBhwp7NCHlOR2KK
RZNl/wKitsU8nx/w7+Ec7FzChGnOFCQHaQOS5jkYSGtuk38Hv8EFIsQhzHJm5NHzQnKQVX92hnNUakz1
qLQZbo1PxXlFnk4IbpyS0LhJ2rSXGqfGvwqwf9P/Y3+jx+BYfAffxTnk05k24+sSohBmFpOJBY8r/89j
9uqh90vpU2bU0Z+Kb9o4LaFr5KmEKY1TE76MTEtYF5kWv4t+Hqf/f4F+3qTIoHhIkUWRTUFk4N/4P/wN
x9yUv3NcPsc6dk6cm/4Gfgu/id+WL+MxyzVKCBOWZ6OEMZDHyKLOxJRonBLfsPGp+DbUc8dQYi6hOExx
mQIE5oRWR2p83qH2/Rzgt/Cb+O0luBZ9WkLrqDPT3XGN8uUazCBiIQZhqiZ7+scIAjFQUkWmTnu38amE
T2VvfINCjZRAtj41HuR8xJAanwv4W15g/D0Gej7pb7lGDmPQa4vfxa6VXjOuXe2exMggjBmIYOzpA9Jj
SkamTY9AuEEJtYXiqoJgSoCYmfhkxE2JzwYiU6j3LkTw31EIhV0D/VS7Rlz7Fulepkfg3uTbZKZ2/8Ls
3WiCKIUDOYkiEs0mqdPDaBgRTz3sXkqa+woScTCycbKrkdOaMIgixaQg7uPecI+411zJtUqbCLM340O/
wpBIUu84jGI7I0huwrBQRquEfxoMgpDvQXFfwH12z/Te0QZyczBjbSTCI/uxx4Z56uUap8W/TEnwFQUS
SSUxDF5ejVS2DHZPPFzKfc9og6/QJsoR4LF2E2ZjRr0YG9ZlY7E9TQxpCLDViADZ9kp6UzCIwSihZm1D
20iZK4jqka2ZUagTkhpTNvJUfH/a2QeVnU0hVVZsMLwxF9i9yxUmRbsQtJU+NWFA01Mzy8nNKEIjzRtP
5GTDJBEjflrCMUXnwuNJnk+FEEUZshiMR4VjaEPlhJtIljVokneSO4V+RqTEdYxMm5ak6EhB/DzCIASp
zeT2m5akP5XQQdnGIj/QgtGOUHp9tp7mVMKGnI5jnUgTW0H8/IIJgbcdb0/atmhjubnFaGBNUxI/Inmq
qzRTm/DA0FnM46t3rkA+IY0IvF0foK3R5nLz5+oLYYVtRl5ffzKhM+2UM4oOEqFOIUARGvF2PoO2l7tB
jAaWMGXcGX46oaY+LX6pokOkCR+VzhMwH1gbK6pG6AP0hdwtufpImBlN6fUjT8a1p42fzjuBQoQ7lkbu
0SAdfSJ3jwiJzGqKigPq0rSx5yoaXoQ7VoRxWKRPm/YZnzvIVZkTVjDLFfKciAujjXyINzaF8PpagXI0
SE04GHYkJlzuNhESFdRyJbopcX1o4942EB/lTbWOELAaFGuNIIjbEcem9JW7T4RE+TVDg5GYYpGnEmbL
xBde3xaQIwIScSL2A92yaDYCCBHk0XhDhR2LcaHD6Y8K8ktr3NUaXUBbkNYXSSI4NvWngG0jKyr7VpgJ
M5D/6FQ3xVIGNKYob9oYDOVSKgL9idh9gTvHNFD2sTClKSa39CfiAmjYc1omv4j3bRjycgoWEkWciDkT
tmtMMPqY9bWoEMmmKHNGnox9hTbWFTQYxUMR8tgJUtl2LxgJroTtHdsMfS3KpDA0gLzGPCI5viX1/HcE
+e0UOSK4E7p7fBup/2nfF1kR5Hj+5/QnY1vTxsGGUFLYI8hvn5ArRBHHYzJCd49th74vsiOBHPM/p0+N
bSHIX4TARXB0akbI76PbggNFLjHm5I9Ijn2JNkbOBJcgf9EAF8HhKXeCt45ETlB0RMDJH3ooxl+flnBJ
kL+IAiKgn2EHJ1/2/3lEKDhh9yLgNyjV+RPSZPKLhLeogibG+pNxJGz/pNMBawa5Kzlid8ZLnfrD45z1
qQmJgvwCDLIIQhMn7vdb1r2Skiv2YznbaTynT4lfKZNfhD0CEigXIo7HkNDd436iHJHIbzdbsOSUuJ6j
N/ueTH5Mk4sZXgEGecY4K+LIVBKyfdT/wBXGGHsoj/Kkl95kd5n8kgBUGkKg6EJeTk3CD04mQVuHDwBn
bD4f4OQPPzo5iJL+b5n8j9QaQEAA3JDygQn/BKwZoAd3bFYEPJEJ+XlwWZro7JPJL+J+gScjNT5TfyKW
hOwcc8jjg2gXSiEb3IQLsZsUv9G4P44/wyvIL5A3UBGEH55CgraN+AocUvDJNkx++cJzEcemtpPJD4i4
XyBP4PlAaNIE4r9uQDdwKU9vy9SCycPVcyF7xlSnN3HO4P1VblRAwCQQCiUjFBp90WtBR7zEwwbygZxh
qhi9ie8M5Behj0BBQLmDUChw87DllFPy/ICGQyFe9Yk4HvuOTH7M9Il6v0CBwOYH6GdoIg2F1vTvDm5p
dhTICX0mVKGkP2nw/kY3JSCQL8hVoaBfR6V5ftq9BjimTRFI218UizgZ+4FMfrGLg4B5QLkUdmAS8d84
9DNwjG+1ohnjoY/+2OQQxWONouojYBagKoQJspDdY+/6LO3xErgWMK+PRqpCcr2fAonvTzL5RegjYF7I
cwOBG4dtoFxjDlcTCbEc+xcLPzqlrUx+kfgKmB08IQ7ZPY74rujTFZyz/gyxtGT1ueofRDtFpsTtEt5f
oFBBRwGsGA3aPDSpYo+IMuCeVZdNy3FYMf2xmB7C+wsUNtgokEpHgT0YBfoOBfc8YqIdGRktbrL391g2
oDS9uP2yADS90rNp2kzS5vT/SLO091T/XlTRJCWBvHlqNml1+r/kpdTpqsdoBpRjGAVoLnD0xXFvOIOD
VqkKce8fdsQ2vD9I/8PNRJKVlUV23U4lbU9/pHpcUcSg89+Sc/evkYxHD8i8q1vJK6kzVI/TAgyjAM0F
vJf0GQYOWr4iJHv/Wt2iStAL2i0LQNOxf8+zX5CrD28xAWRmPWJiUDuuqOGV1Jnk+L2LrF2AC/evk85/
fqZ6rGZAuYZRIOCXIfsrRjSQcgFLjgJy3b9Y+CHbqfx0oZ168cENQ0fffXSfdP1znuqxRQWNaegz89Ia
Q5sAZ+9fJZ3+nKN6vFbAK0LBO8cQr0W9sVq0mOVmh3Pq/s/rT8attQXvDzRJnUa+v74rV2f/djuZvJb2
vurxRQEdzsxhhFe2CdoIbaV2vKZAORd+aDLxXzdoC+UiEmHLzAvw2D80cXwEvQj2Ymq2flvtIjUGJMCX
H/xt6GzEvPF//ah6rL2jSco0svzGHvKIhoO8PdA2aCO147UGPjsctH3kQ48FnbG7nIUqQlKs9a+I47Gf
yN7fZp7xRbXjsytbyINHmYZOT76XTlqc+kD1eHtG33MLyDU5JwLQJmgbtJHa8ZoE1gglTSS+q/p/A04W
eh7AY/+gDQNq6FPiztqaAABUgw7ePWvoeCTE317bYVsd/4x4OXUGSbxzytAGwMG7f9peeRgl0eMxJGDT
0Ivu01vXBzcLtSIkC+Bf4Ycn462NuABDQmJLmHBxOUuCeeffeHibxcNqx9obkPhOTl9BHmbljIJ3aFtM
uLhM9Xgtw1AS3TWWeC/uMRrcLLxkWCp9Ag765Lj1sgBsctnDq2n/IZv/OWIgALD65j7mGdWOtycgxj96
73yue99E2+LftE3Ujtc85GTYb82gbZSbToyjhbE8gnv/kB0jA2gC8g/z/jaS/KoBHv92ZoaBBPj3eBv0
gvnF19d+y5X44r47nPlU9VhbAE+GA7cOv+0+p0MTcLRwwiApwXhefzhmnOz9bX69/5Ibu1kOwMmAONhm
PWEegLkQZRUM9442UDvWpkC5GLp3PPFZ3GcGOGr+ZDhGCn+qR4c50fBnmywAm9/hLfr0x+RUxmUDIe4/
ekg+uLyexclqx9sysLxh/d8Hc3n/tIxL5G17WBJCuRh+ZArxXz1wj0uIW1lwVeaseYyHP0G/jgyyh/CH
ozHFjL/W5CqLXnhwnbQ784nq8U8DhINKSvSZj0mPs/PJ0PMLyXuX1pFF138n6/4+QLbeOkZ2304lh++e
JakZf7GZaSw9OHkvneyno8/vt0+y3AT5yIJrv7I5ikHnv6Geex6L3bFsQe1384JRF75nAuf3+YD+e/pf
q1kbqB1vS+BhUMCW4bcbfBj9Mrhq1jBIPtnz4Qcnj5C9f7YtVn/U0PzULJJ457SBGMBiNhv69FEApVOQ
sh0l/PRLq8mam/vJ3jtpjNxXHv6TS1gFBapV6VQox+9dIDupQDBTO+7iUrZ6E0l7XkarN+ixf9DrUp4X
19k8bZbq8bYGxkXKSSyQ8/qmRxy4aj4ByOEPhaP+ROxqWQB2tcEtvCxmhTk5MEE0+Py3qscCmDgbc2EJ
I2MqDSMemoHo+cU9KoykO6fI3KtbSP9zXz9xdPjf5Q25xIh7HUC/o3aszQJhEKpBP/TH0gipGmSOMIiH
P14r+9ehP8R3erMrAcCT//L3oVzx8e7bKbnWxoP0EMqyG3vY+plbmfcMx1oTSGQxj3GMjhAfX9lEup39
PFcij9Dprwc3DcfjHn+muYDdTfxRTuqTY0nghqHpdSY39wJnzTIK8PAnZM+Yt2Xy20X8b4zeZ7/MRRTE
yBPTl5PX094n/7m0lhygMbpy8kyrwJLvrbeOk+EXvmNC+O76zlzCRjiFpeFqbWDLYJxMjSfBv40iDed1
6AXOPvvaIKyui4nCCOAYfnjKTFkAdkd+jk+pB1WS6Tr1rMq5AlvDlQf/kDuZuUX78ZWNqvduF0A5NHEC
8f6ux1xwlnH3mVaIygvfKEroj8dulgVgV+GPEm1puIAno5SEsSecpffW2kZWe+YXqAKBm9g6xW9Vv12U
s6UZdyUHXjCT4//nGy3s6UZ/xC7jfw5UVb64uo3F02rksQdgRJt/dSu7V7U2sHkgD0A5dP2Q9Npjm/mA
u8+UB8hfdsDbvOnJ8WI7m1z89iQgTka9HfV/5aywvQL3iHuN++sH0vQZ5hW0CLkcimcEshp+8E57cPdZ
8gC+/ZxjWNLEUTgxE4HKD9sqMBP80819j8XJRQF3aG7z480k+5gJliGHQVlYHer5ZZdp4K7M4QLkAaih
RrH4qUT44alfygKwi/AHT0MNO/8d+dPoccCiiNMZl8mQ8wvtoizK84CwfROJ9+JeeKdACcbhAs0HSF96
Hk/dRxyP2WEvAnjj1CwW6/+deVeVEEURNzPvsNzgddo2am1mK+ACwI4Rviv7JpX1qI6X7BVUAMz7O3jO
bl+DntguEmBs/LT91glW41cjQlEG1glhrVLLUx+qtp3NgHIUQvBfNzi9do+XGoDDuj4B+U+Eefzvu3ZA
eGRq/G0IwJYnwHqenU9O3Lug2vkCOThy9xzpZsPbxfAJscBNw+/UjW3xOjhckET4uVox3UrQz+JB20cb
XndkixUgxLZY93I64wp5pNLhArmBWWMsk+537iubzAt4JQgzwu6fdugLDlcfHo21QflKhLkASoTuHTec
CcBGN70F+ZUbYgnkDefvXye9zn6p2qZahpwHZKMS5DHvXawMLVEgAbgNfr04/XQK3z9xNvP+Nhj+TE1f
yZYlq3WwwNOBp8ew9FqtbbUKWQBsSUSjr7p+AQ7LXM6fAHQBLHEoFX5o8vdsBLChBBhD98gLi8hVQf5n
BhYIYhS1lafkeCUo/OBk4rO451pwWOZyPgQQzdYA4UulI47FbIIAIlLibGYE6H72czqE2++aHksD+VOn
M3NV21qLQLSCRyR9l/f5nXIYj0g6yJzOo8krQHV1nMtFnIj9w5YE0PHMHLbbm1pHChQch++es5lZYwiA
Om7is6LvEV2V0pUZl/NVCpUEULzGoH+76pPjjtuKALC2Zc/ttCKxpsfSQJtuu3XMJvZOAlf1ybHE/8eB
aZVa+ruBy/kRwHNy3bR4nfg36+mTY9kWiFoXAB4JXHR9p2rnCZgPn1/dqvm3yDABYDLs50EXq3UL8gWX
85MIcwGUcP+4kxc90WWtCwA7G2A7E+VzvQKFAzwgpPUdtTlXA34Zcq3mwFfCwGW8zAXcBsGfZoYSqPuc
jgH0RDe1LgBsQYIlvmodJmB+nKFJMXIttb7QAhhXMRu8Yeg/tYY1jQKXCyQA72+7h0SmJtzBybQqAKzn
32e0rYlA4WPH7WTN5gMGAWwefq/OuGZNweV8CUA+uKTngu5YB5ShVQHgTSZ4jlf50Pez4GHmQ3Lun8vk
2LUzDBduXbHKlifmwr2H98mfty6Rozf+JMk3z5FLd2+QR4/M1FZZmWyzAC0ul2BcpVFL4Jbh92uNbv4a
uIxdDcFtEPxp9pw8dVzSe2G3SDoCPNSqALBjmrmWOdzMuEXmHPyRvLV6IglfOpCELR1A2qydQr49vpER
Se07Wkb6nWtk+sHvyVtbYkjEuuGkyfrR5N3t75EN5xNJpplEjW0l3yngLnqFCS6AoC0jMutMaPYGuOza
p0VJcBsEf5oVMwjgq26R+tT4B1oUQFTqdPLbrROqHZNfgBAjfv2UeC3sjh0FcrCoB/Fd3IuM3fm56ve0
Cgi23bZpxH/1ABkDDQhbN4zMS16n+r2CYO31faTxSfU+shZyRoBhD40EkKfnAorJIVApj3ld9HQEuKc1
AaDqgzUq5tqyJOlSMgn5vt9j5Ofw+743OXAlVfW7WsSas7tVye+/RsLLG8aSv+6ap2hw88Ft0i95PolM
jlPtK2vAMAJsHpFRc/RrzcFlOQTKmwDkg0u5f9YhjJ5Qc0kwXnCBvS3VOiS/QP7w333LiY8J8nsv7snw
ftJS1e9rDfD+o/+Yb5L8QNC6IWTVn+abM9mQvo80SZxCIrEOR6W/LA3GVcrZwE3D7tUY/fKr4LJri4C8
jwBcAA0+aB9IQ6AbWhPA5PSVZpvtffjoIYnd/fUTyQ+M2jGXZNhALnDz/m3Sf9dHJsnvv3YQCVg7mHxy
YrXq9wsCPGHXL+lTErp7rCZEwAUQsGHo39X6vYzdovMnAB4C1Y9704fe0F9amgfAc6t/GL3g7VmAEWDu
wZ+I7yJKdBPkBxL++I7mCtpfYnE/8wGZmPS1SfIDGAGWnN6m+v2CYstfB4h+y2iCF1VYOxziXA34efDV
F7uE6MHlfIVAXAC1h77UIOJE7BktCWDixeVm38Yk+fo5VvUxRX5gz1/HVL+rRWxLP2SS/MBLG8eS83eu
qH63oLhBR56+iZ8g7JBEYMWRAFzFUgi/1QMvVG3lFQAu50sAutfdMBFWqmpzv5r64zHHtCIAbGeSVAiT
XhgF5h9ZS0KXUREYET9gSV8yadcCs5UOLQHMXUw98B0JXTf0MfI32TiafG9m78/xS3oSE0DgluEkdM84
q4mACeBELPFd2T+1Qmi9huCyLqoWnHoeBSA/DENRKfzo1L1aEQB2cL5XSOt97j7MID+l7SCt1k5iQgih
ePWnMWTB0fXk+j3be7AGucA3qZvIG1umkIj1Ixna/zaTbErfX2jzGn8/uENa7IgjgZupCCjCEidYJRxi
y6GPTiXeS3sfphyuxrjs4YH1bfkSAJKGimGHJmvigZioVLzafy/11uqNb05co4Q/d+syE4Xa320JGA0u
37tJLty5WuijGHKkj1PWkqDNw0kQHQUAS4dDCH3YAzGHpxCvhT3wQEwlxmWJ03kSAGbLntd5VMLuuhXD
kiYs0oIA2p7+SOzkZgM4cOMUabp9kkEAQVtHkNA/LCcCLoCw/ZOIx/wua8Bhmct4xiVvSyEo2I5w9LNC
yO9jZkEAOKnaD1oKSH7FtibaB0qiPRM/ksmfA+pILSICCIDyNSuE5iCNPumwAByWuZwvAfzL5fUQPEvp
ErBhiLQxrhW3RcED2VuM3uwuoF0s/HNrLvJjFGAjgQXCIVkA2cE7RpP6s97GBrkuzk0DyoHTMrefakwA
laI8MGw4+y7p3UkSAD25lTbGwrOoWIOu1tgC2sOhm6dJk1/H5SI/w7aRUmJciCLgG2MFbh2eXXfym4PA
YXkEyJ8AqrzqjSpQebf3WjehqrLqu4HHX1xG7hbBLcxtFVcz/iE9k2gYpCS/AoUZDjGOYhZ47eBbNfpG
vgUOy848XwIopgurjomDcq7RgQ30x2NPQwDWSoSXXN+l2tAC2gTmVd4/uUqV/MF0FAj+lY4EhZQYszmA
5Fjiu6LfBUp8PA9cThfgypdB5EkAsGI6NzYZhjygatiBSdvkMMgqm2PhJdFqDS2gXWy8tF+d/BwQwb6J
ZhWBHP+z94R5ft01kXL3RcbhWnmfBOOGg9m+QPSzSujusV8wAVhhdzi8ptSWZmEFJFy7/w8J3jrSJPk5
ws0oAi4AlF095nZcAe7KHM7zJBg3HOzgHFAHX67sv37waGkESMi2dCI84sJi1QYW0D7a7JnxRPIHbx/F
dnE2V04gJ8DZOG/9Ga1ngrsyh/M8CcYNsRKfC6joMad9S5pcsCfDLJ0IG7+7V8B2MPrIV6bJzwXARDCa
hO+f9MwiYNykjpo67Ie1hr/SFdx1CXFDGJ/nOQBuTABy9uxSvUOId8SxmFM4uSUTYTz0vv7vg6qNK6B9
fHlmk2nPrwQVABPBM4RDCH8gACyC81nW53zlV93Dwd38ToJxw8H/0lVnlaDyFNVowvKLFAZZLhFufmoW
STTj2n8By2LDpX1Ev31snsgPhOwcU2AR8PgfSyA8v+yCNUA1GXddWQUozyVQbjgYMVNx+UVjVYM2D58p
CcByeQDe3J6SITa6tVX8cSOF/Pv3KaYFoCT/DhkQwYH8h0OG+J9+333225+DszJ3Uc0El/MlABi+5FjO
60Vn+lml0bzOHan3z7RkHtDpz7nk0oObqo0roH2cvnOJtNoz/YnEz0V+WQBA2P78jQSMk5SbgRuGPKo5
4t8DwVlZAPmuAHHDlxzkJKJSpWhf34ijUy2aB+BlbZhVvPMgo9CAJc8ChYDMDJJ+7zppn/h+bvIbCUCN
/Ay/528kgADYlug0/nd+qW4EOFvQChA3DBnPsxiqTJkK9N81QneNW2VJAbx+8j22w8GI7Z8aMHL7nBz8
psRc09jxmSpG7VTgdyXmkVG7TGD3549hNLCHY34O9ipA70MdX+Qg0QhJXz6GMfuMsF+BAwtUMZbhqxwc
VODQ16oYd9gEjnzzdBwFviVjj35NXvl9cv7JbxDBWII3vTxNBDwBxmuRPD57dzPlak3GWSn+z3cCzA1f
QvJQokx914r009V3Wf/RGGZYGGShPCDi8BS89Fh106onPcPL4fN9rxwsUWBp7xwsy4Hv8j45WNFXHSv7
5YLfKgV+6J+DHxX4aYABOXv2mN66RPkYo/+6HAT8PDgH6xX4ZYhJBG4YmoONCuDxRQ75KS7AsJbfaEkz
n9QyhslSpwni54n8ABUAXnb3tBKpHP+za3GLaYH6v2tptxfwIAxmgPOdAHPDl1geUN63FipBL2Cn3Yjj
sVcsOQoAaABfSi5NkB8Q5DfAJPmfIIA8k59j95NHAr7+h7b7jSrtQ1uCq3LuyuP/AgkAxvIAmgFgPgCK
qhW6Z/xGCICOAhZdFhF+YLIkAkF+7ZNfSfxnJT8dARhMiMBQ/kyaSDznd9lFOVqXcVXibIHjf25QDmIo
J3lIqeG7tM8E9qNWWBYRcYiGQ1wEKqTnKBTyK4gvyF/IYY8x+SlCd49jO01IiXEOJ3j5EztRuMW2nAWO
ylzFHFaB439u+DJiKD4f4Fq9X1RUxJEpVntrDMIhvx+oCFSIDxQK+QFBfgNMkv8JAnhm8nNABNQRchGw
8AdboKzoe71Ka/83wdEy7tVQtEH9v8Dxv9JYHqBzcUE5FG/cqx20fdRq/uNKcloKGAlAOEH+x2E18iuJ
X4jk5wg/NJnok+Xqz16s/uy0jXIT4U9lnXPBVoCaMh4GlSxVu3IV+vmi5+edButp0oFRwFKTYsZAPAiy
CfLnoKiQH4THkueww5MZ93Dvdcc0mwxulqpV6QVwleKZwx9uPAwqoateloVB5QNr+tGkIxnlUGuNAgAP
hwT57T/syUV+ihAgaUIWhODzbY8zZRtVDwE3ddXYnNUzlT/VTAqDdLoyJWtUdKWftf1+GPCxXhoFrCYA
APMEIJ9Zya8gviC/lRLeJ5CfCYASP5QKAO1dP77lQnBS5iZWf5ot/OFmCINK162CPKBG9QFRr4UdmvS3
NcMgDlQG/CjZhOdXwJLkNxJAYZMfXh/eH6VRz6+733qhjd/b4KQcops1/OHGw6DiuvLly+tKloTS3AI2
DP1Bj1EgJS6TlUZVyGkpsJzgJzoSCPLbP/nh/RMnZPrTtnKf2XYTuEhp76orz5bum636Y2wYUjCxUFpO
NGq5xbboTLPxR1oYBYCII1OJPyVigcivIL4gvzbDHpDf4P3pp/fCnlk1eoYPABdLVixZFdyUOWrW8Icb
D4OcdGVZMlydon7QpuG/6qVcwCo7RhgDM8Ygm/D8hUD+JwjAYuTHZ+L4R4EbhxH3We3+oBx0Z1wso0Py
a5bJL1OGkxqSYafqFbDtdJ16s9r2Q01WK6MAgIkSkE6Q337CHqX3D/1jAvH5vjep3qfJaHDQqZoLnLEy
+S0UAcD4KIAl0lghWoPCPWjzsF2YjdPKKACgOmQQgRrpAQXxBfm1HfYw8lOEJU5g3r/hrOgDlHuNGAdL
y1ugF6L354aTS8mwTlfOydUFAqjrNqPNgLB9E7MtuUw6L2DhECWeKvkBQX4DTJL/CQKwJPkZEidkM++/
qGd29b6Nx4J7Tq7O2PwKM7+FlvwaG0+GS+lKl4bycAEN/dcP3ooncjAKWLsipAQbCdREIMhvgEnyK4lv
bfJT4sP7B6wfQtz/03Y35Ry8/4uy98c+toWW/BobHwUw21Zejr/c6o5t1oVe6AOQTiu5AAdyggBKPkF+
2yR/GCV/aNLErNA944n3190eVOsW2g+cc3JxQgSC0qfZZ36fZnwUKM1GgRIlatF/u/ut7L8C+zKyFXoa
GgUAzBOAkIL8eSC/sQCsTH4uAP81g0iDhLd+Adco5WvJ3l9Z+rSYAPBDSDiUo0Ddqh3CXgv5bdRlfXKs
VdcImQKbJ1g3ODfxBfnzRHxrkR+hD8iPF154fPbutQpN3duAa0bev9CTX2PDj0FxKDtBgRVLVClXh342
8Jjf+cNQ7PVohQdm8gIspQb5BPllmCK/kQCsQX4mAJr4hiVNyPZZ1ofUHtMM+/00KF65HJY9owoJ7hV6
6dOU4Qd5LlBOV8EJ8wJ1HcqX8qGdvT/8yBRKOOsvkVADEwElpCC/AlokPz6TJmbint1nRx9zKOmAl17X
1bk4IeJA5cfisb/S+CggVYR0ugp8FKg17rVudMh6qKehkNYSYg68RxZkzEV8Qf5cxLc2+UP3TWQL3ry+
6vbQtWsINrtqIHMMs77Kyo9VBADjowCbF6B4QVeuOIanhl7fdPsa+7RoMSHmwAx2ICVekSb/EwRgLfIz
AdCwBwJA1c5tSotl4JSubHE3xjEL1/2fZnwUwEyci87ZCfMC9RwqlvMPWDPwqLxMQlNzA0pgnoCJoCiS
X0l8LZGfOk4a9z9CG7h/GJ3iUMEpGJzSlS+BDW+xDg1c497f6sZHAbZGiKJy8UploVT3WsNe7hb068gM
LJPQYlWIA9WhgF+GFl3yK4ivBfKz0Ieey/OLrvdf6BjUH1yinKoHbskcA9c04f254UJQiuLbqVctXrFM
ffrZyGPeux/jZvQIhTRYFeKIQDhESVgkyP8EAViT/HiFKg99fJb0IXXGvf4lOFS8THFwCcudwa1CXfFZ
UMPF5EqI5eEKF+7ts7zvb1A2NtPSaigEYCSQRCAT3x7JryS+1sgvhz6Y8Ko/ozWWOvswDpVnE62aSXxN
GS6IJ8TYQqUKD4UqRDVsSolyju3sZaU3TeYVLCfYOEyQXw0WIH/glhGk4UcdLjqH1GwO7hSXEl886ghO
aSbxNWVQpjIUcqWhUAP62ajOuOb9aGfeQ/lRy/kAgHkCENKuyG8sAI2Rn8X99NweX3TJqNZVPxKckbmD
x2+VoY8mEl9T9ngopNNVd6xQBk/teDac3e4/NCkmSIq1Oj/AAaEyEdgD+U0QX0vkR93fe2FPUnvEqx+B
K45lHKUnvWwg9DE2ZSjEqkJssZwjuyGvRvM6LcKrMWkuoMmlEkqwcGjzcPshv5EArE1+BinpzfZZ2ofU
nfzGKnBE58gWu9Vm3JE4pPnQx9hwoRiupGUSmLyQYrmGFD7e33bbgnc5RZyM1XRlCJBEQHMCQX6zk59V
fPZPyvJd1Z/Un9Z6J+WGL+NI7gkvqyx2e1bDxfJQCJMW2KvdkA+UrVUl1Pv7XvtCaANqPSkG8KAPiGmz
5FcQXyvkZ9g38ZEfzbEavNf2SJkXnfXgRvEyxXncD84oJ7xsSgAwLgK+YlSZD3hUiKrf1GdZnxQ0mE2I
gI4EIKVNkP8JAtAS+dnTXbOjTzsH1nwdnHCsUBoRAo/7rbrS01yGC1fmA+wRSkeX0niczdO1lW8r3xV9
z6OhIk/GZaoRT0vAPAEIaTOeX4PkZ+XOfZMyMfPe8L/t011eaYRd3TxlTmAZDThik3G/KcMN8HyAb7Fe
07GKsyf99HrhneBoKoJ0mxHBUVkEKqTn0AT5FcTXCvklz0/JT9ul0X/bX6r8pm8ncMCxSikvcELmBjjC
4354f5s3HgrhhlDLRWKDiY1aXASuHYI7+C7rkx5CG9UmwqEjNByiRNQU+Z8gAO2Qn4Y91PM3+rD95cot
fDqj72XyY6aXJ73Ker/Ne39uXARIaPgkGW64tqNzaUkE0UHv+C7tcx6NTkn2SPPVITYS5BaB1civJL4G
yY9qD8jP9vL8sF26wfNLfY9yJ7jAJ7tsNul9milFwCtDWOBUm44E8ALelV/3auWzqGcK5gkikm2gRKoQ
gSD/4+SXlzdkh+yflOW3eiBpMOvtUy5RDRDzeztWLuWNvpc5YPMVn7yamghQ8qrjWNkZDeJdIbROU68F
3fYFbRtBIk7EZmt+xlgOh6xCfmMBaIz8bIZ338Rs7MDRYEabQy7etV5DHztULoVFbniyS1nutPmKT16N
iwA3jClu9tYZijqOziwe9Haq7BLmMa/TViRL8LJa2nJRDfpjMSSIktOi5DdBfK2QHwvbcCz28KwX23KH
U+UyEehb2sdwdJz86HtwoMiQnxtuFCUuYxEYcgIHBwd/99lvL8Y2JmwVqcZFgBIpiGlx8hsJwNrkZ6Dk
x0y/1zfdSZ2JzVegL9GnsoND2GNMfrsod+bX1EQg5QQ5IvCl3uM9/1UD7qHx2fMEWn6ohougCJKfhTxI
drGkedNw4vF554xaQ5t+iD5EXzqWduQJL/q4yJOfm7EIeGJcS1fasZHO0ZGJoGb/qIHe3/U8i7xAnxyX
reXl1AiHmAgKm/wK4muC/Ij3qQDwWKn7f9udr9opbBgjv6POi/WlVOrkCa8gv8LQAMrEmJdIa+qKF2+A
fYZoQ/q4BLs185jTcYcyJNLqaMBGAkpSs5L/CQKwFvmlXdskr4/f8F7Ui9SLb7XLObBmc/QZ7TsIAEtf
MMnFS5282iPIrzBjEfDJMrbDhJw4edNG9XOLbTnHd3nfu4gx9SfjsrQ6GuiP0pHgt1Hm9/xaIj/1+mEU
WNPjMa/z3dojXv2c9hHifZ7s4kF29CH6En3KyV+kEt68mlIEfMYY60KwB6QbrxBBBK6dQnp4ze9yFA3P
tl1Jjc/U4mjAwiGIwFzkVxDfWuRnxGfbFU7MDPl9DPFZ0pvU/0+b41Xb+fdG36CPHEs5oq+wpBl9hz7k
M7yC/E8xLgK+dgiLorAHJHsdE40lPeSQyNfBySm4/ozW3/gt63cvmBJAr9Fd6FDGzRFBPsn/BAFYmvwg
PhNAEvX6SRPZqliPee9muI1/fZGDk0Mo65NSDj7oI9ZXUp+h79CHyrU9gvxPMaUIsCIQy2J5hQiJVH2e
F8DjVO8S2osOv/vx1BY6BiGR1sIijAQgar7IryS+FsiP/fmxSzO9FryUvMHMNgertvbrhz5gfYF4X9oF
hCe76DP0HfpQkD+fxkWgrBAhgUIsyUIi6mk8DaOBg0NgvSktPvL+tscl7OjANuZFkqyhEUFNBFonv/Q2
durxE2mSS7/vu6ofafS/9pdqDnnlU9rmwaztJa+PEicPedBH6CtlpUeQv4CGRkMD8rwAS2V5SISasqFK
ROFXsbFby/rvv73KZ2nvO3j4Hk9yQQRaEQLCIS4Ck+Q3FoCFyQ/SM+BtjPD69P+xT4/n/C533Ca98VOF
sLqt0NaszWnbow/kvuAhD/qIx/ui0mMG46MBzwswrKKWjLIaKgxuOkfkBiXRKRgN/F07Bvds+FH7bb4r
+j1kC+uoELQyIuiPx1ICj3m651cQ3xLkz0X8xPFsGQPifM8F3R7Wi31re9W2/n3QtqyNaVtT345YH14f
fYC+QJ+gb0S8XwjGRcBDIl4qVY4G9VnprRQTARNCtV6Rwxp93GGP38r+mWxEkNcVcSFYa5c6Fg5Rwpok
v5EACpP8IZz8MvHxTEbAusHE++vumfWntd5b7d3QEZz4aFvHUo4obyLWV3p9XuIUIU8hGxcChlflaMBz
g7p0NGjIwqJSpSACjAoBEELDD9/5zWdpnwwsUZBKpwlspam1xMBE8LssAguTn5EeSJyQJYU6E7KDd44m
vj/2J55fdMmoH99qh0z8ALkNaXvSWN+R7eqB7e95rK/0+qLEaSFTGw0Qd+JBalQfMOuIsKgRKhOs86RO
9HftENzLfWbb1d7fdr+GhzMQ8+rl8ilDSny2JYXAwiGIQIX45iY/PDvDH+OzGfEpcP+BW4cTvH6o0dyO
190mv7mmamtWz4fHl+N8Fu5gKQPCHbQt2hhtjTYXXt9KhobmQuDlUl4pwsQLhmaU4+pJ+UFuIVR4uX7r
elNbzPP87N1kvx8GZCE8kifUDCESF0NhCwL5CQiLXMXc5Me2M4z0e8dlU+KD8I+wbgfzJn5rBxHvhT0e
NZgVfbL2yH/Pp8lta7SN3EZ8GQPifMzmoi3RpmhbXuExLm8K8lvBuAjggYzDIjxgzfMDLgTm0bgQnJzL
RLzYr8kY9/ffXu/5Tbf0AEoKkIOVUSUxSCNDIQsC4VDobojg2cgfjE+J9Nk0xMmSSc88PZaO+P88hHgv
7kUazemY7ja1xXrXLqFjnco4RRiIj7aRQh1OfB7noy2Nwx3h9TVkytEAQzLKcJiB5PkB9pqRRgSdTsoR
ypVEp/M8wb9icJ03aw9rmtDgg+gtXAwYGcL2T2JhEhWDNNOsMkKYQxQIhyCCvJI/mAPE3z02O3jPuCwa
6jwC8VlySz0/rh8ThBLpO6W7xbXc8mLfJtPL+9VoaSA92gBtAeJLO/dxj48248RHW6JN0baiwqNRQ4c8
SQh8RJByBNSvSzl6S17PkDCDFP4VQ2u3fHFI05gGM9qs85jfOdV3Rb+7ARuGUuKNYStRGeGNBIHZZzVh
GEON/BzSSDCOjULw2I9jdDYlfFbQ7nFZwRQhu8c+AvFZmIPv/TqKBFAvj/dqeX3V7a77B9GpdSe/ua5G
r8i48oG13qL3hqRWIj6qZYjvpaoOavk8xld6fFPEF+TXsD1NCIhjkcihfo01K/WRMOuoB1QTQ+nqFaOq
tQ/oV2d8808aznp7MwThs7T3LSzLxoQWvC3yB+x4LYdNQDYFxJETQsngSzVM4kQsC11AdICGNhzZLLwB
0akY8Aim/y+U7D/0Z48den7R9Zb7h+1S68W+tRkztS+08utfulr5l/h9sHsC6Us6UNIbwhyUM9EGaAu0
CdpGEN9OzJQQEMeibo1KBiZweHgkjQo0V2BioGFByUrlpRAhRxABJV4oH/VCK99uNQe9ElcvvuXihh++
s93j884nfRf3vOa/sv89rFAN3DKcxvKjmDjC9k1kAsEzAhHHY6Sqk8poYBglqJDCD05i4QuWdcCj4yET
nxX9iDclOvXs9zzmvnvNfXa7k/Xi39peZ8xri+HhKzXz6o5ro9cYKF8ru/aSEDW9F5n0qOZwb8/DHLQB
2gJtgrYRxLczMxYCT5Z5+VQ5KqC+nSMGxMRymFSyYjmQiovBMEJQBJao5ByJsMm1feDAmkObxteZ8Mac
BgltVjScHb3ZY07HvR7zOh/1/KJLqve33c9Sb33Bd0nvS77L+lylodU1v5X9r7F/L+1zyWdJ7wveC3ue
9VzQNdVzbqcj9d9rs7deTMtNbuPfWF5zyMtzavTSJ7zQ2n9g+cAab5WoVLoxfltxHfy6fEsips8JbxDX
K0mPe1R6e17O5MmtIL6dmlIIqGCojQpYwYj4FwThIwMmfpAYutPRwVMSBA2TIAqMECUNVSWlKDgQc4Ok
wSWcy0SWdavazNn/xRYu4XXauujdol2iGr7DgH/T/8PfcAyOxXfk7/K4XQnp92g4wzw8/UR4wwjvqMPC
NDyFhWvGtXNPj3vCveEe1by9sqojiG/nxoWgHBVQ1zYWA7wkQgQkhoiTlYKQRgiETI6OXlgmwIRRsVxg
yaoVA5k44IlzCyR/wHcRikFsVcsFOlQsGSgRXX7WVorjuYdXEh7XimvGteMejEmPe1V6e058YUXMuLcD
AfiooBQDJnwQImDyB3EyFwS29UAogaoJauUgHkIMJJUgIzwwiIkH+z1lgfiw3ILNRcjzEbkg/T8/jn0H
38U5pHPhnDg3fgO/hd/Eb+MacC24Jk54XCuuGdeOezAmvfD2wh4zU2JAiMBzBi4IPkJgIRjCChAPIQa8
LsgIDwxiwhuDpKi0cJFwwGMrofwbjsV38F2cA+fCOXFu/AZ+C7+J38Y1cA/PCc9jely7IL2wfJtSDGqC
4CMEiIawAmVDEBBeF4klPDCICW8MkmIyDoTlQuGA1waU/8ePw3fwXZwD58I5cW78Bn4Lv4nfxjVwD69G
eEF6Yc9knDzGglATBbwuyMjFAW8MknKRwEPzEUQN/O+c3AD36Py8+A01sqsRHhAmzOymJBgnnbEwuDg4
QFgOEFgNymOU3+XnMyY6oLwWYcKsYkoSKqEkqjE4mdVIbQy1cwPCnsl0uv8DRYFFJOEP/tsAAAAASUVO
RK5CYII=
</value>
</data>
<data name="logoPictureBox.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 3</value>
</data>
<data name="logoPictureBox.Size" type="System.Drawing.Size, System.Drawing">
<value>219, 259</value>
</data>
<data name="logoPictureBox.SizeMode" type="System.Windows.Forms.PictureBoxSizeMode, System.Windows.Forms">
<value>CenterImage</value>
</data>
<data name="logoPictureBox.TabIndex" type="System.Int32, mscorlib">
<value>12</value>
</data>
<data name="&gt;&gt;logoPictureBox.Name" xml:space="preserve">
<value>logoPictureBox</value>
</data>
<data name="&gt;&gt;logoPictureBox.Type" xml:space="preserve">
<value>System.Windows.Forms.PictureBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;logoPictureBox.Parent" xml:space="preserve">
<value>tableLayoutPanel</value>
</data>
<data name="&gt;&gt;logoPictureBox.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="labelProductName.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="labelProductName.Location" type="System.Drawing.Point, System.Drawing">
<value>231, 0</value>
</data>
<data name="labelProductName.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>6, 0, 3, 0</value>
</data>
<data name="labelProductName.Size" type="System.Drawing.Size, System.Drawing">
<value>256, 26</value>
</data>
<data name="labelProductName.TabIndex" type="System.Int32, mscorlib">
<value>19</value>
</data>
<data name="labelProductName.Text" xml:space="preserve">
<value>Product Name</value>
</data>
<data name="labelProductName.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
<value>MiddleLeft</value>
</data>
<data name="&gt;&gt;labelProductName.Name" xml:space="preserve">
<value>labelProductName</value>
</data>
<data name="&gt;&gt;labelProductName.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;labelProductName.Parent" xml:space="preserve">
<value>tableLayoutPanel</value>
</data>
<data name="&gt;&gt;labelProductName.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="labelVersion.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="labelVersion.Location" type="System.Drawing.Point, System.Drawing">
<value>231, 26</value>
</data>
<data name="labelVersion.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>6, 0, 3, 0</value>
</data>
<data name="labelVersion.Size" type="System.Drawing.Size, System.Drawing">
<value>256, 26</value>
</data>
<data name="labelVersion.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="labelVersion.Text" xml:space="preserve">
<value>Version</value>
</data>
<data name="labelVersion.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
<value>MiddleLeft</value>
</data>
<data name="&gt;&gt;labelVersion.Name" xml:space="preserve">
<value>labelVersion</value>
</data>
<data name="&gt;&gt;labelVersion.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;labelVersion.Parent" xml:space="preserve">
<value>tableLayoutPanel</value>
</data>
<data name="&gt;&gt;labelVersion.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<data name="labelCopyright.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="labelCopyright.Location" type="System.Drawing.Point, System.Drawing">
<value>231, 52</value>
</data>
<data name="labelCopyright.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>6, 0, 3, 0</value>
</data>
<data name="labelCopyright.Size" type="System.Drawing.Size, System.Drawing">
<value>256, 26</value>
</data>
<data name="labelCopyright.TabIndex" type="System.Int32, mscorlib">
<value>21</value>
</data>
<data name="labelCopyright.Text" xml:space="preserve">
<value>Copyright</value>
</data>
<data name="labelCopyright.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
<value>MiddleLeft</value>
</data>
<data name="&gt;&gt;labelCopyright.Name" xml:space="preserve">
<value>labelCopyright</value>
</data>
<data name="&gt;&gt;labelCopyright.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;labelCopyright.Parent" xml:space="preserve">
<value>tableLayoutPanel</value>
</data>
<data name="&gt;&gt;labelCopyright.ZOrder" xml:space="preserve">
<value>3</value>
</data>
<data name="okButton.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom, Right</value>
</data>
<data name="okButton.Location" type="System.Drawing.Point, System.Drawing">
<value>412, 239</value>
</data>
<data name="okButton.Size" type="System.Drawing.Size, System.Drawing">
<value>75, 23</value>
</data>
<data name="okButton.TabIndex" type="System.Int32, mscorlib">
<value>24</value>
</data>
<data name="okButton.Text" xml:space="preserve">
<value>&amp;ОК</value>
</data>
<data name="&gt;&gt;okButton.Name" xml:space="preserve">
<value>okButton</value>
</data>
<data name="&gt;&gt;okButton.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;okButton.Parent" xml:space="preserve">
<value>tableLayoutPanel</value>
</data>
<data name="&gt;&gt;okButton.ZOrder" xml:space="preserve">
<value>4</value>
</data>
<data name="textBoxDescription.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="textBoxDescription.Location" type="System.Drawing.Point, System.Drawing">
<value>231, 107</value>
</data>
<data name="textBoxDescription.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>6, 3, 3, 3</value>
</data>
<data name="textBoxDescription.Multiline" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="textBoxDescription.ScrollBars" type="System.Windows.Forms.ScrollBars, System.Windows.Forms">
<value>Both</value>
</data>
<data name="textBoxDescription.Size" type="System.Drawing.Size, System.Drawing">
<value>256, 126</value>
</data>
<data name="textBoxDescription.TabIndex" type="System.Int32, mscorlib">
<value>23</value>
</data>
<data name="textBoxDescription.Text" xml:space="preserve">
<value>Description</value>
</data>
<data name="&gt;&gt;textBoxDescription.Name" xml:space="preserve">
<value>textBoxDescription</value>
</data>
<data name="&gt;&gt;textBoxDescription.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;textBoxDescription.Parent" xml:space="preserve">
<value>tableLayoutPanel</value>
</data>
<data name="&gt;&gt;textBoxDescription.ZOrder" xml:space="preserve">
<value>5</value>
</data>
<data name="linkLabel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="linkLabel1.Location" type="System.Drawing.Point, System.Drawing">
<value>231, 78</value>
</data>
<data name="linkLabel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>6, 0, 3, 0</value>
</data>
<data name="linkLabel1.Size" type="System.Drawing.Size, System.Drawing">
<value>256, 26</value>
</data>
<data name="linkLabel1.TabIndex" type="System.Int32, mscorlib">
<value>25</value>
</data>
<data name="linkLabel1.Text" xml:space="preserve">
<value>Github Repo</value>
</data>
<data name="linkLabel1.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
<value>MiddleLeft</value>
</data>
<data name="&gt;&gt;linkLabel1.Name" xml:space="preserve">
<value>linkLabel1</value>
</data>
<data name="&gt;&gt;linkLabel1.Type" xml:space="preserve">
<value>System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;linkLabel1.Parent" xml:space="preserve">
<value>tableLayoutPanel</value>
</data>
<data name="&gt;&gt;linkLabel1.ZOrder" xml:space="preserve">
<value>6</value>
</data>
<data name="tableLayoutPanel.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="tableLayoutPanel.Location" type="System.Drawing.Point, System.Drawing">
<value>9, 9</value>
</data>
<data name="tableLayoutPanel.RowCount" type="System.Int32, mscorlib">
<value>6</value>
</data>
<data name="tableLayoutPanel.Size" type="System.Drawing.Size, System.Drawing">
<value>490, 265</value>
</data>
<data name="tableLayoutPanel.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="&gt;&gt;tableLayoutPanel.Name" xml:space="preserve">
<value>tableLayoutPanel</value>
</data>
<data name="&gt;&gt;tableLayoutPanel.Type" xml:space="preserve">
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;tableLayoutPanel.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;tableLayoutPanel.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="tableLayoutPanel.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="logoPictureBox" Row="0" RowSpan="6" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="labelProductName" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="labelVersion" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="labelCopyright" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="okButton" Row="5" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="textBoxDescription" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="linkLabel1" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,46,0039,Percent,53,9961" /&gt;&lt;Rows Styles="Percent,10,Percent,10,Percent,10,Percent,10,Percent,50,Percent,10" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
<value>6, 13</value>
</data>
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
<value>508, 283</value>
</data>
<data name="$this.Font" type="System.Drawing.Font, System.Drawing">
<value>Segoe UI, 8.25pt</value>
</data>
<data name="$this.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>9, 9, 9, 9</value>
</data>
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
<value>CenterParent</value>
</data>
<data name="$this.Text" xml:space="preserve">
<value>About</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>FormAboutBox</value>
</data>
<data name="&gt;&gt;$this.Type" xml:space="preserve">
<value>System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
</root>
-138
View File
@@ -1,138 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="labelProductName.Text" xml:space="preserve">
<value>Название продукта</value>
</data>
<data name="labelVersion.Text" xml:space="preserve">
<value>Версия</value>
</data>
<data name="labelCopyright.Text" xml:space="preserve">
<value>Авторские права</value>
</data>
<data name="linkLabel1.Text" xml:space="preserve">
<value>Сайт</value>
</data>
<data name="textBoxDescription.Text" xml:space="preserve">
<value>Описание</value>
</data>
<data name="$this.Text" xml:space="preserve">
<value>О программе</value>
</data>
</root>
-138
View File
@@ -1,138 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="labelProductName.Text" xml:space="preserve">
<value>Tên phần mềm</value>
</data>
<data name="labelVersion.Text" xml:space="preserve">
<value>Phiên bản</value>
</data>
<data name="labelCopyright.Text" xml:space="preserve">
<value>Bản quyền</value>
</data>
<data name="textBoxDescription.Text" xml:space="preserve">
<value>Mô tả</value>
</data>
<data name="linkLabel1.Text" xml:space="preserve">
<value>Kho Github</value>
</data>
<data name="$this.Text" xml:space="preserve">
<value>Giới thiệu</value>
</data>
</root>
-138
View File
@@ -1,138 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="labelProductName.Text" xml:space="preserve">
<value>软件名</value>
</data>
<data name="labelVersion.Text" xml:space="preserve">
<value>版本</value>
</data>
<data name="labelCopyright.Text" xml:space="preserve">
<value>版权</value>
</data>
<data name="textBoxDescription.Text" xml:space="preserve">
<value>描述</value>
</data>
<data name="linkLabel1.Text" xml:space="preserve">
<value>Github 仓库</value>
</data>
<data name="$this.Text" xml:space="preserve">
<value>关于</value>
</data>
</root>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-353
View File
@@ -1,353 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="checkBox_DECODE_UseFramework.Text" xml:space="preserve">
<value>Использовать файлы фремворка из:</value>
</data>
<data name="checkBox_DECODE_Force.Text" xml:space="preserve">
<value>Перезаписывать файлы в каталоге назначения</value>
</data>
<data name="checkBox_DECODE_NoRes.Text" xml:space="preserve">
<value>Не декомпилировать ресурсы</value>
</data>
<data name="checkBox_DECODE_NoSrc.Text" xml:space="preserve">
<value>Не декомпилировать исходный код</value>
</data>
<data name="checkBox_BUILD_UseAapt.Text" xml:space="preserve">
<value>Использовать aapt.exe из</value>
</data>
<data name="checkBox_BUILD_ForceAll.Text" xml:space="preserve">
<value>Пропустить определение изменений и построить все файлы</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="radioButtonFileZipalign.Size" type="System.Drawing.Size, System.Drawing">
<value>57, 18</value>
</data>
<data name="ColumnTime.HeaderText" xml:space="preserve">
<value>Время</value>
</data>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="ColumnTime.Width" type="System.Int32, mscorlib">
<value>65</value>
</data>
<data name="ColumnMessage.HeaderText" xml:space="preserve">
<value>Сообщение</value>
</data>
<data name="clearLogToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>171, 22</value>
</data>
<data name="clearLogToolStripMenuItem.Text" xml:space="preserve">
<value>Очистить журнал</value>
</data>
<data name="contextMenuStripLog.Size" type="System.Drawing.Size, System.Drawing">
<value>172, 26</value>
</data>
<data name="menuItemSettings.Text" xml:space="preserve">
<value>Настройки</value>
</data>
<data name="menuItemExit.Text" xml:space="preserve">
<value>Выход</value>
</data>
<data name="menuItemFile.Text" xml:space="preserve">
<value>Файл</value>
</data>
<data name="menuItemCheckUpdate.Text" xml:space="preserve">
<value>Проверить обновление</value>
</data>
<data name="menuItemAbout.Text" xml:space="preserve">
<value>О программе</value>
</data>
<data name="menuItemHelp.Text" xml:space="preserve">
<value>Справка</value>
</data>
<data name="button_BUILD_Build.Text" xml:space="preserve">
<value>Собрать</value>
</data>
<data name="button_DECODE_Decode.Text" xml:space="preserve">
<value>Декомпилировать</value>
</data>
<data name="tabPageZipAlign.Text" xml:space="preserve">
<value>Выравнивание</value>
</data>
<data name="tabPageSign.Text" xml:space="preserve">
<value>Подпись</value>
</data>
<data name="toolStripStatusLabelStateText.Text" xml:space="preserve">
<value>Загрузка...</value>
</data>
<data name="openFileDialogSignApk.Title" xml:space="preserve">
<value>Выберите файл для подписи</value>
</data>
<data name="checkBox_BUILD_CopyOriginal.Text" xml:space="preserve">
<value>Копировать оригинальный AndroidManifest.xml и папку META-INF в построенный apk</value>
</data>
<data name="checkBox_BUILD_UseFramework.Text" xml:space="preserve">
<value>Использовать файлы фремворка из:</value>
</data>
<data name="checkBox_DECODE_KeepBrokenRes.Text" xml:space="preserve">
<value>Сохранить испорченные ресурсы</value>
</data>
<data name="tabPageBuild.Text" xml:space="preserve">
<value>Сборка</value>
</data>
<data name="tabPageDecode.Text" xml:space="preserve">
<value>Декомпиляция</value>
</data>
<data name="checkBox_DECODE_OutputDirectory.Text" xml:space="preserve">
<value>Декомпилировать в каталог:</value>
</data>
<data name="checkBox_BUILD_OutputAppPath.Text" xml:space="preserve">
<value>Сохранить файл как:</value>
</data>
<data name="tabPageInstallFramework.Text" xml:space="preserve">
<value>Установка фреймворков</value>
</data>
<data name="groupBox_BUILD_Options.Text" xml:space="preserve">
<value>Опции</value>
</data>
<data name="groupBox_DECODE_Options.Text" xml:space="preserve">
<value>Опции</value>
</data>
<data name="groupBox_IF_Options.Text" xml:space="preserve">
<value>Опции</value>
</data>
<data name="button_IF_InstallFramework.Text" xml:space="preserve">
<value>Установить</value>
</data>
<data name="button_ZIPALIGN_Align.Text" xml:space="preserve">
<value>Выровнять</value>
</data>
<data name="label_ZIPALIGN_OutputFile.Text" xml:space="preserve">
<value>Сохранить файл как:</value>
</data>
<data name="groupBox_ZIPALIGN_Options.Text" xml:space="preserve">
<value>Опции</value>
</data>
<data name="checkBox_ZIPALIGN_OverwriteOutputFile.Text" xml:space="preserve">
<value>Перезаписать выходной файл, если он существует</value>
</data>
<data name="button_SIGN_Sign.Text" xml:space="preserve">
<value>Подписать</value>
</data>
<data name="checkBox_IF_FramePath.Text" xml:space="preserve">
<value>Устанавливать фреймворк в каталог:</value>
</data>
<data name="checkBox_ZIPALIGN_Recompress.Text" xml:space="preserve">
<value>Перепаковать с использованием алгоритма Zopfli</value>
</data>
<data name="checkBox_ZIPALIGN_VerboseOutput.Text" xml:space="preserve">
<value>Подробный вывод</value>
</data>
<data name="label_ZIPALIGN_AlignmentBytes.Text" xml:space="preserve">
<value>Выравнивание (в байтах), например, '4' для 32-битного выравнивания</value>
</data>
<data name="checkBox_DECODE_MatchOriginal.Text" xml:space="preserve">
<value>Сохранять файлы близко к оригиналу, насколько это возможно. Предотвращает ребилд.</value>
</data>
<data name="checkBox_ZIPALIGN_CheckAlignment.Text" xml:space="preserve">
<value>Только проверить выравнивание (не модифицирует файл)</value>
</data>
<data name="groupBox_SIGN_Options.Text" xml:space="preserve">
<value>Опции</value>
</data>
<data name="label_SIGN_OutputFile.Text" xml:space="preserve">
<value>Сохранить файл как:</value>
</data>
<data name="label_SIGN_PrivateKey.Text" xml:space="preserve">
<value>Закрытый ключ</value>
</data>
<data name="label_SIGN_PublicKey.Text" xml:space="preserve">
<value>Открытый ключ</value>
</data>
<data name="tabPageMain.Text" xml:space="preserve">
<value>Главная</value>
</data>
<data name="tabPageApkInfo.Text" xml:space="preserve">
<value>Инфо APK</value>
</data>
<data name="checkBox4.Text" xml:space="preserve">
<value>Количество потоков:</value>
</data>
<data name="checkBox_BUILD_NetSecConf.Text" xml:space="preserve">
<value>Добавить файл конфигурации сетевой безопасности (Network Security Configuration)</value>
</data>
<data name="useAapt2ChkBox.Text" xml:space="preserve">
<value>Использовать aapt2 (для версий apktool &lt; 2.11.1)</value>
</data>
<data name="buildSetApiLvlChkBox.Text" xml:space="preserve">
<value>Установить уровень API (напр. 14 для ICS)</value>
</data>
<data name="createUnsignApkChkBox.Text" xml:space="preserve">
<value>Создать неподписанный APK с оригинальной подписью (Core Patch)</value>
</data>
<data name="signAfterBuildChkBox.Text" xml:space="preserve">
<value>Подписать после сборки / выравнивания</value>
</data>
<data name="zipalignAfterBuildChkBox.Text" xml:space="preserve">
<value>Выровнять после сборки</value>
</data>
<data name="checkBox_BUILD_NoCrunch.Text" xml:space="preserve">
<value>Отключить сжатие ресурсов</value>
</data>
<data name="tabPageBaksmali.Text" xml:space="preserve">
<value>Baksmali / Smali</value>
</data>
<data name="tabPageAdb.Text" xml:space="preserve">
<value>ADB</value>
</data>
<data name="mergeApkBtn.Text" xml:space="preserve">
<value>Слияние APK</value>
</data>
<data name="selSplitApkBtn.Text" xml:space="preserve">
<value>Выбрать Split APK</value>
</data>
<data name="baksmaliUseOutputChkBox.Text" xml:space="preserve">
<value>Свой каталог вывода:</value>
</data>
<data name="smaliUseOutputChkBox.Text" xml:space="preserve">
<value>Свой каталог вывода:</value>
</data>
<data name="killAdbBtn.Text" xml:space="preserve">
<value>Перезапустить ADB</value>
</data>
<data name="installApkBtn.Text" xml:space="preserve">
<value>Установить APK</value>
</data>
<data name="refreshDevicesBtn.Text" xml:space="preserve">
<value>Обновить список</value>
</data>
<data name="selApkAdbBtn.Text" xml:space="preserve">
<value>Выбрать APK</value>
</data>
<data name="overrideAbiCheckBox.Text" xml:space="preserve">
<value>Переопределить ABI:</value>
</data>
<data name="bakSmaliGroupBox.Text" xml:space="preserve">
<value>Baksmali (DEX -&gt; Smali)</value>
</data>
<data name="smaliGroupBox.Text" xml:space="preserve">
<value>Smali (Smali -&gt; DEX)</value>
</data>
<data name="decSmaliBtn.Text" xml:space="preserve">
<value>Дизассемблировать</value>
</data>
<data name="comSmaliBtn.Text" xml:space="preserve">
<value>Ассемблировать</value>
</data>
</root>
-549
View File
@@ -1,549 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="splitApkTxt.Text" xml:space="preserve">
<value>Hợp nhất các tệp APK bị chia nhỏ thành một tệp APK duy nhất:</value>
</data>
<data name="mergeApkBtn.Text" xml:space="preserve">
<value>Hợp nhất</value>
</data>
<data name="comApkOpenDir.Text" xml:space="preserve">
<value>Thư mục APK đã biên dịch</value>
</data>
<data name="decOutOpenDirBtn.Text" xml:space="preserve">
<value>Thư mục đầu ra dịch ngược</value>
</data>
<data name="signApkOpenDirBtn.Text" xml:space="preserve">
<value>Thư mục APK đã ký</value>
</data>
<data name="alignApkOpenDirBtn.Text" xml:space="preserve">
<value>Thư mục APK đã Zipalign</value>
</data>
<data name="decApkOpenDirBtn.Text" xml:space="preserve">
<value>Thư mục APK đã dịch ngược</value>
</data>
<data name="compileOutputOpenDirBtn.Text" xml:space="preserve">
<value>Thư mục đầu ra biên dịch</value>
</data>
<data name="button_OpenMainActivity.Text" xml:space="preserve">
<value>Smali của Activity khởi động</value>
</data>
<data name="label4.Text" xml:space="preserve">
<value>Ký APK:</value>
</data>
<data name="button_SIGN_Sign.Text" xml:space="preserve">
<value>Ký</value>
</data>
<data name="label3.Text" xml:space="preserve">
<value>Zipalign tệp APK:</value>
</data>
<data name="button_ZIPALIGN_Align.Text" xml:space="preserve">
<value>Zipalign</value>
</data>
<data name="label2.Text" xml:space="preserve">
<value>Thư mục APK đã dịch ngược:</value>
</data>
<data name="button_BUILD_Build.Text" xml:space="preserve">
<value>Biên dịch</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>Tệp APK/XAPK/APKS/ZIP/APKM:</value>
</data>
<data name="button_DECODE_Decode.Text" xml:space="preserve">
<value>Dịch ngược</value>
</data>
<data name="tabPageMain.Text" xml:space="preserve">
<value>Trang chính</value>
</data>
<data name="label31.Text" xml:space="preserve">
<value>Activity khởi động:</value>
</data>
<data name="label30.Text" xml:space="preserve">
<value>Kiến trúc:</value>
</data>
<data name="label17.Text" xml:space="preserve">
<value>Tệp:</value>
</data>
<data name="label18.Text" xml:space="preserve">
<value>Bản địa hóa:</value>
</data>
<data name="label15.Text" xml:space="preserve">
<value>Quyền:</value>
</data>
<data name="label14.Text" xml:space="preserve">
<value>Mật độ (DPI):</value>
</data>
<data name="label19.Text" xml:space="preserve">
<value>Liên kết cửa hàng:</value>
</data>
<data name="label7.Text" xml:space="preserve">
<value>Tên ứng dụng:</value>
</data>
<data name="label9.Text" xml:space="preserve">
<value>Tên gói ứng dụng:</value>
</data>
<data name="label8.Text" xml:space="preserve">
<value>Phiên bản:</value>
</data>
<data name="label11.Text" xml:space="preserve">
<value>SDK tương thích tối thiểu:</value>
</data>
<data name="label10.Text" xml:space="preserve">
<value>Tên mã:</value>
</data>
<data name="label13.Text" xml:space="preserve">
<value>Kích thước màn hình</value>
</data>
<data name="label12.Text" xml:space="preserve">
<value>SDK mục tiêu:</value>
</data>
<data name="basicInfoTabPage.Text" xml:space="preserve">
<value>Thông tin cơ bản</value>
</data>
<data name="tabPage3.Text" xml:space="preserve">
<value>Thông tin đầy đủ</value>
</data>
<data name="tabPageApkInfo.Text" xml:space="preserve">
<value>Thông tin APK</value>
</data>
<data name="checkBox7.Text" xml:space="preserve">
<value>Không phân tích thông tin APK khi chọn APK để dịch ngược</value>
</data>
<data name="decSetApiLvlChkBox.Text" xml:space="preserve">
<value>Đặt cấp độ API cho các tệp sẽ được tạo, ví dụ: 14 cho ICS.</value>
</data>
<data name="checkBox_DECODE_FixError.Text" xml:space="preserve">
<value>Sửa lỗi ApkTool sau khi dịch ngược</value>
</data>
<data name="checkBox_DECODE_FixError.ToolTip" xml:space="preserve">
<value>Sẽ xóa extractNativeLibs, useEmbeddedDex, APKTOOL_DUMMY, các thuộc tính liên quan đến split và đặt sparseresource thành false</value>
</data>
<data name="checkBox_DECODE_OnlyMainClasses.Text" xml:space="preserve">
<value>Chỉ dịch ngược các tệp dex chính trong thư mục gốc (classes[0-9]*.dex).</value>
</data>
<data name="checkBox_DECODE_OnlyMainClasses.ToolTip" xml:space="preserve">
<value>Sửa lỗi ApkTool bất thường</value>
</data>
<data name="checkBox_DECODE_UseFramework.Text" xml:space="preserve">
<value>Sử dụng vị trí tệp framework:</value>
</data>
<data name="checkBox_DECODE_MatchOriginal.Text" xml:space="preserve">
<value>Giữ các tệp gần với bản gốc nhất có thể, ngăn việc xây dựng lại</value>
</data>
<data name="checkBox_DECODE_OutputDirectory.Text" xml:space="preserve">
<value>Thư mục đầu ra:</value>
</data>
<data name="checkBox_DECODE_KeepBrokenRes.Text" xml:space="preserve">
<value>Giữ lại tài nguyên bị hỏng</value>
</data>
<data name="checkBox_DECODE_NoSrc.Text" xml:space="preserve">
<value>Không dịch ngược mã nguồn</value>
</data>
<data name="checkBox_DECODE_Force.Text" xml:space="preserve">
<value>Buộc xóa thư mục đích</value>
</data>
<data name="checkBox_DECODE_NoRes.Text" xml:space="preserve">
<value>Không dịch ngược tài nguyên (resources)</value>
</data>
<data name="checkBox_DECODE_NoDebugInfo.Text" xml:space="preserve">
<value>Không xuất thông tin gỡ lỗi (.local, .param, .line, v.v.)</value>
</data>
<data name="groupBox_DECODE_Options.Text" xml:space="preserve">
<value>Tùy chọn</value>
</data>
<data name="tabPageDecode.Text" xml:space="preserve">
<value>Dịch ngược</value>
</data>
<data name="checkBox_BUILD_NetSecConf.Text" xml:space="preserve">
<value>Thêm cấu hình bảo mật mạng chung vào APK đầu ra</value>
</data>
<data name="useAapt2ChkBox.Text" xml:space="preserve">
<value>Sử dụng aapt2 (Nâng cấp apktool để sử dụng tệp nhị phân aapt2 thử nghiệm)</value>
</data>
<data name="buildSetApiLvlChkBox.Text" xml:space="preserve">
<value>Đặt cấp độ API cho các tệp sẽ được tạo, ví dụ: 14 cho ICS.</value>
</data>
<data name="createUnsignApkChkBox.Text" xml:space="preserve">
<value>Tạo APK chưa ký với chữ ký gốc sau khi biên dịch</value>
</data>
<data name="createUnsignApkChkBox.ToolTip" xml:space="preserve">
<value>Chỉ tương thích với các mô-đun vá lõi, yêu cầu thiết bị đã root.</value>
</data>
<data name="signAfterBuildChkBox.Text" xml:space="preserve">
<value>Ký sau khi Biên dịch/Zipalign</value>
</data>
<data name="zipalignAfterBuildChkBox.Text" xml:space="preserve">
<value>Zipalign sau khi biên dịch</value>
</data>
<data name="checkBox_BUILD_NoCrunch.Text" xml:space="preserve">
<value>Vô hiệu hóa việc xử lý các tệp tài nguyên trong bước biên dịch</value>
</data>
<data name="checkBox_BUILD_ForceAll.Text" xml:space="preserve">
<value>Bỏ qua kiểm tra thay đổi và biên dịch tất cả các tệp</value>
</data>
<data name="checkBox_BUILD_OutputAppPath.Text" xml:space="preserve">
<value>Thư mục đầu ra APK</value>
</data>
<data name="checkBox_BUILD_OutputAppPath.ToolTip" xml:space="preserve">
<value>Thư mục đầu ra đã biên dịch cũng sẽ được sử dụng cho Zipalign và ký</value>
</data>
<data name="checkBox_BUILD_CopyOriginal.Text" xml:space="preserve">
<value>Sao chép thư mục AndroidManifest.xml và META-INF gốc</value>
</data>
<data name="checkBox_BUILD_UseAapt.Text" xml:space="preserve">
<value>Sử dụng vị trí tệp aapt.exe:</value>
</data>
<data name="checkBox_BUILD_UseFramework.Text" xml:space="preserve">
<value>Sử dụng vị trí tệp framework:</value>
</data>
<data name="groupBox_BUILD_Options.Text" xml:space="preserve">
<value>Tùy chọn</value>
</data>
<data name="tabPageBuild.Text" xml:space="preserve">
<value>Biên dịch</value>
</data>
<data name="checkBox2.Text" xml:space="preserve">
<value>Cài đặt APK sau khi ký (đảm bảo đã chọn thiết bị trong tùy chọn ADB trước)</value>
</data>
<data name="checkBox1.Text" xml:space="preserve">
<value>Ghi đè tệp đầu vào</value>
</data>
<data name="autoDelIdsigChkBox.Text" xml:space="preserve">
<value>Tự động xóa tệp idsig</value>
</data>
<data name="schemev4ComboBox.Items" xml:space="preserve">
<value>Mặc định</value>
</data>
<data name="schemev4ComboBox.Items1" xml:space="preserve">
<value>Bật</value>
</data>
<data name="schemev4ComboBox.Items2" xml:space="preserve">
<value>Tắt</value>
</data>
<data name="label27.Text" xml:space="preserve">
<value>Lược đồ ký v4:</value>
</data>
<data name="schemev3ComboBox.Items" xml:space="preserve">
<value>Mặc định</value>
</data>
<data name="schemev3ComboBox.Items1" xml:space="preserve">
<value>Bật</value>
</data>
<data name="schemev3ComboBox.Items2" xml:space="preserve">
<value>Tắt</value>
</data>
<data name="label26.Text" xml:space="preserve">
<value>Lược đồ ký v3:</value>
</data>
<data name="schemev2ComboBox.Items" xml:space="preserve">
<value>Mặc định</value>
</data>
<data name="schemev2ComboBox.Items1" xml:space="preserve">
<value>Bật</value>
</data>
<data name="schemev2ComboBox.Items2" xml:space="preserve">
<value>Tắt</value>
</data>
<data name="label25.Text" xml:space="preserve">
<value>Lược đồ ký v2:</value>
</data>
<data name="schemev1ComboBox.Items" xml:space="preserve">
<value>Mặc định</value>
</data>
<data name="schemev1ComboBox.Items1" xml:space="preserve">
<value>Bật</value>
</data>
<data name="schemev1ComboBox.Items2" xml:space="preserve">
<value>Tắt</value>
</data>
<data name="label24.Text" xml:space="preserve">
<value>Lược đồ ký v1:</value>
</data>
<data name="useAliasChkBox.Text" xml:space="preserve">
<value>Tên bí danh (Alias)</value>
</data>
<data name="label22.Text" xml:space="preserve">
<value>Rất khuyến khích bạn sử dụng khóa của riêng mình, được tạo bằng Android Studio hoặc các công cụ khác</value>
</data>
<data name="label21.Text" xml:space="preserve">
<value>Mật khẩu:</value>
</data>
<data name="label20.Text" xml:space="preserve">
<value>Tệp keystore/jks:</value>
</data>
<data name="useKeyStoreChkBox.Text" xml:space="preserve">
<value>Sử dụng keystore</value>
</data>
<data name="useSigningOutputDir.Text" xml:space="preserve">
<value>Thư mục đầu ra APK:</value>
</data>
<data name="label_SIGN_PrivateKey.Text" xml:space="preserve">
<value>Khóa riêng:</value>
</data>
<data name="label_SIGN_PublicKey.Text" xml:space="preserve">
<value>Khóa công khai:</value>
</data>
<data name="groupBox_SIGN_Options.Text" xml:space="preserve">
<value>Tùy chọn</value>
</data>
<data name="tabPageSign.Text" xml:space="preserve">
<value>Ký</value>
</data>
<data name="zipalignOutputDirChkBox.Text" xml:space="preserve">
<value>Thư mục đầu ra APK:</value>
</data>
<data name="signAfterZipalignChkBox.Text" xml:space="preserve">
<value>Ký sau khi zipalign</value>
</data>
<data name="checkBox_ZIPALIGN_Recompress.Text" xml:space="preserve">
<value>Nén lại bằng Zopfli</value>
</data>
<data name="label_ZIPALIGN_AlignmentBytes.Text" xml:space="preserve">
<value>Căn chỉnh theo byte, ví dụ: '4' cung cấp căn chỉnh 32-bit</value>
</data>
<data name="checkBox_ZIPALIGN_CheckAlignment.Text" xml:space="preserve">
<value>Chỉ kiểm tra căn chỉnh (không sửa đổi tệp)</value>
</data>
<data name="checkBox_ZIPALIGN_VerboseOutput.Text" xml:space="preserve">
<value>Đầu ra chi tiết</value>
</data>
<data name="checkBox_ZIPALIGN_OverwriteOutputFile.Text" xml:space="preserve">
<value>Ghi đè tệp đầu ra hiện có</value>
</data>
<data name="groupBox_ZIPALIGN_Options.Text" xml:space="preserve">
<value>Tùy chọn</value>
</data>
<data name="tabPageZipAlign.Text" xml:space="preserve">
<value>Zipalign</value>
</data>
<data name="openFwFolderBtn.Text" xml:space="preserve">
<value>Mở thư mục framework</value>
</data>
<data name="clearFwBtn.Text" xml:space="preserve">
<value>Xóa bộ nhớ đệm framework</value>
</data>
<data name="clearFwBeforeDecodeChkBox.Text" xml:space="preserve">
<value>Xóa bộ nhớ đệm Framework trước khi dịch ngược</value>
</data>
<data name="groupBox1.Text" xml:space="preserve">
<value>Tùy chọn</value>
</data>
<data name="checkBox_IF_Tag.Text" xml:space="preserve">
<value>Gắn thẻ frameworks bằng:</value>
</data>
<data name="checkBox_IF_FramePath.Text" xml:space="preserve">
<value>Lưu trữ tệp framework vào:</value>
</data>
<data name="button_IF_InstallFramework.Text" xml:space="preserve">
<value>Cài đặt</value>
</data>
<data name="groupBox_IF_Options.Text" xml:space="preserve">
<value>Tùy chọn</value>
</data>
<data name="label29.Text" xml:space="preserve">
<value>Thư mục biên dịch Smali:</value>
</data>
<data name="smaliUseOutputChkBox.Text" xml:space="preserve">
<value>Thư mục đầu ra Dex:</value>
</data>
<data name="comSmaliBtn.Text" xml:space="preserve">
<value>Biên dịch</value>
</data>
<data name="label28.Text" xml:space="preserve">
<value>Dịch ngược Dex:</value>
</data>
<data name="baksmaliUseOutputChkBox.Text" xml:space="preserve">
<value>Thư mục đầu ra:</value>
</data>
<data name="decSmaliBtn.Text" xml:space="preserve">
<value>Dịch ngược</value>
</data>
<data name="label33.Text" xml:space="preserve">
<value>Chọn thiết bị</value>
</data>
<data name="killAdbBtn.Text" xml:space="preserve">
<value>Dừng tiến trình ADB</value>
</data>
<data name="installApkBtn.Text" xml:space="preserve">
<value>Cài đặt APK</value>
</data>
<data name="refreshDevicesBtn.Text" xml:space="preserve">
<value>Làm mới</value>
</data>
<data name="overrideAbiCheckBox.Text" xml:space="preserve">
<value>Ghi đè ABI mặc định của nền tảng:</value>
</data>
<data name="setVendorChkBox.Text" xml:space="preserve">
<value>Đặt nhà cung cấp là Play Store (com.android.vending)</value>
</data>
<data name="label32.Text" xml:space="preserve">
<value>Chọn APK: </value>
</data>
<data name="toolStripStatusLabelStateText.Text" xml:space="preserve">
<value>Đang tải...</value>
</data>
<data name="clearLogToolStripMenuItem.Text" xml:space="preserve">
<value>Xóa nhật ký</value>
</data>
<data name="newInsToolStripMenuItem.Text" xml:space="preserve">
<value>Tiến trình mới</value>
</data>
<data name="saveLogToFileToolStripMenuItem.Text" xml:space="preserve">
<value>Lưu nhật ký</value>
</data>
<data name="openTempFolderToolStripMenuItem.Text" xml:space="preserve">
<value>Mở thư mục tạm</value>
</data>
<data name="clearTempFolderToolStripMenuItem.Text" xml:space="preserve">
<value>Xóa thư mục tạm</value>
</data>
<data name="exitToolStripMenuItem.Text" xml:space="preserve">
<value>Thoát</value>
</data>
<data name="fileToolStripMenuItem.Text" xml:space="preserve">
<value>Tệp</value>
</data>
<data name="useAPKEditorForDecompilingItem.Text" xml:space="preserve">
<value>Sử dụng APKEditor để dịch ngược</value>
</data>
<data name="settingsToolStripMenuItem.Text" xml:space="preserve">
<value>Cài đặt</value>
</data>
<data name="checkForUpdateToolStripMenuItem.Text" xml:space="preserve">
<value>Kiểm tra cập nhật</value>
</data>
<data name="reportAnIsuueToolStripMenuItem.Text" xml:space="preserve">
<value>Báo cáo sự cố</value>
</data>
<data name="apktoolIssuesToolStripMenuItem.Text" xml:space="preserve">
<value>Sự cố Apktool</value>
</data>
<data name="baksmaliIssuesToolStripMenuItem.Text" xml:space="preserve">
<value>Sự cố Baksmali</value>
</data>
<data name="aboutToolStripMenuItem.Text" xml:space="preserve">
<value>Giới thiệu</value>
</data>
<data name="helpToolStripMenuItem.Text" xml:space="preserve">
<value>Trợ giúp</value>
</data>
<data name="checkBox_DECODE_UseApkEditorMerge.Text" xml:space="preserve">
<value>Sử dụng APKEditor.jar để hợp nhất/tách APK (nhanh hơn)</value>
</data>
</root>
-549
View File
@@ -1,549 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="splitApkTxt.Text" xml:space="preserve">
<value>将拆分的 APK 合并为单个 APK:</value>
</data>
<data name="mergeApkBtn.Text" xml:space="preserve">
<value>合并</value>
</data>
<data name="comApkOpenDir.Text" xml:space="preserve">
<value>编译的 APK 目录</value>
</data>
<data name="decOutOpenDirBtn.Text" xml:space="preserve">
<value>反编译输出目录</value>
</data>
<data name="signApkOpenDirBtn.Text" xml:space="preserve">
<value>签名的 APK 目录</value>
</data>
<data name="alignApkOpenDirBtn.Text" xml:space="preserve">
<value>Zip 对齐的 APK 目录</value>
</data>
<data name="decApkOpenDirBtn.Text" xml:space="preserve">
<value>反编译的 APK 目录</value>
</data>
<data name="compileOutputOpenDirBtn.Text" xml:space="preserve">
<value>编译输出目录</value>
</data>
<data name="button_OpenMainActivity.Text" xml:space="preserve">
<value>启动项 smail</value>
</data>
<data name="label4.Text" xml:space="preserve">
<value>APK 签名:</value>
</data>
<data name="button_SIGN_Sign.Text" xml:space="preserve">
<value>签名</value>
</data>
<data name="label3.Text" xml:space="preserve">
<value>APK 文件对齐优化:</value>
</data>
<data name="button_ZIPALIGN_Align.Text" xml:space="preserve">
<value>对齐优化</value>
</data>
<data name="label2.Text" xml:space="preserve">
<value>反编译 APK 目录:</value>
</data>
<data name="button_BUILD_Build.Text" xml:space="preserve">
<value>编译</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>APK/XAPK/APKS/ZIP/APKM 文件:</value>
</data>
<data name="button_DECODE_Decode.Text" xml:space="preserve">
<value>反编译</value>
</data>
<data name="tabPageMain.Text" xml:space="preserve">
<value>首页</value>
</data>
<data name="label31.Text" xml:space="preserve">
<value>启动 activity:</value>
</data>
<data name="label30.Text" xml:space="preserve">
<value>架构:</value>
</data>
<data name="label17.Text" xml:space="preserve">
<value>文件:</value>
</data>
<data name="label18.Text" xml:space="preserve">
<value>本地化:</value>
</data>
<data name="label15.Text" xml:space="preserve">
<value>权限:</value>
</data>
<data name="label14.Text" xml:space="preserve">
<value>密度:</value>
</data>
<data name="label19.Text" xml:space="preserve">
<value>商店链接:</value>
</data>
<data name="label7.Text" xml:space="preserve">
<value>应用名:</value>
</data>
<data name="label9.Text" xml:space="preserve">
<value>应用包名:</value>
</data>
<data name="label8.Text" xml:space="preserve">
<value>版本:</value>
</data>
<data name="label11.Text" xml:space="preserve">
<value>最小兼容 SDK:</value>
</data>
<data name="label10.Text" xml:space="preserve">
<value>代号:</value>
</data>
<data name="label13.Text" xml:space="preserve">
<value>屏幕尺寸</value>
</data>
<data name="label12.Text" xml:space="preserve">
<value>目标 SDK:</value>
</data>
<data name="basicInfoTabPage.Text" xml:space="preserve">
<value>基本信息</value>
</data>
<data name="tabPage3.Text" xml:space="preserve">
<value>完整信息</value>
</data>
<data name="tabPageApkInfo.Text" xml:space="preserve">
<value>APK 信息</value>
</data>
<data name="checkBox7.Text" xml:space="preserve">
<value>在选择 APK 进行反编译时,不要解析 APK 信息</value>
</data>
<data name="decSetApiLvlChkBox.Text" xml:space="preserve">
<value>设置要生成的文件的 API 级别,例如 ICS 的 14。</value>
</data>
<data name="checkBox_DECODE_FixError.Text" xml:space="preserve">
<value>修复反编译后的 ApkTool 错误</value>
</data>
<data name="checkBox_DECODE_FixError.ToolTip" xml:space="preserve">
<value>将删除 extractNativeLibs, useEmbeddedDex, APKTOOL_DUMMY,拆分相关属性并将 sparseresource 设置为 false</value>
</data>
<data name="checkBox_DECODE_OnlyMainClasses.Text" xml:space="preserve">
<value>只反汇编根目录中的主索引类(classes[0-9]*.dex)。</value>
</data>
<data name="checkBox_DECODE_OnlyMainClasses.ToolTip" xml:space="preserve">
<value>修复异常的 ApkTool 错误</value>
</data>
<data name="checkBox_DECODE_UseFramework.Text" xml:space="preserve">
<value>使用的 framework 文件位置:</value>
</data>
<data name="checkBox_DECODE_MatchOriginal.Text" xml:space="preserve">
<value>尽可能保持文件最接近原始,防止重建</value>
</data>
<data name="checkBox_DECODE_OutputDirectory.Text" xml:space="preserve">
<value>输出目录:</value>
</data>
<data name="checkBox_DECODE_KeepBrokenRes.Text" xml:space="preserve">
<value>保留损坏资源</value>
</data>
<data name="checkBox_DECODE_NoSrc.Text" xml:space="preserve">
<value>不反编译源码</value>
</data>
<data name="checkBox_DECODE_Force.Text" xml:space="preserve">
<value>强制删除目标目录</value>
</data>
<data name="checkBox_DECODE_NoRes.Text" xml:space="preserve">
<value>不反编译 resouces</value>
</data>
<data name="checkBox_DECODE_NoDebugInfo.Text" xml:space="preserve">
<value>不要输出调试信息(.Local, .param, .line等)</value>
</data>
<data name="groupBox_DECODE_Options.Text" xml:space="preserve">
<value>选项</value>
</data>
<data name="tabPageDecode.Text" xml:space="preserve">
<value>反编译</value>
</data>
<data name="checkBox_BUILD_NetSecConf.Text" xml:space="preserve">
<value>在输出 APK 中添加通用的网络安全配置文件</value>
</data>
<data name="useAapt2ChkBox.Text" xml:space="preserve">
<value>使用 aapt2(升级 apktool 使用实验性 aapt2 二进制)</value>
</data>
<data name="buildSetApiLvlChkBox.Text" xml:space="preserve">
<value>设置要生成的文件的 API 级别,例如 ICS 的 14。</value>
</data>
<data name="createUnsignApkChkBox.Text" xml:space="preserve">
<value>构建后创建具有原始签名的未签名 APK</value>
</data>
<data name="createUnsignApkChkBox.ToolTip" xml:space="preserve">
<value>只兼容核心补丁模块,需要 root 设备。</value>
</data>
<data name="signAfterBuildChkBox.Text" xml:space="preserve">
<value>在 构建/zip对齐 后进行签名</value>
</data>
<data name="zipalignAfterBuildChkBox.Text" xml:space="preserve">
<value>在构建后进行 zip对齐</value>
</data>
<data name="checkBox_BUILD_NoCrunch.Text" xml:space="preserve">
<value>在构建步骤中禁用对 resource 文件的处理</value>
</data>
<data name="checkBox_BUILD_ForceAll.Text" xml:space="preserve">
<value>跳过变更检测并构建所有文件</value>
</data>
<data name="checkBox_BUILD_OutputAppPath.Text" xml:space="preserve">
<value>APK 输出目录</value>
</data>
<data name="checkBox_BUILD_OutputAppPath.ToolTip" xml:space="preserve">
<value>编译后的输出目录也将用于 Zipalign 和签名</value>
</data>
<data name="checkBox_BUILD_CopyOriginal.Text" xml:space="preserve">
<value>复制原来的 AndroidManifest.xml 和 META-INF 文件夹</value>
</data>
<data name="checkBox_BUILD_UseAapt.Text" xml:space="preserve">
<value>使用的 aapt.exe 文件位置:</value>
</data>
<data name="checkBox_BUILD_UseFramework.Text" xml:space="preserve">
<value>使用的 framework 文件位置:</value>
</data>
<data name="groupBox_BUILD_Options.Text" xml:space="preserve">
<value>选项</value>
</data>
<data name="tabPageBuild.Text" xml:space="preserve">
<value>构建</value>
</data>
<data name="checkBox2.Text" xml:space="preserve">
<value>签名后安装 APK(确保首先在 ADB 选项中选择设备)</value>
</data>
<data name="checkBox1.Text" xml:space="preserve">
<value>覆盖输入文件</value>
</data>
<data name="autoDelIdsigChkBox.Text" xml:space="preserve">
<value>自动删除 idsig 文件</value>
</data>
<data name="schemev4ComboBox.Items" xml:space="preserve">
<value>默认</value>
</data>
<data name="schemev4ComboBox.Items1" xml:space="preserve">
<value>开启</value>
</data>
<data name="schemev4ComboBox.Items2" xml:space="preserve">
<value>关闭</value>
</data>
<data name="label27.Text" xml:space="preserve">
<value>签名方案 v4:</value>
</data>
<data name="schemev3ComboBox.Items" xml:space="preserve">
<value>默认</value>
</data>
<data name="schemev3ComboBox.Items1" xml:space="preserve">
<value>开启</value>
</data>
<data name="schemev3ComboBox.Items2" xml:space="preserve">
<value>关闭</value>
</data>
<data name="label26.Text" xml:space="preserve">
<value>签名方案 v3:</value>
</data>
<data name="schemev2ComboBox.Items" xml:space="preserve">
<value>默认</value>
</data>
<data name="schemev2ComboBox.Items1" xml:space="preserve">
<value>启用</value>
</data>
<data name="schemev2ComboBox.Items2" xml:space="preserve">
<value>关闭</value>
</data>
<data name="label25.Text" xml:space="preserve">
<value>签名方案 v2:</value>
</data>
<data name="schemev1ComboBox.Items" xml:space="preserve">
<value>默认</value>
</data>
<data name="schemev1ComboBox.Items1" xml:space="preserve">
<value>开启</value>
</data>
<data name="schemev1ComboBox.Items2" xml:space="preserve">
<value>关闭</value>
</data>
<data name="label24.Text" xml:space="preserve">
<value>签名方案 v1:</value>
</data>
<data name="useAliasChkBox.Text" xml:space="preserve">
<value>别名</value>
</data>
<data name="label22.Text" xml:space="preserve">
<value>强烈建议您使用自己的密钥,通过 Android Studio 或其他工具创建</value>
</data>
<data name="label21.Text" xml:space="preserve">
<value>密码:</value>
</data>
<data name="label20.Text" xml:space="preserve">
<value>keystore/jks 文件:</value>
</data>
<data name="useKeyStoreChkBox.Text" xml:space="preserve">
<value>使用 keystore</value>
</data>
<data name="useSigningOutputDir.Text" xml:space="preserve">
<value>APK 输出目录:</value>
</data>
<data name="label_SIGN_PrivateKey.Text" xml:space="preserve">
<value>私钥:</value>
</data>
<data name="label_SIGN_PublicKey.Text" xml:space="preserve">
<value>公钥:</value>
</data>
<data name="groupBox_SIGN_Options.Text" xml:space="preserve">
<value>选项</value>
</data>
<data name="tabPageSign.Text" xml:space="preserve">
<value>签名</value>
</data>
<data name="zipalignOutputDirChkBox.Text" xml:space="preserve">
<value>APK 输出目录:</value>
</data>
<data name="signAfterZipalignChkBox.Text" xml:space="preserve">
<value>zip对齐后进行签名</value>
</data>
<data name="checkBox_ZIPALIGN_Recompress.Text" xml:space="preserve">
<value>使用 Zopfli 重新压缩</value>
</data>
<data name="label_ZIPALIGN_AlignmentBytes.Text" xml:space="preserve">
<value>以 bytes 为单位的对齐,例如: '4' 提供 32-bit 对齐</value>
</data>
<data name="checkBox_ZIPALIGN_CheckAlignment.Text" xml:space="preserve">
<value>只检查对齐(不修改文件)</value>
</data>
<data name="checkBox_ZIPALIGN_VerboseOutput.Text" xml:space="preserve">
<value>详细输出</value>
</data>
<data name="checkBox_ZIPALIGN_OverwriteOutputFile.Text" xml:space="preserve">
<value>覆盖现有的输出文件</value>
</data>
<data name="groupBox_ZIPALIGN_Options.Text" xml:space="preserve">
<value>选项</value>
</data>
<data name="tabPageZipAlign.Text" xml:space="preserve">
<value>Zip对齐</value>
</data>
<data name="openFwFolderBtn.Text" xml:space="preserve">
<value>打开 framework 目录</value>
</data>
<data name="clearFwBtn.Text" xml:space="preserve">
<value>清空 framework 缓存</value>
</data>
<data name="clearFwBeforeDecodeChkBox.Text" xml:space="preserve">
<value>反编译前清空 Framework 缓存</value>
</data>
<data name="groupBox1.Text" xml:space="preserve">
<value>选项</value>
</data>
<data name="checkBox_IF_Tag.Text" xml:space="preserve">
<value>标签 frameworks 使用:</value>
</data>
<data name="checkBox_IF_FramePath.Text" xml:space="preserve">
<value>将 framework 文件存储到:</value>
</data>
<data name="button_IF_InstallFramework.Text" xml:space="preserve">
<value>安装</value>
</data>
<data name="groupBox_IF_Options.Text" xml:space="preserve">
<value>选项</value>
</data>
<data name="label29.Text" xml:space="preserve">
<value>Smali 编译目录:</value>
</data>
<data name="smaliUseOutputChkBox.Text" xml:space="preserve">
<value>Dex 输出目录:</value>
</data>
<data name="comSmaliBtn.Text" xml:space="preserve">
<value>编译</value>
</data>
<data name="label28.Text" xml:space="preserve">
<value>Dex 反编译:</value>
</data>
<data name="baksmaliUseOutputChkBox.Text" xml:space="preserve">
<value>输出目录:</value>
</data>
<data name="decSmaliBtn.Text" xml:space="preserve">
<value>反编译</value>
</data>
<data name="label33.Text" xml:space="preserve">
<value>选择设备</value>
</data>
<data name="killAdbBtn.Text" xml:space="preserve">
<value>结束 ADB 进程</value>
</data>
<data name="installApkBtn.Text" xml:space="preserve">
<value>安装 APK</value>
</data>
<data name="refreshDevicesBtn.Text" xml:space="preserve">
<value>刷新</value>
</data>
<data name="overrideAbiCheckBox.Text" xml:space="preserve">
<value>覆盖平台的默认 ABI:</value>
</data>
<data name="setVendorChkBox.Text" xml:space="preserve">
<value>设置 vendor 为 Play Store (com.android.vending)</value>
</data>
<data name="label32.Text" xml:space="preserve">
<value>选择 APK: </value>
</data>
<data name="toolStripStatusLabelStateText.Text" xml:space="preserve">
<value>加载中...</value>
</data>
<data name="clearLogToolStripMenuItem.Text" xml:space="preserve">
<value>清除日志</value>
</data>
<data name="newInsToolStripMenuItem.Text" xml:space="preserve">
<value>新进程</value>
</data>
<data name="saveLogToFileToolStripMenuItem.Text" xml:space="preserve">
<value>保存日志</value>
</data>
<data name="openTempFolderToolStripMenuItem.Text" xml:space="preserve">
<value>打开缓存目录</value>
</data>
<data name="clearTempFolderToolStripMenuItem.Text" xml:space="preserve">
<value>清空缓存目录</value>
</data>
<data name="exitToolStripMenuItem.Text" xml:space="preserve">
<value>退出</value>
</data>
<data name="fileToolStripMenuItem.Text" xml:space="preserve">
<value>文件</value>
</data>
<data name="useAPKEditorForDecompilingItem.Text" xml:space="preserve">
<value>使用 APKEditor 进行反编译</value>
</data>
<data name="settingsToolStripMenuItem.Text" xml:space="preserve">
<value>设置</value>
</data>
<data name="checkForUpdateToolStripMenuItem.Text" xml:space="preserve">
<value>检查更新</value>
</data>
<data name="reportAnIsuueToolStripMenuItem.Text" xml:space="preserve">
<value>反馈问题</value>
</data>
<data name="apktoolIssuesToolStripMenuItem.Text" xml:space="preserve">
<value>Apktool 问题反馈</value>
</data>
<data name="baksmaliIssuesToolStripMenuItem.Text" xml:space="preserve">
<value>Baksmail 问题反馈</value>
</data>
<data name="aboutToolStripMenuItem.Text" xml:space="preserve">
<value>关于</value>
</data>
<data name="helpToolStripMenuItem.Text" xml:space="preserve">
<value>帮助</value>
</data>
<data name="checkBox_DECODE_UseApkEditorMerge.Text" xml:space="preserve">
<value>使用 APKEditor.jar 合并、分离 APK(速度更快)</value>
</data>
</root>
-381
View File
@@ -1,381 +0,0 @@
namespace APKToolGUI
{
partial class FormSettings
{
/// <summary>
/// Требуется переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором форм Windows
/// <summary>
/// Обязательный метод для поддержки конструктора - не изменяйте
/// содержимое данного метода при помощи редактора кода.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormSettings));
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.themeComboBox = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.customApktoolBtn = new System.Windows.Forms.Button();
this.label6 = new System.Windows.Forms.Label();
this.buttonCustomTempLocation = new System.Windows.Forms.Button();
this.buttonCustomJavaLocation = new System.Windows.Forms.Button();
this.groupBoxLanguage = new System.Windows.Forms.GroupBox();
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.groupBoxContextMenu = new System.Windows.Forms.GroupBox();
this.labelAdminRights = new System.Windows.Forms.Label();
this.buttonAddContextMenu = new System.Windows.Forms.Button();
this.buttonRemoveContextMenu = new System.Windows.Forms.Button();
this.buttonCancel = new System.Windows.Forms.Button();
this.buttonОК = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.checkBox7 = new System.Windows.Forms.CheckBox();
this.checkBox6 = new System.Windows.Forms.CheckBox();
this.customApkToolTxtBox = new System.Windows.Forms.TextBox();
this.useCustomApktoolChk = new System.Windows.Forms.CheckBox();
this.checkBox5 = new System.Windows.Forms.CheckBox();
this.checkBox4 = new System.Windows.Forms.CheckBox();
this.customTempLocationTxtBox = new System.Windows.Forms.TextBox();
this.textBoxCustomJavaLocation = new System.Windows.Forms.TextBox();
this.checkBox3 = new System.Windows.Forms.CheckBox();
this.checkBox2 = new System.Windows.Forms.CheckBox();
this.checkBox1 = new System.Windows.Forms.CheckBox();
this.checkBoxCheckUpdateStartup = new System.Windows.Forms.CheckBox();
this.ignoreOutputContextMenuBox = new System.Windows.Forms.CheckBox();
this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout();
this.groupBox1.SuspendLayout();
this.groupBoxLanguage.SuspendLayout();
this.groupBoxContextMenu.SuspendLayout();
this.SuspendLayout();
//
// tabControl1
//
resources.ApplyResources(this.tabControl1, "tabControl1");
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
//
// tabPage1
//
resources.ApplyResources(this.tabPage1, "tabPage1");
this.tabPage1.Controls.Add(this.groupBox1);
this.tabPage1.Controls.Add(this.groupBoxLanguage);
this.tabPage1.Controls.Add(this.groupBoxContextMenu);
this.tabPage1.Name = "tabPage1";
this.tabPage1.UseVisualStyleBackColor = true;
//
// groupBox1
//
resources.ApplyResources(this.groupBox1, "groupBox1");
this.groupBox1.Controls.Add(this.textBox1);
this.groupBox1.Controls.Add(this.checkBox7);
this.groupBox1.Controls.Add(this.checkBox6);
this.groupBox1.Controls.Add(this.themeComboBox);
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Controls.Add(this.customApkToolTxtBox);
this.groupBox1.Controls.Add(this.customApktoolBtn);
this.groupBox1.Controls.Add(this.useCustomApktoolChk);
this.groupBox1.Controls.Add(this.label6);
this.groupBox1.Controls.Add(this.checkBox5);
this.groupBox1.Controls.Add(this.checkBox4);
this.groupBox1.Controls.Add(this.customTempLocationTxtBox);
this.groupBox1.Controls.Add(this.textBoxCustomJavaLocation);
this.groupBox1.Controls.Add(this.buttonCustomTempLocation);
this.groupBox1.Controls.Add(this.checkBox3);
this.groupBox1.Controls.Add(this.buttonCustomJavaLocation);
this.groupBox1.Controls.Add(this.checkBox2);
this.groupBox1.Controls.Add(this.checkBox1);
this.groupBox1.Controls.Add(this.checkBoxCheckUpdateStartup);
this.groupBox1.Name = "groupBox1";
this.groupBox1.TabStop = false;
//
// themeComboBox
//
this.themeComboBox.FormattingEnabled = true;
this.themeComboBox.Items.AddRange(new object[] {
resources.GetString("themeComboBox.Items"),
resources.GetString("themeComboBox.Items1"),
resources.GetString("themeComboBox.Items2")});
resources.ApplyResources(this.themeComboBox, "themeComboBox");
this.themeComboBox.Name = "themeComboBox";
//
// label1
//
resources.ApplyResources(this.label1, "label1");
this.label1.Name = "label1";
//
// customApktoolBtn
//
resources.ApplyResources(this.customApktoolBtn, "customApktoolBtn");
this.customApktoolBtn.Name = "customApktoolBtn";
this.customApktoolBtn.UseVisualStyleBackColor = true;
this.customApktoolBtn.Click += new System.EventHandler(this.customApktoolBtn_Click);
//
// label6
//
resources.ApplyResources(this.label6, "label6");
this.label6.ForeColor = System.Drawing.Color.DimGray;
this.label6.Name = "label6";
//
// buttonCustomTempLocation
//
resources.ApplyResources(this.buttonCustomTempLocation, "buttonCustomTempLocation");
this.buttonCustomTempLocation.Name = "buttonCustomTempLocation";
this.buttonCustomTempLocation.UseVisualStyleBackColor = true;
this.buttonCustomTempLocation.Click += new System.EventHandler(this.buttonCustomTempLocation_Click);
//
// buttonCustomJavaLocation
//
resources.ApplyResources(this.buttonCustomJavaLocation, "buttonCustomJavaLocation");
this.buttonCustomJavaLocation.Name = "buttonCustomJavaLocation";
this.buttonCustomJavaLocation.UseVisualStyleBackColor = true;
this.buttonCustomJavaLocation.Click += new System.EventHandler(this.buttonCustomJavaLocation_Click);
//
// groupBoxLanguage
//
resources.ApplyResources(this.groupBoxLanguage, "groupBoxLanguage");
this.groupBoxLanguage.Controls.Add(this.comboBox1);
this.groupBoxLanguage.Name = "groupBoxLanguage";
this.groupBoxLanguage.TabStop = false;
//
// comboBox1
//
this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
resources.ApplyResources(this.comboBox1, "comboBox1");
this.comboBox1.FormattingEnabled = true;
this.comboBox1.Name = "comboBox1";
//
// groupBoxContextMenu
//
resources.ApplyResources(this.groupBoxContextMenu, "groupBoxContextMenu");
this.groupBoxContextMenu.Controls.Add(this.ignoreOutputContextMenuBox);
this.groupBoxContextMenu.Controls.Add(this.labelAdminRights);
this.groupBoxContextMenu.Controls.Add(this.buttonAddContextMenu);
this.groupBoxContextMenu.Controls.Add(this.buttonRemoveContextMenu);
this.groupBoxContextMenu.Name = "groupBoxContextMenu";
this.groupBoxContextMenu.TabStop = false;
//
// labelAdminRights
//
resources.ApplyResources(this.labelAdminRights, "labelAdminRights");
this.labelAdminRights.Name = "labelAdminRights";
//
// buttonAddContextMenu
//
resources.ApplyResources(this.buttonAddContextMenu, "buttonAddContextMenu");
this.buttonAddContextMenu.Name = "buttonAddContextMenu";
this.buttonAddContextMenu.UseVisualStyleBackColor = true;
this.buttonAddContextMenu.Click += new System.EventHandler(this.buttonAddContextMenu_Click);
//
// buttonRemoveContextMenu
//
resources.ApplyResources(this.buttonRemoveContextMenu, "buttonRemoveContextMenu");
this.buttonRemoveContextMenu.Name = "buttonRemoveContextMenu";
this.buttonRemoveContextMenu.UseVisualStyleBackColor = true;
this.buttonRemoveContextMenu.Click += new System.EventHandler(this.buttonRemoveContextMenu_Click);
//
// buttonCancel
//
resources.ApplyResources(this.buttonCancel, "buttonCancel");
this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.UseVisualStyleBackColor = true;
//
// buttonОК
//
resources.ApplyResources(this.buttonОК, "buttonОК");
this.buttonОК.Name = "buttonОК";
this.buttonОК.UseVisualStyleBackColor = true;
this.buttonОК.Click += new System.EventHandler(this.buttonОК_Click);
//
// textBox1
//
resources.ApplyResources(this.textBox1, "textBox1");
this.textBox1.BackColor = System.Drawing.SystemColors.Window;
this.textBox1.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::APKToolGUI.Properties.Settings.Default, "CustomJVMArgs", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.textBox1.Name = "textBox1";
this.textBox1.Text = global::APKToolGUI.Properties.Settings.Default.CustomJVMArgs;
//
// checkBox7
//
resources.ApplyResources(this.checkBox7, "checkBox7");
this.checkBox7.Checked = global::APKToolGUI.Properties.Settings.Default.UseCustomJVMArgs;
this.checkBox7.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::APKToolGUI.Properties.Settings.Default, "UseCustomJVMArgs", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.checkBox7.Name = "checkBox7";
this.checkBox7.UseVisualStyleBackColor = true;
//
// checkBox6
//
resources.ApplyResources(this.checkBox6, "checkBox6");
this.checkBox6.Checked = global::APKToolGUI.Properties.Settings.Default.DebugMode;
this.checkBox6.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::APKToolGUI.Properties.Settings.Default, "DebugMode", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.checkBox6.Name = "checkBox6";
this.checkBox6.UseVisualStyleBackColor = true;
//
// customApkToolTxtBox
//
resources.ApplyResources(this.customApkToolTxtBox, "customApkToolTxtBox");
this.customApkToolTxtBox.BackColor = System.Drawing.SystemColors.Window;
this.customApkToolTxtBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::APKToolGUI.Properties.Settings.Default, "ApktoolPath", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.customApkToolTxtBox.Name = "customApkToolTxtBox";
this.customApkToolTxtBox.Text = global::APKToolGUI.Properties.Settings.Default.ApktoolPath;
//
// useCustomApktoolChk
//
resources.ApplyResources(this.useCustomApktoolChk, "useCustomApktoolChk");
this.useCustomApktoolChk.Checked = global::APKToolGUI.Properties.Settings.Default.UseCustomApktool;
this.useCustomApktoolChk.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::APKToolGUI.Properties.Settings.Default, "UseCustomApktool", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.useCustomApktoolChk.Name = "useCustomApktoolChk";
this.useCustomApktoolChk.UseVisualStyleBackColor = true;
//
// checkBox5
//
resources.ApplyResources(this.checkBox5, "checkBox5");
this.checkBox5.Checked = global::APKToolGUI.Properties.Settings.Default.Utf8FilenameSupport;
this.checkBox5.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::APKToolGUI.Properties.Settings.Default, "Utf8FilenameSupport", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.checkBox5.Name = "checkBox5";
this.checkBox5.UseVisualStyleBackColor = true;
//
// checkBox4
//
resources.ApplyResources(this.checkBox4, "checkBox4");
this.checkBox4.Checked = global::APKToolGUI.Properties.Settings.Default.UseCustomJavaExe;
this.checkBox4.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::APKToolGUI.Properties.Settings.Default, "UseCustomJavaExe", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.checkBox4.Name = "checkBox4";
this.checkBox4.UseVisualStyleBackColor = true;
//
// customTempLocationTxtBox
//
resources.ApplyResources(this.customTempLocationTxtBox, "customTempLocationTxtBox");
this.customTempLocationTxtBox.BackColor = System.Drawing.SystemColors.Window;
this.customTempLocationTxtBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::APKToolGUI.Properties.Settings.Default, "TempDir", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.customTempLocationTxtBox.Name = "customTempLocationTxtBox";
this.customTempLocationTxtBox.Text = global::APKToolGUI.Properties.Settings.Default.TempDir;
//
// textBoxCustomJavaLocation
//
resources.ApplyResources(this.textBoxCustomJavaLocation, "textBoxCustomJavaLocation");
this.textBoxCustomJavaLocation.BackColor = System.Drawing.SystemColors.Window;
this.textBoxCustomJavaLocation.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::APKToolGUI.Properties.Settings.Default, "JavaExe", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.textBoxCustomJavaLocation.Name = "textBoxCustomJavaLocation";
this.textBoxCustomJavaLocation.Text = global::APKToolGUI.Properties.Settings.Default.JavaExe;
//
// checkBox3
//
resources.ApplyResources(this.checkBox3, "checkBox3");
this.checkBox3.Checked = global::APKToolGUI.Properties.Settings.Default.UseCustomTempDir;
this.checkBox3.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::APKToolGUI.Properties.Settings.Default, "UseCustomTempDir", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.checkBox3.Name = "checkBox3";
this.checkBox3.UseVisualStyleBackColor = true;
//
// checkBox2
//
resources.ApplyResources(this.checkBox2, "checkBox2");
this.checkBox2.Checked = global::APKToolGUI.Properties.Settings.Default.PlaySoundWhenDone;
this.checkBox2.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::APKToolGUI.Properties.Settings.Default, "PlaySoundWhenDone", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.checkBox2.Name = "checkBox2";
this.checkBox2.UseVisualStyleBackColor = true;
//
// checkBox1
//
resources.ApplyResources(this.checkBox1, "checkBox1");
this.checkBox1.Checked = global::APKToolGUI.Properties.Settings.Default.ClearLogBeforeAction;
this.checkBox1.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBox1.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::APKToolGUI.Properties.Settings.Default, "ClearLogBeforeAction", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.checkBox1.Name = "checkBox1";
this.checkBox1.UseVisualStyleBackColor = true;
//
// checkBoxCheckUpdateStartup
//
resources.ApplyResources(this.checkBoxCheckUpdateStartup, "checkBoxCheckUpdateStartup");
this.checkBoxCheckUpdateStartup.Checked = global::APKToolGUI.Properties.Settings.Default.CheckForUpdateAtStartup;
this.checkBoxCheckUpdateStartup.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBoxCheckUpdateStartup.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::APKToolGUI.Properties.Settings.Default, "CheckForUpdateAtStartup", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.checkBoxCheckUpdateStartup.Name = "checkBoxCheckUpdateStartup";
this.checkBoxCheckUpdateStartup.UseVisualStyleBackColor = true;
//
// ignoreOutputContextMenuBox
//
resources.ApplyResources(this.ignoreOutputContextMenuBox, "ignoreOutputContextMenuBox");
this.ignoreOutputContextMenuBox.Checked = global::APKToolGUI.Properties.Settings.Default.IgnoreOutputDirContextMenu;
this.ignoreOutputContextMenuBox.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::APKToolGUI.Properties.Settings.Default, "IgnoreOutputDirContextMenu", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.ignoreOutputContextMenuBox.Name = "ignoreOutputContextMenuBox";
this.ignoreOutputContextMenuBox.UseVisualStyleBackColor = true;
//
// FormSettings
//
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.buttonОК);
this.Controls.Add(this.tabControl1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "FormSettings";
this.Load += new System.EventHandler(this.FormSettings_Load);
this.tabControl1.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.groupBoxLanguage.ResumeLayout(false);
this.groupBoxContextMenu.ResumeLayout(false);
this.groupBoxContextMenu.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.GroupBox groupBoxLanguage;
private System.Windows.Forms.ComboBox comboBox1;
private System.Windows.Forms.GroupBox groupBoxContextMenu;
private System.Windows.Forms.Label labelAdminRights;
private System.Windows.Forms.Button buttonAddContextMenu;
private System.Windows.Forms.Button buttonRemoveContextMenu;
private System.Windows.Forms.Button buttonCancel;
private System.Windows.Forms.Button buttonОК;
private System.Windows.Forms.TextBox textBoxCustomJavaLocation;
private System.Windows.Forms.Button buttonCustomJavaLocation;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.CheckBox checkBoxCheckUpdateStartup;
private System.Windows.Forms.CheckBox checkBox1;
private System.Windows.Forms.CheckBox ignoreOutputContextMenuBox;
private System.Windows.Forms.CheckBox checkBox2;
private System.Windows.Forms.CheckBox checkBox4;
private System.Windows.Forms.TextBox customTempLocationTxtBox;
private System.Windows.Forms.Button buttonCustomTempLocation;
private System.Windows.Forms.CheckBox checkBox3;
internal System.Windows.Forms.Label label6;
private System.Windows.Forms.CheckBox checkBox5;
private System.Windows.Forms.TextBox customApkToolTxtBox;
private System.Windows.Forms.Button customApktoolBtn;
private System.Windows.Forms.CheckBox useCustomApktoolChk;
private System.Windows.Forms.ComboBox themeComboBox;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.CheckBox checkBox6;
private System.Windows.Forms.CheckBox checkBox7;
private System.Windows.Forms.TextBox textBox1;
}
}
-227
View File
@@ -1,227 +0,0 @@
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using APKToolGUI.Languages;
using APKToolGUI.Utils;
using Ookii.Dialogs.WinForms;
using System.Globalization;
using System.Reflection;
using System.Collections.Generic;
using System.Windows.Shapes;
using static APKToolGUI.UpdateChecker;
using APKToolGUI.Properties;
using APKToolGUI.Controls;
using System.Diagnostics;
using System.Linq;
namespace APKToolGUI
{
public partial class FormSettings : Form
{
string currentLanguage;
bool currentUseApktoolChk;
string currentApktoolPath;
int currentTheme;
public FormSettings()
{
InitializeComponent();
if (Program.IsDarkTheme())
DarkTheme.SetTheme(Controls, this);
currentUseApktoolChk = useCustomApktoolChk.Checked;
currentApktoolPath = customApkToolTxtBox.Text;
if (!AdminUtils.IsAdministrator())
{
SetButtonShield(buttonAddContextMenu, true);
SetButtonShield(buttonRemoveContextMenu, true);
}
int themeInt = (themeComboBox.Items.Count + 1 > Settings.Default.Theme) ? Settings.Default.Theme : 0;
themeComboBox.SelectedIndex = themeInt;
currentTheme = themeInt;
}
#region GUI
private void FormSettings_Load(object sender, EventArgs e)
{
LoadSettings();
}
private void buttonОК_Click(object sender, EventArgs e)
{
SaveSettings();
Close();
}
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr SendMessage(HandleRef hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
private static void SetButtonShield(Button btn, bool showShield)
{
// BCM_SETSHIELD = 0x0000160C
SendMessage(new HandleRef(btn, btn.Handle), 0x160C, IntPtr.Zero, showShield ? new IntPtr(1) : IntPtr.Zero);
}
private void buttonAddContextMenu_Click(object sender, EventArgs e)
{
if (MessageBox.Show(Language.DoYouRealyWantToInstallCM, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
RunAsAdmin(Application.ExecutablePath, "ccm");
}
private void buttonRemoveContextMenu_Click(object sender, EventArgs e)
{
if (MessageBox.Show(Language.DoYouRealyWantToRemoveCM, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
RunAsAdmin(Application.ExecutablePath, "rcm");
}
#endregion
private void LoadSettings()
{
string sysLang = Language.SystemLanguage;
comboBox1.Items.Add(sysLang);
comboBox1.Items.Add(CultureInfo.GetCultureInfo("en"));
CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
string _culture = Settings.Default.Culture;
foreach (CultureInfo culture in cultures)
{
foreach (string resourceName in Assembly.GetExecutingAssembly().GetManifestResourceNames())
{
//Debug.WriteLine(resourceName);
string[] cultName = resourceName.Split('.');
if (cultName[1] == culture.Name)
{
//Debug.WriteLine("Lang: " + cultName[1] + " " + culture.Name);
string lang = string.Format("{0} [{1}]", culture.DisplayName, culture.Name);
comboBox1.Items.Add(lang);
if (culture.Name == _culture)
comboBox1.SelectedItem = lang;
}
}
}
comboBox1.DisplayMember = "NativeName"; // <= System.Globalization.CultureInfo.GetCultureInfo("ru-RU").NativeName
comboBox1.ValueMember = "Name"; // <= System.Globalization.CultureInfo.GetCultureInfo("ru-RU").Name
if (_culture.Equals("Auto"))
{
currentLanguage = sysLang;
comboBox1.SelectedItem = sysLang;
}
else if (string.IsNullOrEmpty(_culture))
{
comboBox1.SelectedIndex = 1;
}
else
{
try
{
currentLanguage = Settings.Default.Culture;
comboBox1.SelectedItem = _culture;
}
catch { }
}
}
private void SaveSettings()
{
try
{
if (Language.SystemLanguage.Equals(comboBox1.SelectedItem.ToString()))
Settings.Default.Culture = "Auto";
else
Settings.Default.Culture = StringExt.RegexExtract(@"(?<=\[)(.*?)(?=\])", comboBox1.SelectedItem.ToString());
Settings.Default.Theme = themeComboBox.SelectedIndex;
Settings.Default.Save();
if (string.IsNullOrEmpty(currentLanguage))
currentLanguage = "en";
Debug.WriteLine("Combobox: " + comboBox1.SelectedItem.ToString() + " Language: " + currentLanguage);
if (!comboBox1.SelectedItem.ToString().Contains(currentLanguage) || themeComboBox.SelectedIndex != currentTheme)
if (MessageBox.Show(Language.RestartApplicationPrompt, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
Application.Restart();
if (currentUseApktoolChk != useCustomApktoolChk.Checked || currentApktoolPath != customApkToolTxtBox.Text)
{
FormMain.Instance.SetApktoolPath();
}
}
catch (Exception ex)
{
Log.e(ex.ToString());
}
}
public static void RunAsAdmin(string aFileName, string anArguments)
{
System.Diagnostics.ProcessStartInfo processInfo = new System.Diagnostics.ProcessStartInfo();
processInfo.FileName = aFileName;
processInfo.Arguments = anArguments;
processInfo.UseShellExecute = true;
processInfo.Verb = "runas";
try
{
System.Diagnostics.Process.Start(processInfo);
}
catch (Exception e)
{
MessageBox.Show(e.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCustomJavaLocation_Click(object sender, EventArgs e)
{
using (OpenFileDialog openJavaExe = new OpenFileDialog())
{
openJavaExe.Filter = "java.exe|java.exe";
if (openJavaExe.ShowDialog() == DialogResult.OK)
textBoxCustomJavaLocation.Text = Program.GetPortablePath(openJavaExe.FileName);
}
}
private void buttonCustomTempLocation_Click(object sender, EventArgs e)
{
using (VistaFolderBrowserDialog fbd = new VistaFolderBrowserDialog())
{
if (!String.IsNullOrWhiteSpace(customTempLocationTxtBox.Text))
fbd.SelectedPath = customTempLocationTxtBox.Text;
if (fbd.ShowDialog() == DialogResult.OK)
{
customTempLocationTxtBox.Text = fbd.SelectedPath;
//Clear temp folder
DirectoryUtils.Delete(Program.TEMP_PATH);
//Create new temp folder
Program.TEMP_PATH = Program.RandTempDirectory();
Directory.CreateDirectory(Program.TEMP_PATH);
}
}
}
private async void customApktoolBtn_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "Apktool (*.jar)|*.jar";
if (ofd.ShowDialog() == DialogResult.OK)
{
customApkToolTxtBox.Text = ofd.FileName;
}
}
}
}
}
-235
View File
@@ -1,235 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="checkBox7.Size" type="System.Drawing.Size, System.Drawing">
<value>206, 17</value>
</data>
<data name="checkBox7.Text" xml:space="preserve">
<value>Benutzerdefinierte JVM-Argumente</value>
</data>
<data name="checkBox6.Size" type="System.Drawing.Size, System.Drawing">
<value>101, 17</value>
</data>
<data name="checkBox6.Text" xml:space="preserve">
<value>Debug-Modus</value>
</data>
<data name="themeComboBox.Items" xml:space="preserve">
<value>Automatisch</value>
</data>
<data name="themeComboBox.Items1" xml:space="preserve">
<value>Hell</value>
</data>
<data name="themeComboBox.Items2" xml:space="preserve">
<value>Dunkel</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>Thema</value>
</data>
<data name="customApktoolBtn.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="useCustomApktoolChk.Size" type="System.Drawing.Size, System.Drawing">
<value>232, 17</value>
</data>
<data name="useCustomApktoolChk.Text" xml:space="preserve">
<value>Benutzerdefinierter APKTool-Speicherort</value>
</data>
<data name="label6.Size" type="System.Drawing.Size, System.Drawing">
<value>502, 13</value>
</data>
<data name="label6.Text" xml:space="preserve">
<value>Der Vorgang wird langsamer sein, da die Dateien in den temporären Ordner verschoben werden</value>
</data>
<data name="checkBox5.Size" type="System.Drawing.Size, System.Drawing">
<value>218, 17</value>
</data>
<data name="checkBox5.Text" xml:space="preserve">
<value>Unterstützung für UTF-8-Dateinamen</value>
</data>
<data name="checkBox4.Size" type="System.Drawing.Size, System.Drawing">
<value>212, 17</value>
</data>
<data name="checkBox4.Text" xml:space="preserve">
<value>Benutzerdefinierter Java-Speicherort</value>
</data>
<data name="buttonCustomTempLocation.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="checkBox3.Size" type="System.Drawing.Size, System.Drawing">
<value>233, 17</value>
</data>
<data name="checkBox3.Text" xml:space="preserve">
<value>Benutzerdefinierter temporärer Standort</value>
</data>
<data name="buttonCustomJavaLocation.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="checkBox2.Size" type="System.Drawing.Size, System.Drawing">
<value>203, 17</value>
</data>
<data name="checkBox2.Text" xml:space="preserve">
<value>Ton abspielen, wenn du fertig bist</value>
</data>
<data name="checkBox1.Size" type="System.Drawing.Size, System.Drawing">
<value>281, 17</value>
</data>
<data name="checkBox1.Text" xml:space="preserve">
<value>Protokoll löschen, bevor du Maßnahmen ergreifst</value>
</data>
<data name="checkBoxCheckUpdateStartup.Size" type="System.Drawing.Size, System.Drawing">
<value>191, 17</value>
</data>
<data name="checkBoxCheckUpdateStartup.Text" xml:space="preserve">
<value>Beim Start nach Updates suchen</value>
</data>
<data name="groupBox1.Text" xml:space="preserve">
<value>Allgemein</value>
</data>
<data name="groupBoxLanguage.Text" xml:space="preserve">
<value>Sprache</value>
</data>
<data name="ignoreOutputContextMenuBox.Size" type="System.Drawing.Size, System.Drawing">
<value>376, 17</value>
</data>
<data name="ignoreOutputContextMenuBox.Text" xml:space="preserve">
<value>Benutzerdefiniertes Ausgabeverzeichnis für Kontextmenü ignorieren</value>
</data>
<data name="labelAdminRights.Text" xml:space="preserve">
<value>Administratorrechte erforderlich</value>
</data>
<data name="buttonAddContextMenu.Text" xml:space="preserve">
<value>Install …</value>
</data>
<data name="buttonRemoveContextMenu.Text" xml:space="preserve">
<value>Deinstall …</value>
</data>
<data name="groupBoxContextMenu.Text" xml:space="preserve">
<value>Kontextmenü</value>
</data>
<data name="tabPage1.Text" xml:space="preserve">
<value>Allgemein</value>
</data>
<data name="buttonCancel.Text" xml:space="preserve">
<value>Abbrechen</value>
</data>
<data name="$this.Text" xml:space="preserve">
<value>Einstellungen</value>
</data>
</root>
File diff suppressed because it is too large Load Diff
-181
View File
@@ -1,181 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="checkBox1.Size" type="System.Drawing.Size, System.Drawing">
<value>288, 17</value>
</data>
<data name="checkBox1.Text" xml:space="preserve">
<value>Очищать журнал событий перед каждой операцией</value>
</data>
<data name="checkBoxCheckUpdateStartup.Size" type="System.Drawing.Size, System.Drawing">
<value>276, 17</value>
</data>
<data name="checkBoxCheckUpdateStartup.Text" xml:space="preserve">
<value>Проверять обновление при запуске (раз в сутки)</value>
</data>
<data name="groupBox1.Text" xml:space="preserve">
<value>Прочее</value>
</data>
<data name="labelCustomJavaLocation.Text" xml:space="preserve">
<value>Пользовательское расположение</value>
</data>
<data name="buttonCustomJavaLocation.Size" type="System.Drawing.Size, System.Drawing">
<value>23, 22</value>
</data>
<data name="groupBoxLanguage.Text" xml:space="preserve">
<value>Язык</value>
</data>
<data name="labelAdminRights.Text" xml:space="preserve">
<value>Требуются права администратора</value>
</data>
<data name="buttonAddContextMenu.Text" xml:space="preserve">
<value>Установить</value>
</data>
<data name="buttonRemoveContextMenu.Text" xml:space="preserve">
<value>Удалить</value>
</data>
<data name="groupBoxContextMenu.Text" xml:space="preserve">
<value>Контекстное меню</value>
</data>
<data name="tabPage1.Text" xml:space="preserve">
<value>Общие</value>
</data>
<data name="buttonCancel.Text" xml:space="preserve">
<value>Отмена</value>
</data>
<data name="$this.Text" xml:space="preserve">
<value>Настройки</value>
</data>
<data name="buttonCustomJavaLocation.Text" xml:space="preserve">
<value>Указать путь к Java</value>
</data>
<data name="useCustomApktoolChk.Text" xml:space="preserve">
<value>Свой путь к Apktool</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>Тема</value>
</data>
<data name="checkBox6.Text" xml:space="preserve">
<value>Режим отладки</value>
</data>
<data name="checkBox7.Text" xml:space="preserve">
<value>Аргументы JVM</value>
</data>
</root>
-199
View File
@@ -1,199 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="checkBox7.Text" xml:space="preserve">
<value>Tùy chỉnh lệnh JVM</value>
</data>
<data name="checkBox6.Text" xml:space="preserve">
<value>Chế độ gỡ lỗi</value>
</data>
<data name="themeComboBox.Items" xml:space="preserve">
<value>Tự động</value>
</data>
<data name="themeComboBox.Items1" xml:space="preserve">
<value>Sáng</value>
</data>
<data name="themeComboBox.Items2" xml:space="preserve">
<value>Tối</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>Giao diện</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="useCustomApktoolChk.TabIndex" type="System.Resources.ResXNullRef, System.Windows.Forms">
<value />
</data>
<data name="useCustomApktoolChk.Text" xml:space="preserve">
<value>Vị trí apktool tùy chỉnh</value>
</data>
<data name="label6.Text" xml:space="preserve">
<value>Việc di chuyển các tệp trong quá trình xử lý vào thư mục tạm có thể mất thời gian, vui lòng kiên nhẫn chờ đợi</value>
</data>
<data name="checkBox5.Text" xml:space="preserve">
<value>Hỗ trợ tên tệp UTF-8 (bật khi tên tệp bị lỗi hiển thị)</value>
</data>
<data name="checkBox4.Text" xml:space="preserve">
<value>Vị trí Java tùy chỉnh</value>
</data>
<data name="checkBox3.Text" xml:space="preserve">
<value>Vị trí bộ đệm tùy chỉnh</value>
</data>
<data name="checkBox2.Text" xml:space="preserve">
<value>Âm báo hoàn thành</value>
</data>
<data name="checkBox1.Text" xml:space="preserve">
<value>Xóa nhật ký trước khi thực hiện</value>
</data>
<data name="checkBoxCheckUpdateStartup.Text" xml:space="preserve">
<value>Kiểm tra cập nhật khi khởi động</value>
</data>
<data name="groupBox1.Text" xml:space="preserve">
<value>Chung</value>
</data>
<data name="groupBoxLanguage.Text" xml:space="preserve">
<value>Ngôn ngữ</value>
</data>
<data name="ignoreOutputContextMenuBox.Text" xml:space="preserve">
<value>Bỏ qua thư mục đầu ra tùy chỉnh của menu chuột phải</value>
</data>
<data name="labelAdminRights.Text" xml:space="preserve">
<value>Yêu cầu quyền quản trị</value>
</data>
<data name="buttonAddContextMenu.Text" xml:space="preserve">
<value>Cài đặt</value>
</data>
<data name="buttonRemoveContextMenu.Text" xml:space="preserve">
<value>Gỡ cài đặt</value>
</data>
<data name="groupBoxContextMenu.Text" xml:space="preserve">
<value>Menu chuột phải</value>
</data>
<data name="tabPage1.Text" xml:space="preserve">
<value>Chung</value>
</data>
<data name="buttonCancel.Text" xml:space="preserve">
<value>Hủy</value>
</data>
<data name="buttonОК.Text" xml:space="preserve">
<value>OK</value>
</data>
<data name="$this.Text" xml:space="preserve">
<value>Cài đặt</value>
</data>
</root>
-199
View File
@@ -1,199 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="checkBox7.Text" xml:space="preserve">
<value>自定义 JVM 命令</value>
</data>
<data name="checkBox6.Text" xml:space="preserve">
<value>调试模式</value>
</data>
<data name="themeComboBox.Items" xml:space="preserve">
<value>自动</value>
</data>
<data name="themeComboBox.Items1" xml:space="preserve">
<value>浅色</value>
</data>
<data name="themeComboBox.Items2" xml:space="preserve">
<value>深色</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>主题</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="useCustomApktoolChk.TabIndex" type="System.Resources.ResXNullRef, System.Windows.Forms">
<value />
</data>
<data name="useCustomApktoolChk.Text" xml:space="preserve">
<value>自定义 apktool 位置</value>
</data>
<data name="label6.Text" xml:space="preserve">
<value>操作过程的文件移动到缓存目录中需要时间,请耐心等待</value>
</data>
<data name="checkBox5.Text" xml:space="preserve">
<value>UTF-8 文件名支持,中文乱码开启</value>
</data>
<data name="checkBox4.Text" xml:space="preserve">
<value>自定义 Java 位置</value>
</data>
<data name="checkBox3.Text" xml:space="preserve">
<value>自定义缓存位置</value>
</data>
<data name="checkBox2.Text" xml:space="preserve">
<value>完成提示音</value>
</data>
<data name="checkBox1.Text" xml:space="preserve">
<value>操作前清除日志</value>
</data>
<data name="checkBoxCheckUpdateStartup.Text" xml:space="preserve">
<value>启动时检查更新</value>
</data>
<data name="groupBox1.Text" xml:space="preserve">
<value>常规</value>
</data>
<data name="groupBoxLanguage.Text" xml:space="preserve">
<value>语言</value>
</data>
<data name="ignoreOutputContextMenuBox.Text" xml:space="preserve">
<value>忽略右键菜单的自定义输出目录</value>
</data>
<data name="labelAdminRights.Text" xml:space="preserve">
<value>需要管理员权限</value>
</data>
<data name="buttonAddContextMenu.Text" xml:space="preserve">
<value>安装</value>
</data>
<data name="buttonRemoveContextMenu.Text" xml:space="preserve">
<value>卸载</value>
</data>
<data name="groupBoxContextMenu.Text" xml:space="preserve">
<value>右键菜单</value>
</data>
<data name="tabPage1.Text" xml:space="preserve">
<value>常规</value>
</data>
<data name="buttonCancel.Text" xml:space="preserve">
<value>取消</value>
</data>
<data name="buttonОК.Text" xml:space="preserve">
<value>确定</value>
</data>
<data name="$this.Text" xml:space="preserve">
<value>设置</value>
</data>
</root>
File diff suppressed because it is too large Load Diff
+726
View File
@@ -0,0 +1,726 @@
<Window x:Class="APKToolGUI.Forms.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ctrl="clr-namespace:APKToolGUI.Controls"
Title="APK Tool GUI"
Width="641" Height="686"
MinWidth="560" MinHeight="560"
WindowStartupLocation="CenterScreen"
UseLayoutRounding="True" TextOptions.TextFormattingMode="Display"
FontFamily="Segoe UI" FontSize="12"
Background="{DynamicResource WindowBackground}"
Foreground="{DynamicResource PrimaryText}">
<!-- Main application window. Shared dark/light control styles are merged from
Themes/Controls.xaml; the actual colours are applied via WpfTheme.Apply in the code-behind. -->
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Themes/Controls.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<DockPanel LastChildFill="True">
<!-- ===== Menu ===== -->
<Menu DockPanel.Dock="Top">
<MenuItem x:Name="menuFile" Header="File">
<MenuItem x:Name="menuNewInstance" Header="New instance" Click="NewInstance_Click"/>
<MenuItem x:Name="menuSaveLog" Header="Save log to file" Click="SaveLog_Click"/>
<Separator/>
<MenuItem x:Name="menuOpenTemp" Header="Open temp folder" Click="OpenTempFolder_Click"/>
<MenuItem x:Name="menuClearTemp" Header="Clear temp folder" Click="ClearTempFolder_Click"/>
<Separator/>
<MenuItem x:Name="menuExit" Header="Exit" Click="Exit_Click"/>
</MenuItem>
<MenuItem x:Name="menuSettings" Header="Settings">
<MenuItem x:Name="menuUseApkEditor" Header="Use APKEditor for decompiling" IsCheckable="True"/>
<MenuItem x:Name="menuOpenSettings" Header="Open settings..." Click="OpenSettings_Click"/>
</MenuItem>
<MenuItem x:Name="menuHelp" Header="Help">
<MenuItem x:Name="menuCheckUpdate" Header="Check for update" Click="CheckUpdate_Click"/>
<MenuItem x:Name="menuReportIssue" Header="Report an issue" Click="ReportIssue_Click"/>
<MenuItem x:Name="menuApktoolIssues" Header="Apktool issue tracker" Click="ApktoolIssues_Click"/>
<MenuItem x:Name="menuBaksmaliIssues" Header="Baksmali issue tracker" Click="BaksmaliIssues_Click"/>
<MenuItem x:Name="menuAbout" Header="About" Click="About_Click"/>
</MenuItem>
</Menu>
<!-- ===== Status bar ===== -->
<StatusBar DockPanel.Dock="Bottom">
<StatusBarItem>
<StackPanel Orientation="Horizontal">
<Image x:Name="statusIcon" Width="16" Height="16" Margin="2,0,6,0" VerticalAlignment="Center"/>
<TextBlock x:Name="statusText" VerticalAlignment="Center" Text="Ready"/>
</StackPanel>
</StatusBarItem>
<StatusBarItem HorizontalAlignment="Right">
<ProgressBar x:Name="progressBar" Width="170" Height="14" Visibility="Collapsed"/>
</StatusBarItem>
</StatusBar>
<!-- ===== Tabs over log (resizable split) ===== -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="3*" MinHeight="220"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="180" MinHeight="100"/>
</Grid.RowDefinitions>
<TabControl x:Name="tabControlMain" Grid.Row="0">
<TabItem x:Name="tabMain" Header="Main">
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="3">
<StackPanel>
<!-- Decompile input -->
<TextBlock x:Name="label1" Text="APK/XAPK/APKS/ZIP/APKM File:" Margin="0,0,0,3"/>
<Grid Margin="0,0,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="textBox_DECODE_InputAppPath" Grid.Column="0" Height="25" VerticalContentAlignment="Center"/>
<Button x:Name="button_DECODE_BrowseInputAppPath" Grid.Column="1" Content="..." Width="34" Height="25" Margin="6,0,0,0"/>
<Button x:Name="button_DECODE_Decode" Grid.Column="2" Content="Decompile" Width="118" Height="25" Margin="6,0,0,0"/>
</Grid>
<!-- Compile input -->
<TextBlock x:Name="label2" Text="Decompiled APK folder:" Margin="0,0,0,3"/>
<Grid Margin="0,0,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="textBox_BUILD_InputProjectDir" Grid.Column="0" Height="25" VerticalContentAlignment="Center"/>
<Button x:Name="button_BUILD_BrowseInputProjectDir" Grid.Column="1" Content="..." Width="34" Height="25" Margin="6,0,0,0"/>
<Button x:Name="button_BUILD_Build" Grid.Column="2" Content="Compile" Width="118" Height="25" Margin="6,0,0,0"/>
</Grid>
<!-- Zipalign input -->
<TextBlock x:Name="label3" Text="APK file to align:" Margin="0,0,0,3"/>
<Grid Margin="0,0,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="textBox_ZIPALIGN_InputFile" Grid.Column="0" Height="25" VerticalContentAlignment="Center"/>
<Button x:Name="button_ZIPALIGN_BrowseInputFile" Grid.Column="1" Content="..." Width="34" Height="25" Margin="6,0,0,0"/>
<Button x:Name="button_ZIPALIGN_Align" Grid.Column="2" Content="Align" Width="118" Height="25" Margin="6,0,0,0"/>
</Grid>
<!-- Sign input -->
<TextBlock x:Name="label4" Text="APK File to sign:" Margin="0,0,0,3"/>
<Grid Margin="0,0,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="textBox_SIGN_InputFile" Grid.Column="0" Height="25" VerticalContentAlignment="Center"/>
<Button x:Name="button_SIGN_BrowseInputFile" Grid.Column="1" Content="..." Width="34" Height="25" Margin="6,0,0,0"/>
<Button x:Name="button_SIGN_Sign" Grid.Column="2" Content="Sign" Width="118" Height="25" Margin="6,0,0,0"/>
</Grid>
<!-- Merge split APK input -->
<TextBlock x:Name="splitApkTxt" Text="Merge split APK into single APK:" Margin="0,0,0,3"/>
<Grid Margin="0,0,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="splitApkPathTxtBox" Grid.Column="0" Height="25" VerticalContentAlignment="Center"/>
<Button x:Name="selSplitApkBtn" Grid.Column="1" Content="..." Width="34" Height="25" Margin="6,0,0,0"/>
<Button x:Name="mergeApkBtn" Grid.Column="2" Content="Merge" Width="118" Height="25" Margin="6,0,0,0"/>
</Grid>
<!-- Shortcut buttons (3 x 3) -->
<UniformGrid Columns="3" Rows="3">
<UniformGrid.Resources>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Margin" Value="3"/>
<Setter Property="Height" Value="30"/>
</Style>
</UniformGrid.Resources>
<Button x:Name="decOutOpenDirBtn" Content="Decompile output location"/>
<Button x:Name="decApkOpenDirBtn" Content="Decompiled APK location"/>
<Button x:Name="alignApkOpenDirBtn" Content="Zipalign APK location"/>
<Button x:Name="compileOutputOpenDirBtn" Content="Compile output location"/>
<Button x:Name="comApkOpenDir" Content="Compiled APK location"/>
<Button x:Name="signApkOpenDirBtn" Content="Sign APK location"/>
<Button x:Name="openAndroidMainfestBtn" Content="AndroidManifest.xml"/>
<Button x:Name="openApktoolYmlBtn" Content="Apktool.yml"/>
<Button x:Name="button_OpenMainActivity" Content="Main activity smali"/>
</UniformGrid>
</StackPanel>
</ScrollViewer>
</TabItem>
<TabItem x:Name="tabApkInfo" Header="APK Info">
<TabControl x:Name="tabControl1" Margin="3" BorderThickness="0" Background="Transparent">
<TabItem x:Name="basicInfoTabPage" Header="Basic info">
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="10">
<StackPanel>
<!-- File + icon -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label x:Name="label17" Grid.Column="0" Content="File:" Padding="0" VerticalAlignment="Center" Margin="0,0,8,0"/>
<TextBox x:Name="fileTxtBox" Grid.Column="1" Height="24" IsReadOnly="True" VerticalContentAlignment="Center"/>
<Button x:Name="selApkFileInfoBtn" Grid.Column="2" Content="..." Width="34" Height="24" Margin="6,0,0,0"/>
</Grid>
<Grid Margin="0,3,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label x:Name="label7" Grid.Row="0" Grid.Column="0" Content="App name:" Padding="0" VerticalAlignment="Center" Margin="0,4,8,4"/>
<TextBox x:Name="appTxtBox" Grid.Row="0" Grid.Column="1" Height="24" IsReadOnly="True" VerticalContentAlignment="Center" Margin="0,4"/>
<Label x:Name="label9" Grid.Row="1" Grid.Column="0" Content="Package name:" Padding="0" VerticalAlignment="Center" Margin="0,4,8,4"/>
<TextBox x:Name="packNameTxtBox" Grid.Row="1" Grid.Column="1" Height="24" IsReadOnly="True" VerticalContentAlignment="Center" Margin="0,4"/>
</Grid>
</StackPanel>
<Border Grid.Column="1" Width="88" Height="88" Margin="12,0,0,0" VerticalAlignment="Top"
Background="{DynamicResource PanelBackground}" BorderBrush="{DynamicResource PanelBorder}" BorderThickness="1">
<Image x:Name="apkIconPicBox" Stretch="Uniform" Margin="2"/>
</Border>
</Grid>
<!-- Links -->
<Label x:Name="label19" Content="Links:" Padding="0" Margin="0,3,0,3"/>
<UniformGrid Columns="3" Rows="2">
<UniformGrid.Resources>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Margin" Value="3"/>
<Setter Property="Height" Value="28"/>
</Style>
</UniformGrid.Resources>
<Button x:Name="psLinkBtn" Content="Play Store"/>
<Button x:Name="apkComboLinkBtn" Content="ApkCombo"/>
<Button x:Name="apkPureLinkBtn" Content="ApkPure"/>
<Button x:Name="apkGkLinkBtn" Content="ApkGk"/>
<Button x:Name="apkSupportLinkBtn" Content="Apk.support"/>
<Button x:Name="apkMirrorLinkBtn" Content="Apk Mirror"/>
</UniformGrid>
<!-- Fields -->
<Grid Margin="0,3,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label x:Name="label31" Grid.Row="0" Grid.Column="0" Content="Launch activity:" Padding="0" VerticalAlignment="Center" Margin="0,4,8,4"/>
<TextBox x:Name="launchActivityTxtBox" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="3" Height="24" IsReadOnly="True" VerticalContentAlignment="Center" Margin="0,4"/>
<Label x:Name="label8" Grid.Row="1" Grid.Column="0" Content="Version:" Padding="0" VerticalAlignment="Center" Margin="0,4,8,4"/>
<TextBox x:Name="verTxtBox" Grid.Row="1" Grid.Column="1" Height="24" IsReadOnly="True" VerticalContentAlignment="Center" Margin="0,4,16,4"/>
<Label x:Name="label10" Grid.Row="1" Grid.Column="2" Content="Build:" Padding="0" VerticalAlignment="Center" Margin="0,4,8,4"/>
<TextBox x:Name="buildTxtBox" Grid.Row="1" Grid.Column="3" Height="24" IsReadOnly="True" VerticalContentAlignment="Center" Margin="0,4"/>
<Label x:Name="label11" Grid.Row="2" Grid.Column="0" Content="Min. SDK" Padding="0" VerticalAlignment="Center" Margin="0,4,8,4"/>
<TextBox x:Name="minSdkTxtBox" Grid.Row="2" Grid.Column="1" Height="24" IsReadOnly="True" VerticalContentAlignment="Center" Margin="0,4,16,4"/>
<Label x:Name="label12" Grid.Row="2" Grid.Column="2" Content="Target SDK:" Padding="0" VerticalAlignment="Center" Margin="0,4,8,4"/>
<TextBox x:Name="targetSdkTxtBox" Grid.Row="2" Grid.Column="3" Height="24" IsReadOnly="True" VerticalContentAlignment="Center" Margin="0,4"/>
<Label x:Name="label13" Grid.Row="3" Grid.Column="0" Content="Screen sizes: " Padding="0" VerticalAlignment="Center" Margin="0,4,8,4"/>
<TextBox x:Name="screenTxtBox" Grid.Row="3" Grid.Column="1" Height="24" IsReadOnly="True" VerticalContentAlignment="Center" Margin="0,4,16,4"/>
<Label x:Name="label30" Grid.Row="3" Grid.Column="2" Content="Architectures:" Padding="0" VerticalAlignment="Center" Margin="0,4,8,4"/>
<TextBox x:Name="archSdkTxtBox" Grid.Row="3" Grid.Column="3" Height="24" IsReadOnly="True" VerticalContentAlignment="Center" Margin="0,4"/>
<Label x:Name="label14" Grid.Row="4" Grid.Column="0" Content="Densities: " Padding="0" VerticalAlignment="Center" Margin="0,4,8,4"/>
<TextBox x:Name="densityTxtBox" Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="3" Height="24" IsReadOnly="True" VerticalContentAlignment="Center" Margin="0,4"/>
</Grid>
<Label x:Name="label18" Content="Locals: " Padding="0" Margin="0,10,0,2"/>
<RichTextBox x:Name="localsTxtBox" Height="64" IsReadOnly="True" VerticalScrollBarVisibility="Auto"/>
<Label x:Name="label15" Content="Permissions: " Padding="0" Margin="0,10,0,2"/>
<RichTextBox x:Name="permTxtBox" Height="120" IsReadOnly="True" VerticalScrollBarVisibility="Auto"/>
</StackPanel>
</ScrollViewer>
</TabItem>
<TabItem x:Name="tabPage3" Header="AAPT dump">
<RichTextBox x:Name="fullInfoTextBox" Margin="3" IsReadOnly="True"
VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
FontFamily="Consolas"/>
</TabItem>
<TabItem x:Name="signatureTabPage" Header="Signature">
<RichTextBox x:Name="sigTxtBox" Margin="3" IsReadOnly="True"
VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
FontFamily="Consolas"/>
</TabItem>
</TabControl>
</TabItem>
<TabItem x:Name="tabDecode" Header="Decode">
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="10">
<GroupBox x:Name="groupBox_DECODE_Options" Header="Options">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<CheckBox x:Name="decSetApiLvlChkBox" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Margin="0,4"
Content="Set API level of the file to generate, e.g. 14 for ICS."/>
<ctrl:NumericUpDown x:Name="decApiLvlUpDown" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Width="70" Margin="0,4"
Minimum="0" Maximum="35"/>
<CheckBox x:Name="checkBox_DECODE_NoSrc" Grid.Row="1" Grid.ColumnSpan="3" Margin="0,4" Content="Do not decode sources."/>
<CheckBox x:Name="checkBox_DECODE_NoRes" Grid.Row="2" Grid.ColumnSpan="3" Margin="0,4" Content="Do not decode resources."/>
<CheckBox x:Name="checkBox_DECODE_Force" Grid.Row="3" Grid.ColumnSpan="3" Margin="0,4" Content="Force delete destination directory."/>
<CheckBox x:Name="checkBox_DECODE_KeepBrokenRes" Grid.Row="4" Grid.ColumnSpan="3" Margin="0,4" Content="Keep broken resource."/>
<CheckBox x:Name="checkBox_DECODE_MatchOriginal" Grid.Row="5" Grid.ColumnSpan="3" Margin="0,4" Content="Keeps files to closest to original as possible. Prevents rebuild."/>
<CheckBox x:Name="checkBox_DECODE_UseFramework" Grid.Row="6" Grid.Column="0" VerticalAlignment="Center" Margin="0,4"
Content="Uses framework files located in:"/>
<TextBox x:Name="textBox_DECODE_FrameDir" Grid.Row="6" Grid.Column="1" Width="236" Height="24" Margin="10,4,0,4" VerticalContentAlignment="Center"/>
<Button x:Name="button_DECODE_BrowseFrameDir" Grid.Row="6" Grid.Column="2" Content="..." Width="34" Height="24" Margin="6,4,0,4"/>
<CheckBox x:Name="checkBox_DECODE_OutputDirectory" Grid.Row="7" Grid.Column="0" VerticalAlignment="Center" Margin="0,4"
Content="Output directory:"/>
<TextBox x:Name="textBox_DECODE_OutputDirectory" Grid.Row="7" Grid.Column="1" Width="236" Height="24" Margin="10,4,0,4" VerticalContentAlignment="Center"/>
<Button x:Name="button_DECODE_BrowseOutputDirectory" Grid.Row="7" Grid.Column="2" Content="..." Width="34" Height="24" Margin="6,4,0,4"/>
<CheckBox x:Name="checkBox_DECODE_OnlyMainClasses" Grid.Row="8" Grid.ColumnSpan="3" Margin="0,4" Content="Only disassemble the main dex classes (classes[0-9]*.dex) in the root. (&lt;2.12.1)"/>
<CheckBox x:Name="checkBox_DECODE_FixError" Grid.Row="9" Grid.ColumnSpan="3" Margin="0,4" Content="Fix ApkTool errors after decompile"/>
<CheckBox x:Name="checkBox_DECODE_NoDebugInfo" Grid.Row="10" Grid.ColumnSpan="3" Margin="0,4" Content="Don't write out debug info (.local, .param, .line, etc.)"/>
<CheckBox x:Name="checkBox7" Grid.Row="11" Grid.ColumnSpan="3" Margin="0,4" Content="Don't parse APK info when selecting APK for decompiling"/>
<CheckBox x:Name="checkBox3" Grid.Row="12" Grid.Column="0" VerticalAlignment="Center" Margin="0,4" Content="Set the number of threads to use."/>
<ctrl:NumericUpDown x:Name="decJobsLvlUpDown" Grid.Row="12" Grid.Column="1" HorizontalAlignment="Right" Width="70" Margin="0,4" Minimum="1" Maximum="64"/>
</Grid>
</GroupBox>
</ScrollViewer>
</TabItem>
<TabItem x:Name="tabBuild" Header="Build">
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="10">
<GroupBox x:Name="groupBox_BUILD_Options" Header="Options">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<CheckBox x:Name="buildSetApiLvlChkBox" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Margin="0,4"
Content="Set API level of the file to generate, e.g. 14 for ICS."/>
<ctrl:NumericUpDown x:Name="buildApiLvlUpDown" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Width="70" Margin="0,4" Minimum="0" Maximum="35"/>
<CheckBox x:Name="checkBox_BUILD_ForceAll" Grid.Row="1" Grid.ColumnSpan="3" Margin="0,4" Content="Skip changes detection and build all files."/>
<CheckBox x:Name="checkBox_BUILD_UseAapt" Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" Margin="0,4" Content="Uses aapt.exe located in:"/>
<TextBox x:Name="textBox_BUILD_AaptPath" Grid.Row="2" Grid.Column="1" Width="236" Height="24" Margin="10,4,0,4" VerticalContentAlignment="Center"/>
<Button x:Name="button_BUILD_BrowseAaptPath" Grid.Row="2" Grid.Column="2" Content="..." Width="34" Height="24" Margin="6,4,0,4"/>
<CheckBox x:Name="checkBox_BUILD_UseFramework" Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" Margin="0,4" Content="Uses framework files located in:"/>
<TextBox x:Name="textBox_BUILD_FrameDir" Grid.Row="3" Grid.Column="1" Width="236" Height="24" Margin="10,4,0,4" VerticalContentAlignment="Center"/>
<Button x:Name="button_BUILD_BrowseFrameDir" Grid.Row="3" Grid.Column="2" Content="..." Width="34" Height="24" Margin="6,4,0,4"/>
<CheckBox x:Name="checkBox_BUILD_OutputAppPath" Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" Margin="0,4" Content="APK output directory:"/>
<TextBox x:Name="textBox_BUILD_OutputAppPath" Grid.Row="4" Grid.Column="1" Width="236" Height="24" Margin="10,4,0,4" VerticalContentAlignment="Center"/>
<Button x:Name="button_BUILD_BrowseOutputAppPath" Grid.Row="4" Grid.Column="2" Content="..." Width="34" Height="24" Margin="6,4,0,4"/>
<CheckBox x:Name="checkBox_BUILD_NoCrunch" Grid.Row="5" Grid.ColumnSpan="3" Margin="0,4" Content="Disable crunching of resource files during the build step."/>
<CheckBox x:Name="checkBox_BUILD_NetSecConf" Grid.Row="6" Grid.ColumnSpan="3" Margin="0,4" Content="Add a generic Network Security Configuration file in the output APK"/>
<CheckBox x:Name="zipalignAfterBuildChkBox" Grid.Row="7" Grid.ColumnSpan="3" Margin="0,4" Content="Zipalign after build"/>
<CheckBox x:Name="signAfterBuildChkBox" Grid.Row="8" Grid.ColumnSpan="3" Margin="0,4" Content="Sign after build / zipalign"/>
<CheckBox x:Name="createUnsignApkChkBox" Grid.Row="9" Grid.ColumnSpan="3" Margin="0,4" Content="Create unsigned APK with original signature after build"/>
<CheckBox x:Name="useAapt2ChkBox" Grid.Row="10" Grid.ColumnSpan="3" Margin="0,4" Content="Use aapt2 (Upgrades apktool to use experimental aapt2 binary.) (&lt; 2.11.1)"/>
<CheckBox x:Name="checkBox_BUILD_CopyOriginal" Grid.Row="11" Grid.ColumnSpan="3" Margin="0,4" Content="Copy original AndroidManifest.xml and META-INF folder"/>
<CheckBox x:Name="checkBox4" Grid.Row="12" Grid.Column="0" VerticalAlignment="Center" Margin="0,4" Content="Set the number of threads to use."/>
<ctrl:NumericUpDown x:Name="comJobsLvlUpDown" Grid.Row="12" Grid.Column="1" HorizontalAlignment="Right" Width="70" Margin="0,4" Minimum="1" Maximum="64"/>
</Grid>
</GroupBox>
</ScrollViewer>
</TabItem>
<TabItem x:Name="tabSign" Header="Sign">
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="10">
<GroupBox x:Name="groupBox_SIGN_Options" Header="Options">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="label22" Grid.Row="0" Grid.ColumnSpan="3" TextWrapping="Wrap" Margin="0,0,0,8"
Foreground="{DynamicResource SecondaryText}"
Text="It is strongly recommended that you use your own key, created via Android Studio or other tools"/>
<Label x:Name="label_SIGN_PublicKey" Grid.Row="1" Grid.Column="0" Content="Public key:" Padding="0" VerticalAlignment="Center" Margin="0,4,10,4"/>
<TextBox x:Name="textBox_SIGN_PublicKey" Grid.Row="1" Grid.Column="1" Height="24" Margin="0,4" VerticalContentAlignment="Center"/>
<Button x:Name="button_SIGN_BrowsePublicKey" Grid.Row="1" Grid.Column="2" Content="..." Width="34" Height="24" Margin="6,4,0,4"/>
<Label x:Name="label_SIGN_PrivateKey" Grid.Row="2" Grid.Column="0" Content="Private key:" Padding="0" VerticalAlignment="Center" Margin="0,4,10,4"/>
<TextBox x:Name="textBox_SIGN_PrivateKey" Grid.Row="2" Grid.Column="1" Height="24" Margin="0,4" VerticalContentAlignment="Center"/>
<Button x:Name="button_SIGN_BrowsePrivateKey" Grid.Row="2" Grid.Column="2" Content="..." Width="34" Height="24" Margin="6,4,0,4"/>
<CheckBox x:Name="useAliasChkBox" Grid.Row="3" Grid.Column="0" Content="Alias:" VerticalAlignment="Center" Margin="0,4,10,4"/>
<TextBox x:Name="aliasTxtBox" Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" Height="24" Margin="0,4" VerticalContentAlignment="Center"/>
<CheckBox x:Name="useKeyStoreChkBox" Grid.Row="4" Grid.ColumnSpan="3" Content="Use keystore" Margin="0,6,0,4"/>
<Label x:Name="label20" Grid.Row="5" Grid.Column="0" Content="keystore/jks file:" Padding="0" VerticalAlignment="Center" Margin="0,4,10,4"/>
<TextBox x:Name="keyStoreFileTxtBox" Grid.Row="5" Grid.Column="1" Height="24" Margin="0,4" VerticalContentAlignment="Center"/>
<Button x:Name="selectKeyStoreFileBtn" Grid.Row="5" Grid.Column="2" Content="..." Width="34" Height="24" Margin="6,4,0,4"/>
<Label x:Name="label21" Grid.Row="6" Grid.Column="0" Content="Password:" Padding="0" VerticalAlignment="Center" Margin="0,4,10,4"/>
<PasswordBox x:Name="textBox3" Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2" Height="24" Margin="0,4" VerticalContentAlignment="Center"/>
<Label x:Name="label23" Grid.Row="7" Grid.Column="0" Content="Private key password:" Padding="0" VerticalAlignment="Center" Margin="0,4,10,4"/>
<PasswordBox x:Name="textBox4" Grid.Row="7" Grid.Column="1" Grid.ColumnSpan="2" Height="24" Margin="0,4" VerticalContentAlignment="Center"/>
<CheckBox x:Name="useSigningOutputDir" Grid.Row="8" Grid.Column="0" Content="APK output directory:" VerticalAlignment="Center" Margin="0,4,10,4"/>
<TextBox x:Name="textBox_SIGN_OutputFile" Grid.Row="8" Grid.Column="1" Height="24" Margin="0,4" VerticalContentAlignment="Center"/>
<Button x:Name="button_SIGN_BrowseOutputFile" Grid.Row="8" Grid.Column="2" Content="..." Width="34" Height="24" Margin="6,4,0,4"/>
<Grid Grid.Row="9" Grid.ColumnSpan="3" Margin="0,6,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label x:Name="label24" Grid.Column="0" Content="Scheme v1:" Padding="0" VerticalAlignment="Center" Margin="0,0,8,0"/>
<ComboBox x:Name="schemev1ComboBox" Grid.Column="1" Margin="0,0,16,0">
<ComboBoxItem>Default</ComboBoxItem>
<ComboBoxItem>True</ComboBoxItem>
<ComboBoxItem>False</ComboBoxItem>
</ComboBox>
<Label x:Name="label25" Grid.Column="2" Content="Scheme v2:" Padding="0" VerticalAlignment="Center" Margin="0,0,8,0"/>
<ComboBox x:Name="schemev2ComboBox" Grid.Column="3">
<ComboBoxItem>Default</ComboBoxItem>
<ComboBoxItem>True</ComboBoxItem>
<ComboBoxItem>False</ComboBoxItem>
</ComboBox>
</Grid>
<Grid Grid.Row="10" Grid.ColumnSpan="3" Margin="0,6,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label x:Name="label26" Grid.Column="0" Content="Scheme v3:" Padding="0" VerticalAlignment="Center" Margin="0,0,8,0"/>
<ComboBox x:Name="schemev3ComboBox" Grid.Column="1" Margin="0,0,16,0">
<ComboBoxItem>Default</ComboBoxItem>
<ComboBoxItem>True</ComboBoxItem>
<ComboBoxItem>False</ComboBoxItem>
</ComboBox>
<Label x:Name="label27" Grid.Column="2" Content="Scheme v4:" Padding="0" VerticalAlignment="Center" Margin="0,0,8,0"/>
<ComboBox x:Name="schemev4ComboBox" Grid.Column="3">
<ComboBoxItem>Default</ComboBoxItem>
<ComboBoxItem>True</ComboBoxItem>
<ComboBoxItem>False</ComboBoxItem>
</ComboBox>
</Grid>
<CheckBox x:Name="autoDelIdsigChkBox" Grid.Row="11" Grid.ColumnSpan="3" Margin="0,8,0,4" Content="Auto delete idsig file"/>
<CheckBox x:Name="checkBox1" Grid.Row="12" Grid.ColumnSpan="3" Margin="0,4" Content="Overwrite input file"/>
<CheckBox x:Name="checkBox2" Grid.Row="13" Grid.ColumnSpan="3" Margin="0,4" Content="Install APK after signing (Make sure the device is selected in ADB tab first)"/>
</Grid>
</GroupBox>
</ScrollViewer>
</TabItem>
<TabItem x:Name="tabZipalign" Header="Zip align">
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="10">
<GroupBox x:Name="groupBox_ZIPALIGN_Options" Header="Options">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label x:Name="label_ZIPALIGN_AlignmentBytes" Grid.Row="0" Grid.Column="0" Padding="0" VerticalAlignment="Center" Margin="0,4"
Content="Alignment in bytes, e.g. '4' provides 32-bit alignment"/>
<ctrl:NumericUpDown x:Name="numericUpDown_ZIPALIGN_AlignmentBytes" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Width="70" Margin="0,4" Minimum="1" Maximum="64"/>
<CheckBox x:Name="checkBox_ZIPALIGN_CheckAlignment" Grid.Row="1" Grid.ColumnSpan="3" Margin="0,4" Content="Check alignment only (does not modify file)"/>
<CheckBox x:Name="checkBox_ZIPALIGN_VerboseOutput" Grid.Row="2" Grid.ColumnSpan="3" Margin="0,4" Content="Verbose output"/>
<CheckBox x:Name="checkBox_ZIPALIGN_Recompress" Grid.Row="3" Grid.ColumnSpan="3" Margin="0,4" Content="Recompress using Zopfli"/>
<CheckBox x:Name="checkBox_ZIPALIGN_OverwriteOutputFile" Grid.Row="4" Grid.ColumnSpan="3" Margin="0,4" Content="Overwrite existing output file"/>
<CheckBox x:Name="signAfterZipalignChkBox" Grid.Row="5" Grid.ColumnSpan="3" Margin="0,4" Content="Sign after zipalign"/>
<CheckBox x:Name="zipalignOutputDirChkBox" Grid.Row="6" Grid.Column="0" VerticalAlignment="Center" Margin="0,4" Content="APK output directory:"/>
<TextBox x:Name="textBox_ZIPALIGN_OutputFile" Grid.Row="6" Grid.Column="1" Width="236" Height="24" Margin="10,4,0,4" VerticalContentAlignment="Center"/>
<Button x:Name="button_ZIPALIGN_BrowseOutputFile" Grid.Row="6" Grid.Column="2" Content="..." Width="34" Height="24" Margin="6,4,0,4"/>
</Grid>
</GroupBox>
</ScrollViewer>
</TabItem>
<TabItem x:Name="tabFramework" Header="Framework">
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="10">
<StackPanel>
<GroupBox x:Name="groupBox_IF_Options" Header="Install Framework">
<StackPanel>
<Grid Margin="0,4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<CheckBox x:Name="checkBox_IF_FramePath" Grid.Column="0" VerticalAlignment="Center" Margin="0,0,10,0" Content="Stores framework files into:"/>
<TextBox x:Name="textBox_IF_FrameDir" Grid.Column="1" Height="24" VerticalContentAlignment="Center"/>
<Button x:Name="button_IF_BrowseFrameDir" Grid.Column="2" Content="..." Width="34" Height="24" Margin="6,0,0,0"/>
</Grid>
<Grid Margin="0,4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<CheckBox x:Name="checkBox_IF_Tag" Grid.Column="0" VerticalAlignment="Center" Margin="0,0,10,0" Content="Tag frameworks using:"/>
<TextBox x:Name="textBox_IF_Tag" Grid.Column="1" Height="24" VerticalContentAlignment="Center"/>
</Grid>
<Grid Margin="0,4,0,4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="textBox_IF_InputFramePath" Grid.Column="0" Height="24" VerticalContentAlignment="Center"/>
<Button x:Name="button_IF_BrowseInputFramePath" Grid.Column="1" Content="..." Width="34" Height="24" Margin="6,0,0,0"/>
<Button x:Name="button_IF_InstallFramework" Grid.Column="2" Content="Install" Width="90" Height="24" Margin="6,0,0,0"/>
</Grid>
</StackPanel>
</GroupBox>
<GroupBox x:Name="groupBox1" Header="Options">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<CheckBox x:Name="clearFwBeforeDecodeChkBox" Grid.Column="0" VerticalAlignment="Center" Margin="0,4" Content="Clear framework before decompiling"/>
<Button x:Name="clearFwBtn" Grid.Column="1" Content="Clear framework" Height="26" Padding="10,0" Margin="6,4,0,4"/>
</Grid>
<Button x:Name="openFwFolderBtn" HorizontalAlignment="Left" Content="Open framework folder" Height="26" Padding="10,0" Margin="0,8,0,4"/>
</StackPanel>
</GroupBox>
</StackPanel>
</ScrollViewer>
</TabItem>
<TabItem x:Name="tabBaksmali" Header="Baksmali">
<ScrollViewer VerticalScrollBarVisibility="Auto" Padding="10">
<StackPanel>
<GroupBox x:Name="bakSmaliGroupBox" Header="Baksmali">
<StackPanel>
<Grid Margin="0,4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<CheckBox x:Name="baksmaliUseOutputChkBox" Grid.Column="0" VerticalAlignment="Center" Margin="0,0,10,0" Content="Folder output directory:"/>
<TextBox x:Name="baksmaliBrowseOutputTxtBox" Grid.Column="1" Height="24" VerticalContentAlignment="Center"/>
<Button x:Name="baksmaliBrowseOutputBtn" Grid.Column="2" Content="..." Width="34" Height="24" Margin="6,0,0,0"/>
</Grid>
<Label x:Name="label28" Content="Dex to decompile:" Padding="0" Margin="0,8,0,2"/>
<Grid Margin="0,2,0,4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="baksmaliBrowseInputDexTxtBox" Grid.Column="0" Height="24" VerticalContentAlignment="Center"/>
<Button x:Name="baksmaliBrowseInputDexBtn" Grid.Column="1" Content="..." Width="34" Height="24" Margin="6,0,0,0"/>
<Button x:Name="decSmaliBtn" Grid.Column="2" Content="Decompile" Width="100" Height="24" Margin="6,0,0,0"/>
</Grid>
</StackPanel>
</GroupBox>
<GroupBox x:Name="smaliGroupBox" Header="Smali">
<StackPanel>
<Grid Margin="0,4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<CheckBox x:Name="smaliUseOutputChkBox" Grid.Column="0" VerticalAlignment="Center" Margin="0,0,10,0" Content="Dex output directory:"/>
<TextBox x:Name="smaliBrowseOutputTxtBox" Grid.Column="1" Height="24" VerticalContentAlignment="Center"/>
<Button x:Name="smaliBrowseOutputBtn" Grid.Column="2" Content="..." Width="34" Height="24" Margin="6,0,0,0"/>
</Grid>
<Label x:Name="label29" Content="Smali folder to compile:" Padding="0" Margin="0,8,0,2"/>
<Grid Margin="0,2,0,4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="smaliBrowseInputDirTxtBox" Grid.Column="0" Height="24" VerticalContentAlignment="Center"/>
<Button x:Name="smaliBrowseInputDirBtn" Grid.Column="1" Content="..." Width="34" Height="24" Margin="6,0,0,0"/>
<Button x:Name="comSmaliBtn" Grid.Column="2" Content="Compile" Width="100" Height="24" Margin="6,0,0,0"/>
</Grid>
</StackPanel>
</GroupBox>
</StackPanel>
</ScrollViewer>
</TabItem>
<TabItem x:Name="tabAdb" Header="ADB">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,4">
<TextBlock x:Name="label33" Text="Selected device: " VerticalAlignment="Center"/>
<TextBlock x:Name="selAdbDeviceLbl" VerticalAlignment="Center"/>
</StackPanel>
<CheckBox x:Name="setVendorChkBox" Grid.Row="1" Margin="0,6" Content="Set vendor to Play Store (com.android.vending)"/>
<StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,6">
<CheckBox x:Name="overrideAbiCheckBox" VerticalAlignment="Center" Content="Override platform's default ABI: "/>
<ComboBox x:Name="overrideAbiComboBox" Width="150" Margin="8,0,0,0">
<ComboBoxItem>arm64-v8a</ComboBoxItem>
<ComboBoxItem>armeabi-v7a</ComboBoxItem>
<ComboBoxItem>x86</ComboBoxItem>
<ComboBoxItem>x86_64</ComboBoxItem>
</ComboBox>
</StackPanel>
<Grid Grid.Row="3" Margin="0,6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="label32" Grid.Column="0" Text="Selected APK: " VerticalAlignment="Center" Margin="0,0,8,0"/>
<TextBox x:Name="apkPathAdbTxtBox" Grid.Column="1" Height="24" VerticalContentAlignment="Center"/>
<Button x:Name="selApkAdbBtn" Grid.Column="2" Content="..." Width="34" Height="24" Margin="6,0,0,0"/>
</Grid>
<Grid Grid.Row="4" Margin="0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button x:Name="killAdbBtn" Grid.Column="0" Content="Kill adb process" Height="28" Padding="10,0"/>
<Button x:Name="refreshDevicesBtn" Grid.Column="1" Content="Refresh" Height="28" Padding="14,0" Margin="8,0,0,0"/>
<Button x:Name="installApkBtn" Grid.Column="3" Content="Install APK" Height="28" Padding="12,0"/>
</Grid>
<ListBox x:Name="devicesListBox" Grid.Row="5" Margin="0,4,0,0"/>
</Grid>
</TabItem>
</TabControl>
<GridSplitter Grid.Row="1" Height="5" HorizontalAlignment="Stretch"
VerticalAlignment="Center" Margin="0,3" ResizeBehavior="PreviousAndNext"/>
<!-- Virtualized, console-style log: replaces the slow FlowDocument RichTextBox.
LogView implements IScrollInfo, so the host ScrollViewer (CanContentScroll=True)
drives the themed scroll bars. -->
<Border Grid.Row="2" BorderBrush="{DynamicResource PanelBorder}" BorderThickness="1"
Background="{DynamicResource LogBackground}">
<ScrollViewer CanContentScroll="True" Focusable="False"
VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<ctrl:LogView x:Name="logTxtBox"
FontFamily="Consolas" FontSize="12"
Foreground="{DynamicResource PrimaryText}"
Background="{DynamicResource LogBackground}">
<ctrl:LogView.ContextMenu>
<ContextMenu>
<MenuItem x:Name="menuLogCopy" Header="Copy" InputGestureText="Ctrl+C" Click="LogCopy_Click"/>
<MenuItem x:Name="menuLogCopyAll" Header="Copy all" Click="LogCopyAll_Click"/>
<Separator/>
<MenuItem x:Name="menuLogClear" Header="Clear log" Click="LogClear_Click"/>
</ContextMenu>
</ctrl:LogView.ContextMenu>
</ctrl:LogView>
</ScrollViewer>
</Border>
</Grid>
</DockPanel>
</Window>
+521
View File
@@ -0,0 +1,521 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Media;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using APKToolGUI.ApkTool;
using APKToolGUI.Controls;
using APKToolGUI.Properties;
using APKToolGUI.Utils;
using Ionic.Zip;
using Java;
using Microsoft.WindowsAPICodePack.Taskbar;
using Ookii.Dialogs.WinForms;
using Lang = APKToolGUI.Languages.Language;
using WinForms = System.Windows.Forms;
using DColor = System.Drawing.Color;
using Res = APKToolGUI.Properties.Resources;
namespace APKToolGUI.Forms
{
/// <summary>
/// The main application window. This file holds the constructor, settings bindings,
/// event wiring, window lifecycle and menu; <c>MainWindow.Logic.cs</c> holds the
/// apktool operation logic, the control event handlers, localization and drag-drop.
/// </summary>
public partial class MainWindow : Window
{
internal Adb adb;
internal ApkEditor apkeditor;
internal Apktool apktool;
internal Signapk signapk;
internal Baksmali baksmali;
internal Smali smali;
internal Zipalign zipalign;
internal UpdateChecker updateCheker;
internal AaptParser aapt;
private bool IgnoreOutputDirContextMenu;
private bool isRunning;
private string javaPath;
private readonly System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
private string lastStartedDate;
private System.Drawing.Bitmap previousApkIcon;
private IntPtr _hwnd = IntPtr.Zero;
internal static MainWindow Instance { get; private set; }
public MainWindow()
{
Instance = this;
Program.SetLanguage();
InitializeComponent();
Theme theme = (Theme)Settings.Default.Theme;
WpfTheme.Apply(this, Program.IsDarkTheme());
NativeDarkMode.ApplyTheme(this, theme);
Title = "APK Tool GUI - v" + WinForms.Application.ProductVersion;
menuUseApkEditor.IsChecked = Settings.Default.UseApkeditor;
Log.Output = ToLog;
ApplyLocalization();
aapt = new AaptParser();
// Validate stored paths (mirrors the old FormMain constructor)
if (!File.Exists(Settings.Default.Decode_InputAppPath)) Settings.Default.Decode_InputAppPath = "";
if (!Directory.Exists(Settings.Default.Build_InputDir)) Settings.Default.Build_InputDir = "";
if (!File.Exists(Settings.Default.Sign_InputFile)) Settings.Default.Sign_InputFile = "";
if (!File.Exists(Settings.Default.Zipalign_InputFile)) Settings.Default.Zipalign_InputFile = "";
if (!File.Exists(Settings.Default.Sign_PrivateKey) || String.IsNullOrEmpty(Settings.Default.Sign_PrivateKey)) Settings.Default.Sign_PrivateKey = Program.SIGNAPK_KEYPRIVATE;
if (!File.Exists(Settings.Default.Sign_PublicKey) || String.IsNullOrEmpty(Settings.Default.Sign_PublicKey)) Settings.Default.Sign_PublicKey = Program.SIGNAPK_KEYPUBLIC;
BindSettings();
schemev1ComboBox.SelectedIndex = Clamp(Settings.Default.Sign_Schemev1, schemev1ComboBox.Items.Count);
schemev2ComboBox.SelectedIndex = Clamp(Settings.Default.Sign_Schemev2, schemev2ComboBox.Items.Count);
schemev3ComboBox.SelectedIndex = Clamp(Settings.Default.Sign_Schemev3, schemev3ComboBox.Items.Count);
schemev4ComboBox.SelectedIndex = (Settings.Default.Sign_Schemev4 >= 0 && Settings.Default.Sign_Schemev4 < schemev4ComboBox.Items.Count) ? Settings.Default.Sign_Schemev4 : 2;
overrideAbiComboBox.SelectedIndex = Clamp(Settings.Default.Adb_OverrideAbi, overrideAbiComboBox.Items.Count);
WireEvents();
Loaded += MainWindow_Loaded;
Closing += MainWindow_Closing;
Activated += (s, e) => { if (!isRunning && _hwnd != IntPtr.Zero) TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.NoProgress, _hwnd); };
}
private static int Clamp(int value, int count)
{
return (value >= 0 && value < count) ? value : 0;
}
#region Settings bindings
private void BindSettings()
{
BindText(textBox_DECODE_InputAppPath, "Decode_InputAppPath");
BindChecked(checkBox_DECODE_NoSrc, "Decode_NoSrc");
BindChecked(checkBox_DECODE_NoRes, "Decode_NoRes");
BindChecked(checkBox_DECODE_Force, "Decode_Force");
BindChecked(checkBox_DECODE_KeepBrokenRes, "Decode_KeepBrokenRes");
BindChecked(checkBox_DECODE_MatchOriginal, "Decode_MatchOriginal");
BindChecked(checkBox_DECODE_OnlyMainClasses, "Decode_OnlyMainClasses");
BindChecked(checkBox_DECODE_NoDebugInfo, "Decode_NoDebugInfo");
BindChecked(checkBox_DECODE_FixError, "Decode_FixError");
BindChecked(checkBox7, "Decode_DontParseApkInfo");
BindChecked(checkBox_DECODE_UseFramework, "Decode_UseFramework");
BindChecked(checkBox_DECODE_OutputDirectory, "Decode_UseOutputDir");
BindText(textBox_DECODE_FrameDir, "Framework_FrameDir");
BindText(textBox_DECODE_OutputDirectory, "Decode_OutputDir");
BindChecked(decSetApiLvlChkBox, "Decode_SetApiLevel");
BindValue(decApiLvlUpDown, "Decode_ApiLevel");
BindChecked(checkBox3, "Decode_SetJobs");
BindValue(decJobsLvlUpDown, "Decode_Jobs");
BindEnabled(textBox_DECODE_FrameDir, "Decode_UseFramework");
BindEnabled(button_DECODE_BrowseFrameDir, "Decode_UseFramework");
BindEnabled(textBox_DECODE_OutputDirectory, "Decode_UseOutputDir");
BindEnabled(button_DECODE_BrowseOutputDirectory, "Decode_UseOutputDir");
BindText(textBox_BUILD_InputProjectDir, "Build_InputDir");
BindChecked(checkBox_BUILD_ForceAll, "Build_ForceAll");
BindChecked(checkBox_BUILD_UseAapt, "Build_UseAapt");
BindText(textBox_BUILD_AaptPath, "Build_AaptPath");
BindChecked(checkBox_BUILD_UseFramework, "Build_UseFramework");
BindText(textBox_BUILD_FrameDir, "Framework_FrameDir");
BindChecked(checkBox_BUILD_OutputAppPath, "Build_UseOutputAppPath");
BindText(textBox_BUILD_OutputAppPath, "Build_OutputAppPath");
BindChecked(checkBox_BUILD_NoCrunch, "Build_NoCrunch");
BindChecked(checkBox_BUILD_NetSecConf, "Build_NetSecConf");
BindChecked(zipalignAfterBuildChkBox, "Build_ZipalignAfterBuild");
BindChecked(signAfterBuildChkBox, "Build_SignAfterBuild");
BindChecked(createUnsignApkChkBox, "Build_CreateUnsignedApk");
BindChecked(useAapt2ChkBox, "Build_UseAapt2");
BindChecked(checkBox_BUILD_CopyOriginal, "Build_CopyOriginal");
BindChecked(buildSetApiLvlChkBox, "Build_SetApiLevel");
BindValue(buildApiLvlUpDown, "Build_ApiLevel");
BindChecked(checkBox4, "Build_SetJobs");
BindValue(comJobsLvlUpDown, "Build_Jobs");
BindEnabled(textBox_BUILD_AaptPath, "Build_UseAapt");
BindEnabled(button_BUILD_BrowseAaptPath, "Build_UseAapt");
BindEnabled(textBox_BUILD_FrameDir, "Build_UseFramework");
BindEnabled(button_BUILD_BrowseFrameDir, "Build_UseFramework");
BindEnabled(textBox_BUILD_OutputAppPath, "Build_UseOutputAppPath");
BindEnabled(button_BUILD_BrowseOutputAppPath, "Build_UseOutputAppPath");
BindText(textBox_SIGN_InputFile, "Sign_InputFile");
BindText(textBox_SIGN_PublicKey, "Sign_PublicKey");
BindText(textBox_SIGN_PrivateKey, "Sign_PrivateKey");
BindChecked(useAliasChkBox, "Sign_SetAlias");
BindText(aliasTxtBox, "Sign_Alias");
BindChecked(useKeyStoreChkBox, "Sign_UseKeystoreFile");
BindText(keyStoreFileTxtBox, "Sign_KeystoreFilePath");
// textBox3 / textBox4 are PasswordBoxes (masked); synced to Settings in WireEvents
// (PasswordBox.Password is not a bindable DependencyProperty).
BindChecked(useSigningOutputDir, "Sign_UseOutputDir");
BindText(textBox_SIGN_OutputFile, "Sign_OutputDir");
BindChecked(autoDelIdsigChkBox, "AutoDeleteIdsigFile");
BindChecked(checkBox1, "Sign_OverwriteInputFile");
BindChecked(checkBox2, "Sign_InstallApkAfterSign");
BindText(textBox_ZIPALIGN_InputFile, "Zipalign_InputFile");
BindValue(numericUpDown_ZIPALIGN_AlignmentBytes, "Zipalign_AlignmentInBytes");
BindChecked(checkBox_ZIPALIGN_CheckAlignment, "Zipalign_CheckOnly");
BindChecked(checkBox_ZIPALIGN_VerboseOutput, "Zipalign_Verbose");
BindChecked(checkBox_ZIPALIGN_Recompress, "Zipalign_Recompress");
BindChecked(checkBox_ZIPALIGN_OverwriteOutputFile, "Zipalign_OverwriteOutputFile");
BindChecked(signAfterZipalignChkBox, "Zipalign_SignAfterZipAlign");
BindChecked(zipalignOutputDirChkBox, "Zipalign_UseOutputDir");
BindText(textBox_ZIPALIGN_OutputFile, "Zipalign_OutputDir");
BindChecked(checkBox_IF_FramePath, "Framework_UseFrameDir");
BindText(textBox_IF_FrameDir, "Framework_FrameDir");
BindChecked(checkBox_IF_Tag, "InstallFramework_UseTag");
BindText(textBox_IF_Tag, "InstallFramework_Tag");
BindText(textBox_IF_InputFramePath, "InstallFramework_InputFramePath");
BindChecked(clearFwBeforeDecodeChkBox, "Framework_ClearBeforeDecode");
BindEnabled(textBox_IF_FrameDir, "Framework_UseFrameDir");
BindEnabled(button_IF_BrowseFrameDir, "Framework_UseFrameDir");
BindEnabled(textBox_IF_Tag, "InstallFramework_UseTag");
BindChecked(baksmaliUseOutputChkBox, "Baksmali_UseOutputDir");
BindText(baksmaliBrowseOutputTxtBox, "Baksmali_OutputDir");
BindText(baksmaliBrowseInputDexTxtBox, "Baksmali_InputDexFile");
BindChecked(smaliUseOutputChkBox, "Smali_UseOutputDir");
BindText(smaliBrowseOutputTxtBox, "Smali_OutputDir");
BindText(smaliBrowseInputDirTxtBox, "Smali_InputDir");
BindChecked(setVendorChkBox, "Adb_SetVendor");
BindChecked(overrideAbiCheckBox, "Adb_SetOverrideAbi");
BindText(apkPathAdbTxtBox, "Adb_SelectedApkPath");
BindText(splitApkPathTxtBox, "SplitApk_InputFile");
}
private static void BindChecked(CheckBox c, string prop)
{
c.SetBinding(System.Windows.Controls.Primitives.ToggleButton.IsCheckedProperty,
new Binding(prop) { Source = Settings.Default, Mode = BindingMode.TwoWay });
}
private static void BindText(TextBox t, string prop)
{
t.SetBinding(TextBox.TextProperty,
new Binding(prop) { Source = Settings.Default, Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged });
}
private static void BindValue(NumericUpDown n, string prop)
{
n.SetBinding(NumericUpDown.ValueProperty,
new Binding(prop) { Source = Settings.Default, Mode = BindingMode.TwoWay });
}
private static void BindEnabled(Control c, string prop)
{
c.SetBinding(UIElement.IsEnabledProperty,
new Binding(prop) { Source = Settings.Default, Mode = BindingMode.OneWay });
}
#endregion
#region Event wiring
private void WireEvents()
{
// Decode
button_DECODE_BrowseFrameDir.Click += Button_DECODE_BrowseFrameDir_Click;
button_DECODE_BrowseOutputDirectory.Click += Button_DECODE_BrowseOutputDirectory_Click;
button_DECODE_BrowseInputAppPath.Click += Button_DECODE_BrowseInputAppPath_Click;
button_DECODE_Decode.Click += Button_DECODE_Decode_Click;
// Build
button_BUILD_BrowseAaptPath.Click += Button_BUILD_BrowseAaptPath_Click;
button_BUILD_BrowseFrameDir.Click += Button_BUILD_BrowseFrameDir_Click;
button_BUILD_BrowseOutputAppPath.Click += Button_BUILD_BrowseOutputAppPath_Click;
button_BUILD_BrowseInputProjectDir.Click += Button_BUILD_BrowseInputProjectDir_Click;
button_BUILD_Build.Click += Button_BUILD_Build_Click;
// Sign
button_SIGN_BrowsePublicKey.Click += Button_SIGN_BrowsePublicKey_Click;
button_SIGN_BrowsePrivateKey.Click += Button_SIGN_BrowsePrivateKey_Click;
button_SIGN_BrowseInputFile.Click += Button_SIGN_BrowseInputFile_Click;
button_SIGN_BrowseOutputFile.Click += Button_SIGN_BrowseOutputFile_Click;
selectKeyStoreFileBtn.Click += SelectKeyStoreFileBtn_Click;
button_SIGN_Sign.Click += Button_SIGN_Sign_Click;
schemev1ComboBox.SelectionChanged += SchemeComboBox_Changed;
schemev2ComboBox.SelectionChanged += SchemeComboBox_Changed;
schemev3ComboBox.SelectionChanged += SchemeComboBox_Changed;
schemev4ComboBox.SelectionChanged += SchemeComboBox_Changed;
// Masked password fields: PasswordBox.Password isn't bindable, so load + sync manually.
textBox3.Password = Settings.Default.Sign_KeystorePassword ?? "";
textBox4.Password = Settings.Default.Sign_KeyPassword ?? "";
textBox3.PasswordChanged += (s, e) => Settings.Default.Sign_KeystorePassword = textBox3.Password;
textBox4.PasswordChanged += (s, e) => Settings.Default.Sign_KeyPassword = textBox4.Password;
// Zipalign
checkBox_ZIPALIGN_CheckAlignment.Click += (s, e) => ApplyZipalignCheckSwitch();
button_ZIPALIGN_BrowseOutputFile.Click += Button_ZIPALIGN_BrowseOutputFile_Click;
button_ZIPALIGN_BrowseInputFile.Click += Button_ZIPALIGN_BrowseInputFile_Click;
button_ZIPALIGN_Align.Click += Button_ZIPALIGN_Align_Click;
// Framework
button_IF_BrowseFrameDir.Click += Button_IF_BrowseFrameDir_Click;
button_IF_BrowseInputFramePath.Click += Button_IF_BrowseInputFramePath_Click;
button_IF_InstallFramework.Click += Button_IF_InstallFramework_Click;
clearFwBtn.Click += ClearFwBtn_Click;
openFwFolderBtn.Click += OpenFwFolderBtn_Click;
// Baksmali / Smali
baksmaliBrowseOutputBtn.Click += BaksmaliBrowseOutputBtn_Click;
baksmaliBrowseInputDexBtn.Click += BaksmaliBrowseInputDexBtn_Click;
decSmaliBtn.Click += DecSmaliBtn_Click;
smaliBrowseOutputBtn.Click += SmaliBrowseOutputBtn_Click;
smaliBrowseInputDirBtn.Click += SmaliBrowseInputDirBtn_Click;
comSmaliBtn.Click += ComSmaliBtn_Click;
// ADB
killAdbBtn.Click += KillAdbBtn_Click;
installApkBtn.Click += InstallApkBtn_Click;
refreshDevicesBtn.Click += RefreshDevicesBtn_Click;
selApkAdbBtn.Click += SelApkAdbBtn_Click;
devicesListBox.SelectionChanged += DevicesListBox_SelectionChanged;
overrideAbiComboBox.SelectionChanged += OverrideAbiComboBox_Changed;
// APK info
selApkFileInfoBtn.Click += SelApkFileInfoBtn_Click;
apkIconPicBox.MouseLeftButtonUp += ApkIcon_Click;
psLinkBtn.Click += (s, e) => { if (aapt != null) Process.Start(aapt.PlayStoreLink); };
apkComboLinkBtn.Click += (s, e) => { if (aapt != null) Process.Start(aapt.ApkComboLink); };
apkPureLinkBtn.Click += (s, e) => { if (aapt != null) Process.Start(aapt.ApkPureLink); };
apkGkLinkBtn.Click += (s, e) => { if (aapt != null) Process.Start(aapt.ApkGkLink); };
apkSupportLinkBtn.Click += (s, e) => { if (aapt != null) Process.Start(aapt.ApkSupportLink); };
apkMirrorLinkBtn.Click += (s, e) => { if (aapt != null) Process.Start(aapt.ApkMirrorLink); };
// Main tab shortcut buttons
mergeApkBtn.Click += MergeApkBtn_Click;
selSplitApkBtn.Click += SelSplitApkBtn_Click;
openAndroidMainfestBtn.Click += OpenAndroidMainfestBtn_Click;
openApktoolYmlBtn.Click += OpenApktoolYmlBtn_Click;
compileOutputOpenDirBtn.Click += CompiledApkOpenDirBtn_Click;
button_OpenMainActivity.Click += Button_OpenMainActivity_Click;
decApkOpenDirBtn.Click += DecApkOpenDirBtn_Click;
decOutOpenDirBtn.Click += DecOutOpenDirBtn_Click;
comApkOpenDir.Click += ComApkOpenDir_Click;
signApkOpenDirBtn.Click += SignApkOpenDirBtn_Click;
alignApkOpenDirBtn.Click += AlignApkOpenDirBtn_Click;
// Menu extras
menuUseApkEditor.Click += (s, e) => Settings.Default.UseApkeditor = menuUseApkEditor.IsChecked;
// Cancel by clicking status text / progress bar
statusText.MouseLeftButtonUp += (s, e) => PromptCancel();
progressBar.MouseLeftButtonUp += (s, e) => PromptCancel();
WireDragDrop();
ApplyZipalignCheckSwitch();
}
#endregion
#region Window lifecycle
private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
_hwnd = new WindowInteropHelper(this).Handle;
try { new TaskBarJumpList(_hwnd); } catch (Exception ex) { Debug.WriteLine(ex); }
await Task.Run(() =>
{
InitializeUpdateChecker();
InitializeZipalign();
javaPath = JavaUtils.GetJavaPath();
if (javaPath != null)
{
InitializeBaksmali();
InitializeSmali();
InitializeAPKTool();
InitializeSignapk();
InitializeApkEditor();
string javaVersion = apktool.GetJavaVersion();
if (javaVersion != null)
{
ToLog(ApktoolEventType.None, javaVersion);
if (!String.IsNullOrWhiteSpace(apktool.Version) && !Regex.IsMatch(apktool.Version, @"\r\n?|\n"))
ToLog(ApktoolEventType.None, $"{Lang.APKToolVersion} {apktool.Version}");
else
ToLog(ApktoolEventType.Error, Lang.CantDetectApktoolVersion);
string apkeditorVersion = apkeditor.GetVersion();
if (!String.IsNullOrWhiteSpace(apkeditorVersion))
ToLog(ApktoolEventType.None, apkeditorVersion);
else
ToLog(ApktoolEventType.Error, Lang.CantDetectApkeditorVersion);
}
else
ToLog(ApktoolEventType.Error, Lang.ErrorJavaDetect);
}
else
{
ToLog(ApktoolEventType.Error, Lang.ErrorJavaDetect);
BeginInvokeOnUIThread(() =>
{
tabMain.IsEnabled = false;
tabBaksmali.IsEnabled = false;
tabFramework.IsEnabled = false;
});
}
InitializeAdb();
if (AdminUtils.IsAdministrator())
ToLog(ApktoolEventType.Warning, Lang.DragDropNotSupported);
else
ToLog(ApktoolEventType.None, Lang.DragDropSupported);
ToLog(ApktoolEventType.None, String.Format(Lang.TempDirectory, Program.TEMP_PATH));
TimeSpan updateInterval = DateTime.Now - Settings.Default.LastUpdateCheck;
if (updateInterval.Days > 0 && Settings.Default.CheckForUpdateAtStartup)
updateCheker.CheckAsync(true);
});
ToStatus(Lang.Done, Res.done);
RunCmdArgs();
await ListDevices();
}
private void MainWindow_Closing(object sender, CancelEventArgs e)
{
Save();
try { previousApkIcon?.Dispose(); previousApkIcon = null; } catch { }
try
{
adb?.Dispose(); zipalign?.Dispose(); apktool?.Dispose(); signapk?.Dispose();
baksmali?.Dispose(); smali?.Dispose(); apkeditor?.Dispose();
}
catch (Exception ex) { Debug.WriteLine(ex); }
DirectoryUtils.Delete(Program.TEMP_PATH);
}
private async void RunCmdArgs()
{
try
{
if (Environment.GetCommandLineArgs().Length == 3)
{
if (Settings.Default.IgnoreOutputDirContextMenu)
IgnoreOutputDirContextMenu = true;
string file = Environment.GetCommandLineArgs()[2];
switch (Environment.GetCommandLineArgs()[1])
{
case "decapk":
if (file.ContainsAny(".xapk", ".zip", ".apks", ".apkm")) { if (await MergeAndDecompile(file) == 0) Close(); }
else { if (await Decompile(file) == 0) Close(); }
break;
case "comapk": if (await Build(file) == 0) Close(); break;
case "sign": if (await Sign(file) == 0) Close(); break;
case "zipalign": if (await Align(file) == 0) Close(); break;
case "baksmali": if (await Baksmali(file) == 0) Close(); break;
case "smali": if (await Smali(file) == 0) Close(); break;
case "viewinfo": tabControlMain.SelectedIndex = 1; await GetApkInfo(file); break;
default: IgnoreOutputDirContextMenu = false; break;
}
}
}
catch (Exception ex) { ToLog(ApktoolEventType.Error, ex.Message); }
}
#endregion
#region Menu
private void NewInstance_Click(object sender, RoutedEventArgs e) => Process.Start(System.Reflection.Assembly.GetExecutingAssembly().Location);
private void SaveLog_Click(object sender, RoutedEventArgs e)
{
using (var sfd = new WinForms.SaveFileDialog())
{
sfd.FileName = "APK Tool GUI logs";
sfd.Filter = Lang.TextFile + " (*.txt)|*.txt";
if (sfd.ShowDialog() == WinForms.DialogResult.OK)
File.WriteAllText(sfd.FileName, GetLogText());
}
}
private void OpenTempFolder_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(Program.TEMP_PATH)) return;
if (!Directory.Exists(Program.TEMP_PATH)) Directory.CreateDirectory(Program.TEMP_PATH);
Process.Start("explorer.exe", Program.TEMP_PATH);
}
private async void ClearTempFolder_Click(object sender, RoutedEventArgs e)
{
Running(Lang.ClearTempFolder);
try
{
await Task.Run(() =>
{
foreach (var subDir in new DirectoryInfo(Program.TEMP_MAIN).EnumerateDirectories())
{
ToLog(ApktoolEventType.None, String.Format(Lang.DeletingFolder, subDir));
DirectoryUtils.Delete(subDir.FullName);
}
Directory.CreateDirectory(Program.TEMP_PATH);
});
Done();
}
catch (Exception ex) { Error(ex); }
}
private void Exit_Click(object sender, RoutedEventArgs e) => Close();
private void OpenSettings_Click(object sender, RoutedEventArgs e) => new SettingsWindow { Owner = this }.ShowDialog();
private void CheckUpdate_Click(object sender, RoutedEventArgs e) => updateCheker?.CheckAsync();
private void ReportIssue_Click(object sender, RoutedEventArgs e) => Process.Start("https://github.com/AndnixSH/APKToolGUI/issues/new/choose");
private void ApktoolIssues_Click(object sender, RoutedEventArgs e) => Process.Start("https://github.com/iBotPeaches/Apktool/issues?q=is%3Aissue");
private void BaksmaliIssues_Click(object sender, RoutedEventArgs e) => Process.Start("https://github.com/JesusFreke/smali/issues?q=is%3Aissue");
private void About_Click(object sender, RoutedEventArgs e) => new AboutWindow { Owner = this }.ShowDialog();
private string GetLogText()
{
FlushLogNow();
return logTxtBox.GetText();
}
private void LogCopy_Click(object sender, RoutedEventArgs e)
{
FlushLogNow();
logTxtBox.CopySelection();
}
private void LogCopyAll_Click(object sender, RoutedEventArgs e)
{
FlushLogNow();
logTxtBox.CopyAll();
}
private void LogClear_Click(object sender, RoutedEventArgs e)
{
ClearLogQueue();
logTxtBox.Clear();
}
#endregion
}
}
+134
View File
@@ -0,0 +1,134 @@
<Window x:Class="APKToolGUI.Forms.SettingsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Settings"
Width="580" Height="588"
MinWidth="520" MinHeight="420"
ResizeMode="CanResize" ShowInTaskbar="False"
WindowStartupLocation="CenterScreen"
UseLayoutRounding="True" TextOptions.TextFormattingMode="Display"
FontFamily="Segoe UI" FontSize="12"
Background="{DynamicResource WindowBackground}"
Foreground="{DynamicResource PrimaryText}">
<!-- WPF replacement for the former WinForms FormSettings. Shared dark/light styles
from Themes/Controls.xaml; colours applied via WpfTheme.Apply in code-behind.
Resizable: a DockPanel keeps OK/Cancel pinned to the bottom while the groups sit
in a ScrollViewer so the dialog never clips. -->
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Themes/Controls.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<DockPanel Margin="5" LastChildFill="True">
<!-- ===== OK / Cancel (pinned bottom) ===== -->
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal"
HorizontalAlignment="Right" Margin="0,14,0,0">
<Button x:Name="btnOK" MinWidth="88" Height="26" Margin="0,0,8,0" IsDefault="True" Click="OK_Click"/>
<Button x:Name="btnCancel" MinWidth="88" Height="26" IsCancel="True"/>
</StackPanel>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled"
Padding="0,0,6,0">
<StackPanel>
<!-- ===== General =====
col0 = Auto (checkbox / label), col1 = * (input, stretches and never
overflows), col2 = Auto (browse button). Inputs carry a 16px left
margin so labels never crowd the textbox. Nothing spans into col2,
which previously let a long single-line value inflate that column. -->
<GroupBox x:Name="groupGeneral" Header="General">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<CheckBox x:Name="chkCheckUpdate" Grid.Row="0" Grid.ColumnSpan="3" Margin="0,3"/>
<CheckBox x:Name="chkClearLog" Grid.Row="1" Grid.ColumnSpan="3" Margin="0,3"/>
<CheckBox x:Name="chkPlaySound" Grid.Row="2" Grid.ColumnSpan="3" Margin="0,3"/>
<CheckBox x:Name="chkCustomTemp" Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" Margin="0,3"/>
<TextBox x:Name="txtTempDir" Grid.Row="3" Grid.Column="1" Height="24" Margin="16,3,0,3"
VerticalContentAlignment="Center"/>
<Button x:Name="btnTempBrowse" Grid.Row="3" Grid.Column="2" Content="..." Width="32" Height="24"
Margin="6,3,0,3" Click="BrowseTemp_Click"/>
<CheckBox x:Name="chkCustomJava" Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" Margin="0,3"/>
<TextBox x:Name="txtJavaExe" Grid.Row="4" Grid.Column="1" Height="24" Margin="16,3,0,3"
VerticalContentAlignment="Center"/>
<Button x:Name="btnJavaBrowse" Grid.Row="4" Grid.Column="2" Content="..." Width="32" Height="24"
Margin="6,3,0,3" Click="BrowseJava_Click"/>
<CheckBox x:Name="chkCustomJvmArgs" Grid.Row="5" Grid.Column="0" VerticalAlignment="Center" Margin="0,3"/>
<TextBox x:Name="txtJvmArgs" Grid.Row="5" Grid.Column="1" Height="24" Margin="16,3,0,3"
VerticalContentAlignment="Center"/>
<CheckBox x:Name="chkUtf8" Grid.Row="6" Grid.ColumnSpan="3" Margin="0,3"/>
<TextBlock x:Name="lblTempNote" Grid.Row="7" Grid.ColumnSpan="3" Margin="0,3,0,6"
TextWrapping="Wrap" Foreground="{DynamicResource SecondaryText}"/>
<CheckBox x:Name="chkCustomApktool" Grid.Row="8" Grid.Column="0" VerticalAlignment="Center" Margin="0,3"/>
<TextBox x:Name="txtApktoolPath" Grid.Row="8" Grid.Column="1" Height="24" Margin="16,3,0,3"
VerticalContentAlignment="Center"/>
<Button x:Name="btnApktoolBrowse" Grid.Row="8" Grid.Column="2" Content="..." Width="32" Height="24"
Margin="6,3,0,3" Click="BrowseApktool_Click"/>
<Label x:Name="lblTheme" Grid.Row="9" Grid.Column="0" VerticalAlignment="Center" Padding="0" Margin="0,3"/>
<ComboBox x:Name="cboTheme" Grid.Row="9" Grid.Column="1" Margin="16,3,0,3" HorizontalAlignment="Left" Width="160"/>
<CheckBox x:Name="chkDebug" Grid.Row="10" Grid.ColumnSpan="3" Margin="0,3"/>
</Grid>
</GroupBox>
<!-- ===== Language ===== -->
<GroupBox x:Name="groupLanguage" Header="Language">
<ComboBox x:Name="cboLanguage" HorizontalAlignment="Left" Width="360" Margin="0,2"/>
</GroupBox>
<!-- ===== Context menu ===== -->
<GroupBox x:Name="groupContextMenu" Header="Context menu">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label x:Name="lblAdminRights" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Padding="0"/>
<Button x:Name="btnInstallCM" Grid.Row="0" Grid.Column="1" MinWidth="88" Height="26" Margin="6,0,0,0"
Click="InstallContextMenu_Click"/>
<Button x:Name="btnUninstallCM" Grid.Row="0" Grid.Column="2" MinWidth="88" Height="26" Margin="8,0,0,0"
Click="UninstallContextMenu_Click"/>
<CheckBox x:Name="chkIgnoreOutputCM" Grid.Row="1" Grid.ColumnSpan="3" Margin="0,14,0,0"/>
</Grid>
</GroupBox>
</StackPanel>
</ScrollViewer>
</DockPanel>
</Window>
+341
View File
@@ -0,0 +1,341 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using APKToolGUI.Controls;
using APKToolGUI.Properties;
using APKToolGUI.Utils;
using Ookii.Dialogs.WinForms;
using Lang = APKToolGUI.Languages.Language;
using WinForms = System.Windows.Forms;
namespace APKToolGUI.Forms
{
/// <summary>
/// WPF replacement for the former WinForms <c>FormSettings</c>. Behaviour is kept
/// identical: settings are loaded into the controls on open and written back on OK
/// (the old form used live two-way data bindings; a modal dialog makes load/save on
/// OK equivalent), the language list is discovered from embedded satellite resources,
/// and a restart is offered when the language or theme changes.
/// </summary>
public partial class SettingsWindow : Window
{
// Captured at load to detect changes that require a restart / apktool refresh.
private string currentCulture;
private int currentTheme;
private bool currentUseApktoolChk;
private string currentApktoolPath;
/// <summary>Language list entry: a display caption plus the stored culture value.</summary>
private sealed class LanguageItem
{
public string Display { get; }
public string Culture { get; } // "Auto", "" (English) or a culture name
public LanguageItem(string display, string culture) { Display = display; Culture = culture; }
public override string ToString() => Display;
}
public SettingsWindow()
{
InitializeComponent();
Theme theme = (Theme)Settings.Default.Theme;
WpfTheme.Apply(this, Program.IsDarkTheme());
NativeDarkMode.ApplyTheme(this, theme);
ApplyLocalizedText();
LoadFromSettings();
PopulateLanguages();
if (!AdminUtils.IsAdministrator())
{
SetShield(btnInstallCM);
SetShield(btnUninstallCM);
}
}
#region Localization
private void ApplyLocalizedText()
{
var rm = Lang.ResourceManager;
Title = Lang.Settings;
groupGeneral.Header = rm.GetString("SettingsGeneral");
groupLanguage.Header = rm.GetString("SettingsLanguage");
groupContextMenu.Header = rm.GetString("SettingsContextMenu");
chkCheckUpdate.Content = rm.GetString("SettingsCheckUpdate");
chkClearLog.Content = rm.GetString("SettingsClearLog");
chkPlaySound.Content = rm.GetString("SettingsPlaySound");
chkCustomTemp.Content = rm.GetString("SettingsCustomTemp");
chkCustomJava.Content = rm.GetString("SettingsCustomJava");
chkCustomJvmArgs.Content = rm.GetString("SettingsCustomJvmArgs");
chkUtf8.Content = rm.GetString("SettingsUtf8");
lblTempNote.Text = rm.GetString("SettingsTempNote");
chkCustomApktool.Content = rm.GetString("SettingsCustomApktool");
lblTheme.Content = rm.GetString("SettingsTheme");
chkDebug.Content = Lang.DebugMode;
chkIgnoreOutputCM.Content = rm.GetString("SettingsIgnoreOutputCM");
lblAdminRights.Content = rm.GetString("SettingsAdminRights");
btnInstallCM.Content = rm.GetString("SettingsInstall");
btnUninstallCM.Content = rm.GetString("SettingsUninstall");
btnOK.Content = rm.GetString("AboutOK");
btnCancel.Content = rm.GetString("SettingsCancel");
cboTheme.Items.Add(rm.GetString("ThemeAuto"));
cboTheme.Items.Add(rm.GetString("ThemeLight"));
cboTheme.Items.Add(rm.GetString("ThemeDark"));
}
#endregion
#region Load / Save
private void LoadFromSettings()
{
var s = Settings.Default;
chkClearLog.IsChecked = s.ClearLogBeforeAction;
chkPlaySound.IsChecked = s.PlaySoundWhenDone;
chkCheckUpdate.IsChecked = s.CheckForUpdateAtStartup;
chkCustomTemp.IsChecked = s.UseCustomTempDir;
txtTempDir.Text = s.TempDir;
chkCustomJava.IsChecked = s.UseCustomJavaExe;
txtJavaExe.Text = s.JavaExe;
chkCustomJvmArgs.IsChecked = s.UseCustomJVMArgs;
txtJvmArgs.Text = s.CustomJVMArgs;
chkUtf8.IsChecked = s.Utf8FilenameSupport;
chkDebug.IsChecked = s.DebugMode;
chkCustomApktool.IsChecked = s.UseCustomApktool;
txtApktoolPath.Text = s.ApktoolPath;
chkIgnoreOutputCM.IsChecked = s.IgnoreOutputDirContextMenu;
int t = s.Theme;
if (t < 0 || t >= cboTheme.Items.Count) t = 0;
cboTheme.SelectedIndex = t;
currentTheme = t;
currentUseApktoolChk = chkCustomApktool.IsChecked == true;
currentApktoolPath = txtApktoolPath.Text;
}
private void SaveToSettings()
{
try
{
var s = Settings.Default;
s.ClearLogBeforeAction = chkClearLog.IsChecked == true;
s.PlaySoundWhenDone = chkPlaySound.IsChecked == true;
s.CheckForUpdateAtStartup = chkCheckUpdate.IsChecked == true;
s.UseCustomTempDir = chkCustomTemp.IsChecked == true;
s.TempDir = txtTempDir.Text;
s.UseCustomJavaExe = chkCustomJava.IsChecked == true;
s.JavaExe = txtJavaExe.Text;
s.UseCustomJVMArgs = chkCustomJvmArgs.IsChecked == true;
s.CustomJVMArgs = txtJvmArgs.Text;
s.Utf8FilenameSupport = chkUtf8.IsChecked == true;
s.DebugMode = chkDebug.IsChecked == true;
s.UseCustomApktool = chkCustomApktool.IsChecked == true;
s.ApktoolPath = txtApktoolPath.Text;
s.IgnoreOutputDirContextMenu = chkIgnoreOutputCM.IsChecked == true;
string newCulture = (cboLanguage.SelectedItem as LanguageItem)?.Culture ?? currentCulture;
s.Culture = newCulture;
s.Theme = cboTheme.SelectedIndex;
s.Save();
bool languageChanged = newCulture != currentCulture;
bool themeChanged = cboTheme.SelectedIndex != currentTheme;
if (languageChanged || themeChanged)
{
if (WinForms.MessageBox.Show(Lang.RestartApplicationPrompt, WinForms.Application.ProductName,
WinForms.MessageBoxButtons.YesNo, WinForms.MessageBoxIcon.Question) == WinForms.DialogResult.Yes)
{
// This is a WPF app (no WinForms message loop), so WinForms.Application.Restart()
// would start a new instance but never shut this one down. Do it explicitly.
Process.Start(WinForms.Application.ExecutablePath);
System.Windows.Application.Current.Shutdown();
return;
}
}
if (currentUseApktoolChk != (chkCustomApktool.IsChecked == true) || currentApktoolPath != txtApktoolPath.Text)
MainWindow.Instance?.SetApktoolPath();
}
catch (Exception ex)
{
Log.e(ex.ToString());
}
}
#endregion
#region Language list
private void PopulateLanguages()
{
string sysLang = Lang.SystemLanguage;
string culture = Settings.Default.Culture;
currentCulture = culture;
cboLanguage.Items.Add(new LanguageItem(sysLang, "Auto"));
cboLanguage.Items.Add(new LanguageItem(CultureInfo.GetCultureInfo("en").NativeName, ""));
// Discover the languages we ship by scanning the embedded satellite resources
// (e.g. "APKToolGUI.de.resources.dll" -> "de").
foreach (string resourceName in Assembly.GetExecutingAssembly().GetManifestResourceNames())
{
if (!resourceName.EndsWith(".resources.dll", StringComparison.OrdinalIgnoreCase))
continue;
string[] parts = resourceName.Split('.');
if (parts.Length < 2) continue;
try
{
CultureInfo c = CultureInfo.GetCultureInfo(parts[1]);
cboLanguage.Items.Add(new LanguageItem($"{c.DisplayName} [{c.Name}]", c.Name));
}
catch (CultureNotFoundException) { }
}
// Select the entry matching the stored culture.
int select = 1; // default: English
if (culture == "Auto")
select = 0;
else if (!string.IsNullOrEmpty(culture))
{
for (int i = 0; i < cboLanguage.Items.Count; i++)
if (((LanguageItem)cboLanguage.Items[i]).Culture == culture) { select = i; break; }
}
cboLanguage.SelectedIndex = select;
}
#endregion
#region Buttons / pickers
private void OK_Click(object sender, RoutedEventArgs e)
{
SaveToSettings();
Close();
}
private void BrowseJava_Click(object sender, RoutedEventArgs e)
{
using (var ofd = new WinForms.OpenFileDialog())
{
ofd.Filter = string.Format(Lang.FilterJavaExe, "java.exe");
if (ofd.ShowDialog() == WinForms.DialogResult.OK)
txtJavaExe.Text = Program.GetPortablePath(ofd.FileName);
}
}
private void BrowseTemp_Click(object sender, RoutedEventArgs e)
{
using (var fbd = new VistaFolderBrowserDialog())
{
if (!string.IsNullOrWhiteSpace(txtTempDir.Text))
fbd.SelectedPath = txtTempDir.Text;
if (fbd.ShowDialog() == WinForms.DialogResult.OK)
{
txtTempDir.Text = fbd.SelectedPath;
// Move the working temp folder to the new location, as the old form did.
DirectoryUtils.Delete(Program.TEMP_PATH);
Program.TEMP_PATH = Program.RandTempDirectory();
Directory.CreateDirectory(Program.TEMP_PATH);
}
}
}
private void BrowseApktool_Click(object sender, RoutedEventArgs e)
{
using (var ofd = new WinForms.OpenFileDialog())
{
ofd.Filter = string.Format(Lang.FilterApktool, "*.jar");
if (ofd.ShowDialog() == WinForms.DialogResult.OK)
txtApktoolPath.Text = ofd.FileName;
}
}
private void InstallContextMenu_Click(object sender, RoutedEventArgs e)
{
if (WinForms.MessageBox.Show(Lang.DoYouRealyWantToInstallCM, WinForms.Application.ProductName,
WinForms.MessageBoxButtons.YesNo, WinForms.MessageBoxIcon.Question) == WinForms.DialogResult.Yes)
RunAsAdmin(WinForms.Application.ExecutablePath, "ccm");
}
private void UninstallContextMenu_Click(object sender, RoutedEventArgs e)
{
if (WinForms.MessageBox.Show(Lang.DoYouRealyWantToRemoveCM, WinForms.Application.ProductName,
WinForms.MessageBoxButtons.YesNo, WinForms.MessageBoxIcon.Question) == WinForms.DialogResult.Yes)
RunAsAdmin(WinForms.Application.ExecutablePath, "rcm");
}
private static void RunAsAdmin(string fileName, string arguments)
{
var psi = new ProcessStartInfo
{
FileName = fileName,
Arguments = arguments,
UseShellExecute = true,
Verb = "runas"
};
try
{
Process.Start(psi);
}
catch (Exception ex)
{
WinForms.MessageBox.Show(ex.Message, WinForms.Application.ProductName,
WinForms.MessageBoxButtons.OK, WinForms.MessageBoxIcon.Error);
}
}
/// <summary>
/// WPF equivalent of the old BCM_SETSHIELD: prepends the UAC shield icon to a
/// button's caption to signal the action needs elevation.
/// </summary>
private void SetShield(Button btn)
{
try
{
var source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
System.Drawing.SystemIcons.Shield.Handle,
Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromWidthAndHeight(16, 16));
var panel = new StackPanel { Orientation = Orientation.Horizontal };
panel.Children.Add(new Image
{
Source = source,
Width = 16,
Height = 16,
Margin = new Thickness(0, 0, 6, 0),
VerticalAlignment = VerticalAlignment.Center
});
panel.Children.Add(new TextBlock
{
Text = btn.Content as string,
VerticalAlignment = VerticalAlignment.Center
});
btn.Content = panel;
}
catch
{
// Shield is cosmetic; ignore if the icon can't be created.
}
}
#endregion
}
}
@@ -1,74 +0,0 @@
using APKToolGUI.Languages;
using APKToolGUI.Properties;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace APKToolGUI.Handlers
{
internal class AdbControlEventHandlers
{
private static FormMain main;
public AdbControlEventHandlers(FormMain Main)
{
main = Main;
main.killAdbBtn.Click += KillAdbBtn_Click;
main.installApkBtn.Click += InstallApkBtn_Click;
main.refreshDevicesBtn.Click += RefreshDevicesBtn_Click;
main.selApkAdbBtn.Click += SelApkAdbBtn_Click;
main.devicesListBox.SelectedValueChanged += DevicesListBox_SelectedValueChanged;
main.overrideAbiComboBox.SelectedIndexChanged += OverrideAbiComboBox_SelectedIndexChanged;
}
private void OverrideAbiComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
Settings.Default.Adb_OverrideAbi = main.overrideAbiComboBox.SelectedIndex;
}
private async void RefreshDevicesBtn_Click(object sender, EventArgs e)
{
await main.ListDevices();
}
private async void KillAdbBtn_Click(object sender, EventArgs e)
{
if (MessageBox.Show(Language.ConfirmKillingAdbServer, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
main.adb.KillProcess();
await main.ListDevices();
}
}
private async void InstallApkBtn_Click(object sender, EventArgs e)
{
string inputFile = main.apkPathAdbTxtBox.Text;
if (File.Exists(inputFile))
{
await main.Install(inputFile);
}
else
MessageBox.Show(Language.ErrorSelectedFileNotExist, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
private void SelApkAdbBtn_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog())
{
if (ofd.ShowDialog() == DialogResult.OK)
{
main.apkPathAdbTxtBox.Text = ofd.FileName;
}
}
}
private void DevicesListBox_SelectedValueChanged(object sender, EventArgs e)
{
main.ToLog(ApktoolEventType.None, String.Format(Language.DeviceSelected, main.devicesListBox.SelectedItem));
main.selAdbDeviceLbl.Text = main.devicesListBox.GetItemText(main.devicesListBox.SelectedItem);
}
}
}
@@ -1,73 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace APKToolGUI.Handlers
{
internal class ApkinfoControlEventHandlers
{
private static FormMain main;
public ApkinfoControlEventHandlers(FormMain Main)
{
main = Main;
main.selApkFileInfoBtn.Click += SelApkFileInfoBtn_Click;
main.psLinkBtn.Click += PsLinkBtn_Click;
main.apkComboLinkBtn.Click += ApkComboLinkBtn_Click;
main.apkPureLinkBtn.Click += ApkPureLinkBtn_Click;
main.apkGkLinkBtn.Click += ApkGkLinkBtn_Click;
main.apkSupportLinkBtn.Click += ApkSupportLinkBtn_Click;
main.apkMirrorLinkBtn.Click += ApkMirrorLinkBtn_Click;
}
private async void SelApkFileInfoBtn_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog())
{
if (ofd.ShowDialog() == DialogResult.OK)
{
await main.GetApkInfo(ofd.FileName);
}
}
}
private void PsLinkBtn_Click(object sender, EventArgs e)
{
if (main.aapt != null)
Process.Start(main.aapt.PlayStoreLink);
}
private void ApkComboLinkBtn_Click(object sender, EventArgs e)
{
if (main.aapt != null)
Process.Start(main.aapt.ApkComboLink);
}
private void ApkPureLinkBtn_Click(object sender, EventArgs e)
{
if (main.aapt != null)
Process.Start(main.aapt.ApkPureLink);
}
private void ApkGkLinkBtn_Click(object sender, EventArgs e)
{
if (main.aapt != null)
Process.Start(main.aapt.ApkGkLink);
}
private void ApkSupportLinkBtn_Click(object sender, EventArgs e)
{
if (main.aapt != null)
Process.Start(main.aapt.ApkSupportLink);
}
private void ApkMirrorLinkBtn_Click(object sender, EventArgs e)
{
if (main.aapt != null)
Process.Start(main.aapt.ApkMirrorLink);
}
}
}
@@ -1,69 +0,0 @@
using APKToolGUI.Languages;
using APKToolGUI.Properties;
using APKToolGUI.Utils;
using Ookii.Dialogs.WinForms;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace APKToolGUI.Handlers
{
class BaksmaliControlEventHandlers
{
private static FormMain main;
public BaksmaliControlEventHandlers(FormMain Main)
{
main = Main;
main.baksmaliBrowseOutputBtn.Click += BaksmaliBrowseOutputBtn_Click;
main.baksmaliBrowseInputDexBtn.Click += BaksmaliBrowseInputDexBtn_Click;
main.decSmaliBtn.Click += DecSmaliBtn_Click;
}
internal void BaksmaliBrowseOutputBtn_Click(object sender, EventArgs e)
{
VistaFolderBrowserDialog dlg = new VistaFolderBrowserDialog();
dlg.ShowNewFolderButton = true;
if (dlg.ShowDialog() == DialogResult.OK)
{
main.baksmaliBrowseOutputTxtBox.Text = dlg.SelectedPath;
}
}
internal void BaksmaliBrowseInputDexBtn_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "dex|*.dex";
if (ofd.ShowDialog() == DialogResult.OK)
main.baksmaliBrowseInputDexTxtBox.Text = ofd.FileName;
}
}
internal async void DecSmaliBtn_Click(object sender, EventArgs e)
{
if (main.baksmaliUseOutputChkBox.Checked)
{
if (String.IsNullOrWhiteSpace(main.baksmaliBrowseOutputTxtBox.Text) || !Directory.Exists(main.baksmaliBrowseOutputTxtBox.Text))
{
main.ShowMessage(Language.ErrorSelectedOutputFolderNotExist, MessageBoxIcon.Warning);
return;
}
}
if (!File.Exists(main.baksmaliBrowseInputDexTxtBox.Text))
{
main.ShowMessage(Language.ErrorSelectedFileNotExist, MessageBoxIcon.Warning);
return;
}
await main.Baksmali(Settings.Default.Baksmali_InputDexFile);
}
}
}
@@ -1,90 +0,0 @@
using APKToolGUI.Languages;
using APKToolGUI.Properties;
using APKToolGUI.Utils;
using Ookii.Dialogs.WinForms;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace APKToolGUI.Handlers
{
class BuildControlEventHandlers
{
private static FormMain main;
public BuildControlEventHandlers(FormMain Main)
{
main = Main;
main.button_BUILD_BrowseAaptPath.Click += Button_BUILD_BrowseAaptPath_Click;
main.button_BUILD_BrowseFrameDir.Click += Button_BUILD_BrowseFrameDir_Click;
main.button_BUILD_BrowseOutputAppPath.Click += Button_BUILD_BrowseOutputAppPath_Click;
main.button_BUILD_BrowseInputProjectDir.Click += Button_BUILD_BrowseInputProjectDir_Click;
main.button_BUILD_Build.Click += Button_BUILD_Build_Click;
}
internal void Button_BUILD_BrowseAaptPath_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = Language.ExecutableFile + "|*.exe";
if (!String.IsNullOrWhiteSpace(main.textBox_BUILD_AaptPath.Text))
{
ofd.InitialDirectory = Path.GetDirectoryName(main.textBox_BUILD_AaptPath.Text);
ofd.FileName = Path.GetFileName(main.textBox_BUILD_AaptPath.Text);
}
if (ofd.ShowDialog() == DialogResult.OK)
main.textBox_BUILD_AaptPath.Text = ofd.FileName;
}
}
internal void Button_BUILD_BrowseFrameDir_Click(object sender, EventArgs e)
{
using (VistaFolderBrowserDialog fbd = new VistaFolderBrowserDialog())
{
if (!String.IsNullOrWhiteSpace(main.textBox_BUILD_FrameDir.Text))
fbd.SelectedPath = main.textBox_BUILD_FrameDir.Text;
if (fbd.ShowDialog() == DialogResult.OK)
main.textBox_BUILD_FrameDir.Text = fbd.SelectedPath;
}
}
internal void Button_BUILD_BrowseOutputAppPath_Click(object sender, EventArgs e)
{
VistaFolderBrowserDialog dlg = new VistaFolderBrowserDialog();
dlg.ShowNewFolderButton = true;
if (dlg.ShowDialog() == DialogResult.OK)
{
main.textBox_BUILD_OutputAppPath.Text = dlg.SelectedPath;
}
}
internal void Button_BUILD_BrowseInputProjectDir_Click(object sender, EventArgs e)
{
VistaFolderBrowserDialog dlg = new VistaFolderBrowserDialog();
dlg.ShowNewFolderButton = true;
if (dlg.ShowDialog() == DialogResult.OK)
{
main.textBox_BUILD_InputProjectDir.Text = dlg.SelectedPath;
}
}
internal async void Button_BUILD_Build_Click(object sender, EventArgs e)
{
string decApkDir = main.textBox_BUILD_InputProjectDir.Text;
if (Directory.Exists(main.textBox_BUILD_InputProjectDir.Text))
{
await main.Build(decApkDir);
}
else
MessageBox.Show(Language.WarningDecodingFolderNotSelected, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
@@ -1,110 +0,0 @@
using APKToolGUI.Languages;
using APKToolGUI.Properties;
using APKToolGUI.Utils;
using Ookii.Dialogs.WinForms;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace APKToolGUI.Handlers
{
class DecodeControlEventHandlers
{
private static FormMain main;
public DecodeControlEventHandlers(FormMain Main)
{
main = Main;
main.button_DECODE_BrowseFrameDir.Click += Button_DECODE_BrowseFrameDir_Click;
main.button_DECODE_BrowseOutputDirectory.Click += Button_DECODE_BrowseOutputDirectory_Click;
main.button_DECODE_BrowseInputAppPath.Click += Button_DECODE_BrowseInputAppPath_Click;
main.button_DECODE_Decode.Click += Button_DECODE_Decode_Click;
}
internal void Button_DECODE_BrowseFrameDir_Click(object sender, EventArgs e)
{
using (VistaFolderBrowserDialog fbd = new VistaFolderBrowserDialog())
{
if (!String.IsNullOrWhiteSpace(main.textBox_DECODE_FrameDir.Text))
fbd.SelectedPath = main.textBox_DECODE_FrameDir.Text;
if (fbd.ShowDialog() == DialogResult.OK)
main.textBox_DECODE_FrameDir.Text = fbd.SelectedPath;
}
}
internal void Button_DECODE_BrowseOutputDirectory_Click(object sender, EventArgs e)
{
using (VistaFolderBrowserDialog fbd = new VistaFolderBrowserDialog())
{
if (!String.IsNullOrWhiteSpace(main.textBox_DECODE_OutputDirectory.Text))
fbd.SelectedPath = main.textBox_DECODE_OutputDirectory.Text;
else
if (!String.IsNullOrWhiteSpace(main.textBox_DECODE_InputAppPath.Text))
fbd.SelectedPath = Path.GetDirectoryName(main.textBox_DECODE_InputAppPath.Text);
if (fbd.ShowDialog() == DialogResult.OK)
main.textBox_DECODE_OutputDirectory.Text = fbd.SelectedPath;
}
}
internal async void Button_DECODE_BrowseInputAppPath_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "Android Package (*.apk;*.xapk;*.zip;*.apkm;*.apks)|*.apk;*.xapk;*.zip;*.apkm;*.apks";
if (ofd.ShowDialog() == DialogResult.OK)
{
main.textBox_DECODE_InputAppPath.Text = ofd.FileName;
if (!Settings.Default.Decode_DontParseApkInfo)
await main.GetApkInfo(ofd.FileName);
if (main.checkBox_DECODE_OutputDirectory.Checked)
{
main.textBox_DECODE_OutputDirectory.Text = Path.Combine(Path.GetDirectoryName(main.textBox_DECODE_InputAppPath.Text), Path.GetFileNameWithoutExtension(main.textBox_DECODE_InputAppPath.Text));
}
}
}
}
internal async void Button_DECODE_Decode_Click(object sender, EventArgs e)
{
string inputFile = main.textBox_DECODE_InputAppPath.Text;
if (File.Exists(inputFile))
{
if (main.checkBox_DECODE_UseFramework.Checked && !Directory.Exists(main.textBox_DECODE_FrameDir.Text))
{
main.ShowMessage(Language.DecodeSelectedFrameworkNotExist, MessageBoxIcon.Warning);
return;
}
if (main.checkBox_DECODE_OutputDirectory.Checked)
{
if (String.IsNullOrWhiteSpace(Settings.Default.Decode_OutputDir))
{
main.ShowMessage(Language.DecodeDirNotSelected, MessageBoxIcon.Warning);
return;
}
else
if (!PathUtils.IsValidPath(Settings.Default.Decode_OutputDir))
{
main.ShowMessage(Language.DecodeCouldNotCreate, MessageBoxIcon.Warning);
return;
}
}
if (inputFile.ContainsAny(".xapk", ".zip", ".apks", ".apkm"))
{
await main.MergeAndDecompile(inputFile);
}
else
await main.Decompile(inputFile);
}
else
MessageBox.Show(Language.WarningFileForDecodingNotSelected, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
-231
View File
@@ -1,231 +0,0 @@
using APKToolGUI.ApkTool;
using APKToolGUI.Controls;
using APKToolGUI.Languages;
using APKToolGUI.Properties;
using APKToolGUI.Utils;
using SaveToGameWpf.Logic.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace APKToolGUI.Handlers
{
class DragDropHandlers
{
private static FormMain main;
string[] apks = { ".apk", ".xapk", ".zip", ".apks", ".apkm" };
string[] apk = { ".apk" };
public DragDropHandlers(FormMain Main)
{
main = Main;
//Decode
DragEventHandler decEventHandler = new DragEventHandler((sender, e) => { DropApkToDec(e); });
Register(main.decPanel, null, decEventHandler, apks);
Register(main.textBox_DECODE_InputAppPath, main.decPanel, decEventHandler, apks);
Register(main.button_DECODE_Decode, main.decPanel, decEventHandler, apks);
DragEventHandler comEventHandler = new DragEventHandler((sender, e) => { DropDirToCom(e); });
Register(main.comPanel, null, comEventHandler, null);
Register(main.textBox_BUILD_InputProjectDir, main.comPanel, comEventHandler, null);
Register(main.button_BUILD_Build, main.comPanel, comEventHandler, null);
DragEventHandler alignEventHandler = new DragEventHandler((sender, e) => { DropApkToAlign(e); });
Register(main.zipalignPanel, null, alignEventHandler, apk);
Register(main.textBox_ZIPALIGN_InputFile, main.zipalignPanel, alignEventHandler, apk);
Register(main.button_ZIPALIGN_Align, main.zipalignPanel, alignEventHandler, apk);
DragEventHandler signEventHandler = new DragEventHandler((sender, e) => { DropApkToSign(e); });
Register(main.signPanel, null, signEventHandler, apk);
Register(main.textBox_SIGN_InputFile, main.signPanel, signEventHandler, apk);
Register(main.button_SIGN_Sign, main.signPanel, signEventHandler, apk);
DragEventHandler mergeEventHandler = new DragEventHandler((sender, e) => { DropApkToMerge(e); });
Register(main.mergePanel, null, mergeEventHandler, apks);
Register(main.splitApkPathTxtBox, main.mergePanel, mergeEventHandler, apks);
Register(main.mergeApkBtn, main.mergePanel, mergeEventHandler, apks);
DragEventHandler baksmaliEventHandler = new DragEventHandler((sender, e) => { DropDexToBaksmali(e); });
Register(main.bakSmaliGroupBox, null, baksmaliEventHandler, new string[] { ".dex" });
main.bakSmaliGroupBox.AllowDrop = true;
DragEventHandler smaliEventHandler = new DragEventHandler((sender, e) => { DropDirToSmali(e); });
Register(main.smaliGroupBox, null, smaliEventHandler, null);
main.smaliGroupBox.AllowDrop = true;
DragEventHandler apkInfoEventHandler = new DragEventHandler((sender, e) => { DropApkToGetInfo(e); });
Register(main.basicInfoTabPage, null, apkInfoEventHandler, apks);
Register(main.fileTxtBox, null, apkInfoEventHandler, apks);
DragEventHandler adbEventHandler = new DragEventHandler((sender, e) => { DropApkToInstall(e); });
Register(main.tabPageAdb, null, adbEventHandler, apk);
Register(main.installApkBtn, null, adbEventHandler, apk);
}
void Register(Control ctrl, Control extCtrl, DragEventHandler dragHandler, string[] extension)
{
if (extCtrl == null)
extCtrl = ctrl;
ctrl.DragLeave += new EventHandler((sender, e) => extCtrl.BackColor = PanelBackColor());
ctrl.DragEnter += new DragEventHandler((sender, e) => e.CheckDragEnter(extension));
ctrl.DragOver += new DragEventHandler((sender, e) => { if (e.CheckManyDragOver(extension)) extCtrl.BackColor = PanelHoverBackColor(); });
ctrl.DragDrop += dragHandler;
}
private async void DropApkToDec(DragEventArgs e)
{
string[] apkFiles = null;
if (e.DropManyByEnd(file => apkFiles = file, apks))
{
main.decPanel.BackColor = PanelBackColor();
foreach (var apkFile in apkFiles)
{
main.textBox_DECODE_InputAppPath.Text = apkFile;
if (!Settings.Default.Decode_DontParseApkInfo)
await main.GetApkInfo(apkFile);
if (apkFile.ContainsAny(".xapk", ".zip", ".apks", ".apkm"))
{
await main.MergeAndDecompile(apkFile);
}
else
await main.Decompile(apkFile);
}
}
}
private async void DropDirToCom(DragEventArgs e)
{
string[] folders = null;
if (e.DropManyByEnd(file => folders = file, ""))
{
foreach (var folder in folders)
{
if (File.Exists(Path.Combine(folder, "AndroidManifest.xml")))
{
main.textBox_BUILD_InputProjectDir.Text = folder;
main.comPanel.BackColor = PanelBackColor();
await main.Build(folder);
}
else
main.ToLog(ApktoolEventType.Error, Language.ErrorNotAnApk);
}
}
}
private async void DropApkToAlign(DragEventArgs e)
{
string[] apkFiles = null;
if (e.DropManyByEnd(file => apkFiles = file, apks))
{
main.zipalignPanel.BackColor = PanelBackColor();
foreach (var apkFile in apkFiles)
{
main.textBox_ZIPALIGN_InputFile.Text = apkFile;
await main.Align(apkFile);
}
}
}
private async void DropApkToSign(DragEventArgs e)
{
string[] apkFiles = null;
if (e.DropManyByEnd(file => apkFiles = file, apks))
{
main.signPanel.BackColor = PanelBackColor();
foreach (var apkFile in apkFiles)
{
main.textBox_SIGN_InputFile.Text = apkFile;
await main.Sign(apkFile);
}
}
}
private async void DropApkToMerge(DragEventArgs e)
{
string[] apkFiles = null;
if (e.DropManyByEnd(file => apkFiles = file, apks))
{
main.mergePanel.BackColor = PanelBackColor();
foreach (var apkFile in apkFiles)
{
main.splitApkPathTxtBox.Text = apkFile;
await main.Merge(apkFile);
}
}
}
private async void DropDexToBaksmali(DragEventArgs e)
{
string apkFile = null;
if (e.DropOneByEnd(file => apkFile = file, ".dex"))
{
main.baksmaliBrowseInputDexTxtBox.Text = apkFile;
main.bakSmaliGroupBox.BackColor = PanelBackColor();
await main.Baksmali(apkFile);
}
}
private async void DropDirToSmali(DragEventArgs e)
{
string dir = null;
if (e.DropOneByEnd(file => dir = file, null))
{
main.smaliBrowseInputDirTxtBox.Text = dir;
main.smaliGroupBox.BackColor = PanelBackColor();
await main.Smali(dir);
}
}
private async void DropApkToInstall(DragEventArgs e)
{
string dir = null;
if (e.DropOneByEnd(file => dir = file, ".apk"))
{
main.apkPathAdbTxtBox.Text = dir;
main.tabPageAdb.BackColor = PanelBackColor();
await main.Install(dir);
}
}
private async void DropApkToGetInfo(DragEventArgs e)
{
string apkFile = null;
if (e.DropOneByEnd(file => apkFile = file, apks))
{
main.fileTxtBox.Text = apkFile;
main.basicInfoTabPage.BackColor = PanelBackColor();
await main.GetApkInfo(apkFile);
}
}
Color PanelBackColor()
{
if (Program.IsDarkTheme())
return DarkTheme.bgColor;
return Color.White;
}
Color PanelHoverBackColor()
{
if (Program.IsDarkTheme())
return Color.Gray;
return Color.LightGreen;
}
}
}
@@ -1,109 +0,0 @@
using APKToolGUI.Languages;
using APKToolGUI.Properties;
using APKToolGUI.Utils;
using Ookii.Dialogs.WinForms;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace APKToolGUI.Handlers
{
class FrameworkControlEventHandlers
{
private static FormMain main;
public FrameworkControlEventHandlers(FormMain Main)
{
main = Main;
main.button_IF_BrowseFrameDir.Click += Button_IF_BrowseFrameDir_Click;
main.button_IF_BrowseInputFramePath.Click += Button_IF_BrowseInputFramePath_Click;
main.button_IF_InstallFramework.Click += Button_IF_InstallFramework_Click;
main.clearFwBtn.Click += ClearFwBtn_Click;
main.openFwFolderBtn.Click += OpenFwFolderBtn_Click;
}
internal void Button_IF_BrowseFrameDir_Click(object sender, EventArgs e)
{
main.clearFwBeforeDecodeChkBox.Checked = false;
VistaFolderBrowserDialog dlg = new VistaFolderBrowserDialog();
dlg.ShowNewFolderButton = true;
if (dlg.ShowDialog() == DialogResult.OK)
{
main.textBox_IF_FrameDir.Text = dlg.SelectedPath;
}
}
internal void Button_IF_BrowseInputFramePath_Click(object sender, EventArgs e)
{
main.clearFwBeforeDecodeChkBox.Checked = false;
using (OpenFileDialog ofd = new OpenFileDialog())
{
if (File.Exists(main.textBox_IF_InputFramePath.Text))
{
ofd.InitialDirectory = Path.GetDirectoryName(main.textBox_IF_InputFramePath.Text);
ofd.FileName = Path.GetFileNameWithoutExtension(main.textBox_IF_InputFramePath.Text);
}
ofd.Filter = "apk|*.apk";
if (ofd.ShowDialog() == DialogResult.OK)
main.textBox_IF_InputFramePath.Text = ofd.FileName;
}
}
internal async void Button_IF_InstallFramework_Click(object sender, EventArgs e)
{
if (main.checkBox_IF_FramePath.Checked)
{
if (String.IsNullOrWhiteSpace(main.textBox_IF_FrameDir.Text) || !Directory.Exists(main.textBox_IF_FrameDir.Text))
{
main.ShowMessage(Language.ErrorSelectingFrameworkDirectory, MessageBoxIcon.Warning);
return;
}
}
if (main.checkBox_IF_Tag.Checked && String.IsNullOrWhiteSpace(main.textBox_IF_Tag.Text))
{
main.ShowMessage(Language.ErrorEnteringFrameworkTag, MessageBoxIcon.Warning);
return;
}
if (!File.Exists(main.textBox_IF_InputFramePath.Text))
{
main.ShowMessage(Language.ErrorSelectingFrameworkFile, MessageBoxIcon.Warning);
return;
}
main.Running(Language.InstallingFramework);
main.ToLog(ApktoolEventType.None, Language.InstallingFramework + " " + Path.GetFileName(main.textBox_IF_InputFramePath.Text));
await Task.Factory.StartNew(() =>
{
if (main.apktool.InstallFramework() == 0)
main.Done(Language.FrameworkInstalled);
else
main.Error(Language.FrameworkInstallationNotStarted);
});
}
internal async void ClearFwBtn_Click(object sender, EventArgs e)
{
main.Running(Language.ClearingFramework);
await main.ClearFramework();
}
internal void OpenFwFolderBtn_Click(object sender, EventArgs e)
{
if (main.checkBox_IF_FramePath.Checked && Directory.Exists(main.textBox_IF_FrameDir.Text))
Process.Start("explorer.exe", main.textBox_IF_FrameDir.Text);
else if (Directory.Exists(Program.FRAMEWORK_DIR))
Process.Start("explorer.exe", Program.FRAMEWORK_DIR);
else
main.ToLog(ApktoolEventType.Error, Language.ErrorSelectedFolderNotExist);
}
}
}
@@ -1,238 +0,0 @@
using APKToolGUI.Languages;
using APKToolGUI.Properties;
using APKToolGUI.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
namespace APKToolGUI.Handlers
{
internal class MainWindowEventHandlers
{
private static FormMain main;
public MainWindowEventHandlers(FormMain Main)
{
main = Main;
main.clearLogToolStripMenuItem.Click += ClearLogToolStripMenuItem_Click;
main.copyToolStripMenuItem.Click += CopyToolStripMenuItem_Click;
main.openAndroidMainfestBtn.Click += OpenAndroidMainfestBtn_Click;
main.openApktoolYmlBtn.Click += OpenApktoolYmlBtn_Click;
main.compileOutputOpenDirBtn.Click += CompiledApkOpenDirBtn_Click;
main.button_OpenMainActivity.Click += Button_OpenMainActivity_Click;
main.decApkOpenDirBtn.Click += DecApkOpenDirBtn_Click;
main.decOutOpenDirBtn.Click += DecOutOpenDirBtn_Click;
main.comApkOpenDir.Click += ComApkOpenDir_Click;
main.signApkOpenDirBtn.Click += SignApkOpenDirBtn_Click;
main.alignApkOpenDirBtn.Click += AlignApkOpenDirBtn_Click;
main.mergeApkBtn.Click += MergeApkBtn_Click;
main.selSplitApkBtn.Click += SelSplitApkBtn_Click;
}
internal void SelSplitApkBtn_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "Split APK Package (*.xapk;*.zip;*.apkm;*.apks)|*.xapk;*.zip;*.apkm;*.apks";
if (ofd.ShowDialog() == DialogResult.OK)
{
main.splitApkPathTxtBox.Text = ofd.FileName;
}
}
}
internal async void MergeApkBtn_Click(object sender, EventArgs e)
{
try
{
main.Save();
if (!File.Exists(Settings.Default.SplitApk_InputFile))
{
main.ShowMessage(Language.SplitApkNotFound, MessageBoxIcon.Warning);
return;
}
await main.Merge(Settings.Default.SplitApk_InputFile);
}
catch (Exception ex)
{
main.ToLog(ApktoolEventType.Error, ex.Message);
}
}
private void ClearLogToolStripMenuItem_Click(object sender, EventArgs e)
{
main.logTxtBox.Text = "";
}
private void CopyToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
System.Windows.Forms.Clipboard.SetText(main.logTxtBox.SelectedText);
}
catch (Exception ex)
{
main.ToLog(ApktoolEventType.Error, ex.Message);
}
}
internal void DecApkOpenDirBtn_Click(object sender, EventArgs e)
{
if (Directory.Exists(main.textBox_BUILD_InputProjectDir.Text))
Process.Start("explorer.exe", main.textBox_BUILD_InputProjectDir.Text);
else
{
main.ToLog(ApktoolEventType.Error, Language.ErrorSelectedFileNotExist);
}
}
internal void DecOutOpenDirBtn_Click(object sender, EventArgs e)
{
if (Directory.Exists(Settings.Default.Decode_OutputDir))
Process.Start("explorer.exe", Settings.Default.Decode_OutputDir);
else
{
main.ToLog(ApktoolEventType.Error, Language.ErrorSelectedOutputFolderNotExist);
}
}
private void OpenAndroidMainfestBtn_Click(object sender, EventArgs e)
{
if (File.Exists(Path.Combine(main.textBox_BUILD_InputProjectDir.Text, "AndroidManifest.xml")))
Process.Start("explorer.exe", Path.Combine(main.textBox_BUILD_InputProjectDir.Text, "AndroidManifest.xml"));
else
main.ToLog(ApktoolEventType.Error, Language.AndroidManifestNotExist);
}
private void OpenApktoolYmlBtn_Click(object sender, EventArgs e)
{
if (File.Exists(Path.Combine(main.textBox_BUILD_InputProjectDir.Text, "apktool.yml")))
Process.Start("explorer.exe", Path.Combine(main.textBox_BUILD_InputProjectDir.Text, "apktool.yml"));
else
main.ToLog(ApktoolEventType.Error, Language.AndroidManifestNotExist);
}
private void CompiledApkOpenDirBtn_Click(object sender, EventArgs e)
{
if (Directory.Exists(Settings.Default.Build_OutputAppPath))
{
Process.Start("explorer.exe", Settings.Default.Build_OutputAppPath);
}
else
main.ToLog(ApktoolEventType.Error, Language.ErrorSelectedFileNotExist);
}
private void Button_OpenMainActivity_Click(object sender, EventArgs e)
{
string decPath = main.textBox_BUILD_InputProjectDir.Text;
if (Directory.Exists(decPath))
{
var launchActivityList = new List<string>
{
main.aapt != null ? main.aapt.LaunchableActivity : CommonUtils.GetActivityFromManifest(decPath),
"com\\unity3d\\player\\UnityPlayerActivity",
CommonUtils.GetApplicationNameFromManifest(decPath)
};
foreach (string launchActivity in launchActivityList)
{
if (String.IsNullOrEmpty(launchActivity))
continue;
Debug.WriteLine(launchActivity);
string path = null;
bool activityFound = false;
for (int i = 1; i < 100; i++)
{
string smaliFolder = (i == 1) ? "smali" : "smali_classes" + i;
path = Path.Combine(decPath, smaliFolder, launchActivity.Replace(".", "\\") + ".smali");
if (File.Exists(path))
{
Debug.WriteLine(path);
activityFound = true;
break;
}
}
if (activityFound && !CommonUtils.OnCreateExists(path))
continue;
if (activityFound)
{
main.ToLog(ApktoolEventType.None, String.Format(Language.MainActivityFound, path));
Process.Start("explorer.exe", path);
return;
}
else
continue;
}
main.ToLog(ApktoolEventType.Warning, Language.MainActivityNotFoundPleaseFindManually);
}
else
main.ToLog(ApktoolEventType.Error, Language.DecompiledAPKNotExist);
}
internal void ComApkOpenDir_Click(object sender, EventArgs e)
{
string decApkDir = main.textBox_BUILD_InputProjectDir.Text;
string outputFile = decApkDir + " compiled.apk";
if (Settings.Default.Build_SignAfterBuild)
outputFile = decApkDir + " signed.apk";
if (Settings.Default.Build_UseOutputAppPath)
{
outputFile = Path.Combine(Settings.Default.Build_OutputAppPath, Path.GetFileName(decApkDir)) + ".apk";
if (Settings.Default.Build_SignAfterBuild)
outputFile = Path.Combine(Settings.Default.Build_OutputAppPath, Path.GetFileName(decApkDir)) + " signed.apk";
}
if (File.Exists(outputFile))
Process.Start("explorer.exe", string.Format("/select,\"{0}\"", outputFile));
else
{
main.ToLog(ApktoolEventType.Error, Language.ErrorSelectedFileNotExist);
}
}
internal void SignApkOpenDirBtn_Click(object sender, EventArgs e)
{
string inputFile = Settings.Default.Sign_InputFile;
string outputFile = inputFile;
if (Settings.Default.Sign_UseOutputDir)
outputFile = Path.Combine(Settings.Default.Sign_OutputDir, Path.GetFileName(inputFile));
if (File.Exists(outputFile))
Process.Start("explorer.exe", string.Format("/select,\"{0}\"", outputFile));
else
{
main.ToLog(ApktoolEventType.Error, Language.ErrorSelectedFileNotExist);
}
}
internal void AlignApkOpenDirBtn_Click(object sender, EventArgs e)
{
string inputFile = Settings.Default.Zipalign_InputFile;
string outputFile = inputFile;
if (!String.IsNullOrEmpty(outputFile))
{
if (Settings.Default.Zipalign_UseOutputDir)
outputFile = Path.Combine(Settings.Default.Zipalign_OutputDir, Path.GetFileName(inputFile));
if (!Settings.Default.Zipalign_OverwriteOutputFile)
outputFile = PathUtils.GetDirectoryNameWithoutExtension(outputFile) + " aligned.apk";
}
if (File.Exists(outputFile))
Process.Start("explorer.exe", string.Format("/select,\"{0}\"", outputFile));
else
{
main.ToLog(ApktoolEventType.Error, Language.ErrorSelectedFileNotExist);
}
}
}
}
-116
View File
@@ -1,116 +0,0 @@
using APKToolGUI.Languages;
using APKToolGUI.Properties;
using Dark.Net;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace APKToolGUI.Handlers
{
internal class MenuItemHandlers
{
private static FormMain main;
public MenuItemHandlers(FormMain Main)
{
main = Main;
main.saveLogToFileToolStripMenuItem.Click += SaveLogItem_Click;
main.settingsToolStripMenuItem.Click += MenuItemSettings_Click;
main.exitToolStripMenuItem.Click += MenuItemExit_Click;
main.openTempFolderToolStripMenuItem.Click += OpenTempFolderToolStripMenuItem_Click;
main.checkForUpdateToolStripMenuItem.Click += MenuItemCheckUpdate_Click;
main.aboutToolStripMenuItem.Click += MenuItemAbout_Click;
main.apktoolIssuesToolStripMenuItem.Click += ApktoolIssuesLinkItem_Click;
main.baksmaliIssuesToolStripMenuItem.Click += BaksmaliIssuesLinkItem_Click;
main.reportAnIsuueToolStripMenuItem.Click += ReportAnIsuueToolStripMenuItem_Click;
main.newInsToolStripMenuItem.Click += NewInsToolStripMenuItem_Click;
}
private void NewInsToolStripMenuItem_Click(object sender, EventArgs e)
{
Process.Start(System.Reflection.Assembly.GetExecutingAssembly().Location);
}
private void SaveLogItem_Click(object sender, EventArgs e)
{
using (var sfd = new SaveFileDialog())
{
sfd.FileName = "APK Tool GUI logs";
sfd.Filter = Language.TextFile + " (*.txt)|*.txt";
sfd.FilterIndex = 2;
if (sfd.ShowDialog() == DialogResult.OK)
{
File.WriteAllText(sfd.FileName, main.logTxtBox.Text);
}
}
}
private void MenuItemSettings_Click(object sender, EventArgs e)
{
Theme theme = (Theme)Settings.Default.Theme;
if (Program.IsWin10OrAbove())
DarkNet.Instance.SetCurrentProcessTheme(theme);
FormSettings frm = new FormSettings();
if (Program.IsWin10OrAbove())
DarkNet.Instance.SetWindowThemeForms(frm, theme);
frm.ShowDialog();
}
private void MenuItemExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void OpenTempFolderToolStripMenuItem_Click(object sender, EventArgs e)
{
if (Directory.Exists(Program.TEMP_PATH))
Process.Start("explorer.exe", Program.TEMP_PATH);
else
{
Directory.CreateDirectory(Program.TEMP_PATH);
Process.Start("explorer.exe", Program.TEMP_PATH);
}
}
private void MenuItemCheckUpdate_Click(object sender, EventArgs e)
{
main.updateCheker.CheckAsync();
}
private void MenuItemAbout_Click(object sender, EventArgs e)
{
Theme theme = (Theme)Settings.Default.Theme;
if (Program.IsWin10OrAbove())
DarkNet.Instance.SetCurrentProcessTheme(theme);
FormAboutBox frm = new FormAboutBox();
if (Program.IsWin10OrAbove())
DarkNet.Instance.SetWindowThemeForms(frm, theme);
frm.ShowDialog();
}
private void ApktoolIssuesLinkItem_Click(object sender, EventArgs e)
{
Process.Start("https://github.com/iBotPeaches/Apktool/issues?q=is%3Aissue");
}
private void BaksmaliIssuesLinkItem_Click(object sender, EventArgs e)
{
Process.Start("https://github.com/JesusFreke/smali/issues?q=is%3Aissue");
}
private void ReportAnIsuueToolStripMenuItem_Click(object sender, EventArgs e)
{
Process.Start("https://github.com/AndnixSH/APKToolGUI/issues/new/choose");
}
}
}
@@ -1,145 +0,0 @@
using APKToolGUI.ApkTool;
using APKToolGUI.Languages;
using APKToolGUI.Properties;
using APKToolGUI.Utils;
using Ookii.Dialogs.WinForms;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace APKToolGUI.Handlers
{
class SignControlEventHandlers
{
private static FormMain main;
public SignControlEventHandlers(FormMain Main)
{
main = Main;
main.button_SIGN_BrowsePublicKey.Click += Button_SIGN_BrowsePublicKey_Click;
main.button_SIGN_BrowsePrivateKey.Click += Button_SIGN_BrowsePrivateKey_Click;
main.button_SIGN_BrowseInputFile.Click += Button_SIGN_BrowseInputFile_Click;
main.button_SIGN_BrowseOutputFile.Click += Button_SIGN_BrowseOutputFile_Click;
main.schemev1ComboBox.SelectedIndexChanged += SchemeComboBox_SelectedIndexChanged;
main.schemev2ComboBox.SelectedIndexChanged += SchemeComboBox_SelectedIndexChanged;
main.schemev3ComboBox.SelectedIndexChanged += SchemeComboBox_SelectedIndexChanged;
main.schemev4ComboBox.SelectedIndexChanged += SchemeComboBox_SelectedIndexChanged;
main.button_SIGN_Sign.Click += Button_SIGN_Sign_Click;
main.selectKeyStoreFileBtn.Click += SelectKeyStoreFileBtn_Click;
}
internal void Button_SIGN_BrowsePublicKey_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "*.pem|*.pem";
if (File.Exists(main.textBox_SIGN_PublicKey.Text))
{
ofd.InitialDirectory = Path.GetDirectoryName(main.textBox_SIGN_PublicKey.Text);
ofd.FileName = Path.GetFileNameWithoutExtension(main.textBox_SIGN_PublicKey.Text);
}
if (ofd.ShowDialog() == DialogResult.OK)
main.textBox_SIGN_PublicKey.Text = Program.GetPortablePath(ofd.FileName);
}
}
internal void Button_SIGN_BrowsePrivateKey_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "*.pk8|*.pk8";
if (File.Exists(main.textBox_SIGN_PrivateKey.Text))
{
ofd.InitialDirectory = Path.GetDirectoryName(main.textBox_SIGN_PrivateKey.Text);
ofd.FileName = Path.GetFileNameWithoutExtension(main.textBox_SIGN_PrivateKey.Text);
}
if (ofd.ShowDialog() == DialogResult.OK)
main.textBox_SIGN_PrivateKey.Text = Program.GetPortablePath(ofd.FileName);
}
}
internal void Button_SIGN_BrowseOutputFile_Click(object sender, EventArgs e)
{
VistaFolderBrowserDialog dlg = new VistaFolderBrowserDialog();
dlg.ShowNewFolderButton = true;
if (dlg.ShowDialog() == DialogResult.OK)
{
main.textBox_SIGN_OutputFile.Text = dlg.SelectedPath;
}
}
internal async void Button_SIGN_BrowseInputFile_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "(*.apk;*.jar;*.zip)|*.apk;*.jar;*.zip";
if (ofd.ShowDialog() == DialogResult.OK)
{
main.textBox_SIGN_InputFile.Text = ofd.FileName;
await main.GetApkInfo(ofd.FileName);
main.textBox_SIGN_OutputFile.Text =
String.Format("{0}{1}{2}_signed{3}",
Path.GetDirectoryName(main.textBox_SIGN_InputFile.Text),
Path.DirectorySeparatorChar,
Path.GetFileNameWithoutExtension(main.textBox_SIGN_InputFile.Text),
Path.GetExtension(main.textBox_SIGN_InputFile.Text));
}
}
}
internal async void Button_SIGN_Sign_Click(object sender, EventArgs e)
{
try
{
main.Save();
if (!File.Exists(Settings.Default.Sign_PublicKey))
{
main.ShowMessage(Language.SignPublicKeyNotFound, MessageBoxIcon.Warning);
return;
}
if (!File.Exists(Settings.Default.Sign_PrivateKey))
{
main.ShowMessage(Language.SignPrivateKeyNotFound, MessageBoxIcon.Warning);
return;
}
if (!File.Exists(main.textBox_SIGN_InputFile.Text))
{
main.ShowMessage(Language.SignInputFileNotFound, MessageBoxIcon.Warning);
return;
}
await main.Sign(Settings.Default.Sign_InputFile);
}
catch (Exception ex)
{
main.ToLog(ApktoolEventType.Error, ex.Message);
}
}
internal void SelectKeyStoreFileBtn_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "Keystore|*.keystore;*.jks";
if (ofd.ShowDialog() == DialogResult.OK)
main.keyStoreFileTxtBox.Text = ofd.FileName;
}
}
private void SchemeComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
Settings.Default.Sign_Schemev1 = main.schemev1ComboBox.SelectedIndex;
Settings.Default.Sign_Schemev2 = main.schemev2ComboBox.SelectedIndex;
Settings.Default.Sign_Schemev3 = main.schemev3ComboBox.SelectedIndex;
Settings.Default.Sign_Schemev4 = main.schemev4ComboBox.SelectedIndex;
}
}
}
@@ -1,69 +0,0 @@
using APKToolGUI.Languages;
using APKToolGUI.Properties;
using APKToolGUI.Utils;
using Ookii.Dialogs.WinForms;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace APKToolGUI.Handlers
{
class SmaliControlEventHandlers
{
private static FormMain main;
public SmaliControlEventHandlers(FormMain Main)
{
main = Main;
main.smaliBrowseOutputBtn.Click += SmaliBrowseOutputBtn_Click;
main.smaliBrowseInputDirBtn.Click += SmaliBrowseInputDirBtn_Click;
main.comSmaliBtn.Click += ComSmaliBtn_Click;
}
internal void SmaliBrowseOutputBtn_Click(object sender, EventArgs e)
{
VistaFolderBrowserDialog dlg = new VistaFolderBrowserDialog();
dlg.ShowNewFolderButton = true;
if (dlg.ShowDialog() == DialogResult.OK)
{
main.smaliBrowseOutputTxtBox.Text = dlg.SelectedPath;
}
}
internal void SmaliBrowseInputDirBtn_Click(object sender, EventArgs e)
{
VistaFolderBrowserDialog dlg = new VistaFolderBrowserDialog();
dlg.ShowNewFolderButton = true;
if (dlg.ShowDialog() == DialogResult.OK)
{
main.smaliBrowseInputDirTxtBox.Text = dlg.SelectedPath;
}
}
internal async void ComSmaliBtn_Click(object sender, EventArgs e)
{
if (main.smaliUseOutputChkBox.Checked)
{
if (String.IsNullOrWhiteSpace(main.smaliBrowseOutputTxtBox.Text) || !Directory.Exists(main.smaliBrowseOutputTxtBox.Text))
{
main.ShowMessage(Language.ErrorSelectedOutputFolderNotExist, MessageBoxIcon.Warning);
return;
}
}
if (!Directory.Exists(main.smaliBrowseInputDirTxtBox.Text))
{
main.ShowMessage(Language.ErrorSelectedFileNotExist, MessageBoxIcon.Warning);
return;
}
await main.Smali(Settings.Default.Smali_InputDir);
}
}
}
@@ -1,92 +0,0 @@
using APKToolGUI.Languages;
using APKToolGUI.Properties;
using APKToolGUI.Utils;
using Ookii.Dialogs.WinForms;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace APKToolGUI.Handlers
{
class ZipalignControlEventHandlers
{
private static FormMain main;
public ZipalignControlEventHandlers(FormMain Main)
{
main = Main;
CheckAlignSwitch = !Settings.Default.Zipalign_CheckOnly;
main.checkBox_ZIPALIGN_CheckAlignment.Click += CheckBox_ZIPALIGN_CheckAlignment_CheckedChanged;
main.button_ZIPALIGN_BrowseOutputFile.Click += Button_ZIPALIGN_BrowseOutputFile_Click;
main.button_ZIPALIGN_BrowseInputFile.Click += Button_ZIPALIGN_BrowseInputFile_Click;
main.button_ZIPALIGN_Align.Click += Button_ZIPALIGN_Align_Click;
}
internal bool CheckAlignSwitch
{
set
{
main.checkBox_ZIPALIGN_Recompress.Enabled = value;
main.checkBox_ZIPALIGN_OverwriteOutputFile.Enabled = value;
}
}
internal void CheckBox_ZIPALIGN_CheckAlignment_CheckedChanged(object sender, EventArgs e)
{
CheckAlignSwitch = !main.checkBox_ZIPALIGN_CheckAlignment.Checked;
}
internal void Button_ZIPALIGN_BrowseOutputFile_Click(object sender, EventArgs e)
{
VistaFolderBrowserDialog dlg = new VistaFolderBrowserDialog();
dlg.ShowNewFolderButton = true;
if (dlg.ShowDialog() == DialogResult.OK)
{
main.textBox_ZIPALIGN_OutputFile.Text = dlg.SelectedPath;
}
}
internal async void Button_ZIPALIGN_BrowseInputFile_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog())
{
// ofd.Filter = "ZIP archives(*.apk;*.zip;*.jar)|*.apk;*.zip;*.jar";
ofd.Filter = Language.ZIPArchives + " (*.apk)|*.apk";
if (File.Exists(main.textBox_ZIPALIGN_InputFile.Text))
{
ofd.InitialDirectory = Path.GetDirectoryName(main.textBox_ZIPALIGN_InputFile.Text);
ofd.FileName = Path.GetFileName(main.textBox_ZIPALIGN_InputFile.Text);
}
if (ofd.ShowDialog() == DialogResult.OK)
{
main.textBox_ZIPALIGN_InputFile.Text = ofd.FileName;
await main.GetApkInfo(ofd.FileName);
if (!main.checkBox_ZIPALIGN_CheckAlignment.Checked)
main.textBox_ZIPALIGN_OutputFile.Text = String.Format("{0}\\{1}_zipaligned{2}",
Path.GetDirectoryName(ofd.FileName),
Path.GetFileNameWithoutExtension(ofd.FileName),
Path.GetExtension(ofd.FileName));
}
}
}
internal async void Button_ZIPALIGN_Align_Click(object sender, EventArgs e)
{
if (!File.Exists(main.textBox_ZIPALIGN_InputFile.Text))
{
main.ShowMessage(Language.ErrorSelectedFileNotExist, MessageBoxIcon.Warning);
return;
}
string inputFile = Settings.Default.Zipalign_InputFile;
await main.Align(inputFile);
}
}
}
+2 -2
View File
@@ -33,7 +33,7 @@ namespace Java
public new bool Start(string args)
{
EnableRaisingEvents = true;
string customArgs = "--enable-native-access=ALL-UNNAMED";
string customArgs = "";
if (Settings.Default.UseCustomJVMArgs)
customArgs = Settings.Default.CustomJVMArgs;
@@ -51,7 +51,7 @@ namespace Java
using (Process javaProcess = new Process())
{
javaProcess.StartInfo.FileName = JavaPath;
javaProcess.StartInfo.Arguments = String.Format("--enable-native-access=ALL-UNNAMED -jar \"{0}\" {1}", JarPath, args);
javaProcess.StartInfo.Arguments = String.Format("-jar \"{0}\" {1}", JarPath, args);
javaProcess.StartInfo.CreateNoWindow = true;
javaProcess.StartInfo.UseShellExecute = false;
javaProcess.StartInfo.RedirectStandardError = true;
+86
View File
@@ -1337,5 +1337,91 @@ namespace APKToolGUI.Languages {
return ResourceManager.GetString("ZIPArchives", resourceCulture);
}
}
internal static string CopyAll {
get {
return ResourceManager.GetString("CopyAll", resourceCulture);
}
}
internal static string Loading {
get {
return ResourceManager.GetString("Loading", resourceCulture);
}
}
internal static string Ready {
get {
return ResourceManager.GetString("Ready", resourceCulture);
}
}
internal static string SaveImageTitle {
get {
return ResourceManager.GetString("SaveImageTitle", resourceCulture);
}
}
internal static string PngImage {
get {
return ResourceManager.GetString("PngImage", resourceCulture);
}
}
internal static string FilterAndroidPackage {
get { return ResourceManager.GetString("FilterAndroidPackage", resourceCulture); }
}
internal static string FilterSplitApk {
get { return ResourceManager.GetString("FilterSplitApk", resourceCulture); }
}
internal static string FilterApkJarZip {
get { return ResourceManager.GetString("FilterApkJarZip", resourceCulture); }
}
internal static string FilterKeystore {
get { return ResourceManager.GetString("FilterKeystore", resourceCulture); }
}
internal static string FilterPublicKey {
get { return ResourceManager.GetString("FilterPublicKey", resourceCulture); }
}
internal static string FilterPrivateKey {
get { return ResourceManager.GetString("FilterPrivateKey", resourceCulture); }
}
internal static string FilterApk {
get { return ResourceManager.GetString("FilterApk", resourceCulture); }
}
internal static string FilterDex {
get { return ResourceManager.GetString("FilterDex", resourceCulture); }
}
internal static string FilterJavaExe {
get { return ResourceManager.GetString("FilterJavaExe", resourceCulture); }
}
internal static string FilterApktool {
get { return ResourceManager.GetString("FilterApktool", resourceCulture); }
}
internal static string SchemeDefault {
get { return ResourceManager.GetString("SchemeDefault", resourceCulture); }
}
internal static string SchemeTrue {
get { return ResourceManager.GetString("SchemeTrue", resourceCulture); }
}
internal static string SchemeFalse {
get { return ResourceManager.GetString("SchemeFalse", resourceCulture); }
}
internal static string AaptDump {
get { return ResourceManager.GetString("AaptDump", resourceCulture); }
}
}
}
+578
View File
@@ -543,4 +543,582 @@
<data name="SetLanguageRestartApplication" xml:space="preserve">
<value>Sprache installiert. Programm neu starten?</value>
</data>
<data name="AboutVersion" xml:space="preserve">
<value>Version</value>
</data>
<data name="AboutCopyright" xml:space="preserve">
<value>Copyright</value>
</data>
<data name="AboutGithubRepo" xml:space="preserve">
<value>Github Repo</value>
</data>
<data name="SettingsGeneral" xml:space="preserve">
<value>Allgemein</value>
</data>
<data name="SettingsLanguage" xml:space="preserve">
<value>Sprache</value>
</data>
<data name="SettingsContextMenu" xml:space="preserve">
<value>Kontextmenü</value>
</data>
<data name="SettingsTheme" xml:space="preserve">
<value>Thema</value>
</data>
<data name="SettingsTempNote" xml:space="preserve">
<value>Der Vorgang wird langsamer sein, da die Dateien in den temporären Ordner verschoben werden</value>
</data>
<data name="SettingsAdminRights" xml:space="preserve">
<value>Administratorrechte erforderlich</value>
</data>
<data name="SettingsClearLog" xml:space="preserve">
<value>Protokoll löschen, bevor du Maßnahmen ergreifst</value>
</data>
<data name="SettingsPlaySound" xml:space="preserve">
<value>Ton abspielen, wenn du fertig bist</value>
</data>
<data name="SettingsCustomTemp" xml:space="preserve">
<value>Benutzerdefinierter temporärer Standort</value>
</data>
<data name="SettingsCustomJava" xml:space="preserve">
<value>Benutzerdefinierter Java-Speicherort</value>
</data>
<data name="SettingsUtf8" xml:space="preserve">
<value>Unterstützung für UTF-8-Dateinamen</value>
</data>
<data name="SettingsCustomJvmArgs" xml:space="preserve">
<value>Benutzerdefinierte JVM-Argumente</value>
</data>
<data name="SettingsCheckUpdate" xml:space="preserve">
<value>Beim Start nach Updates suchen</value>
</data>
<data name="SettingsCustomApktool" xml:space="preserve">
<value>Benutzerdefinierter APKTool-Speicherort</value>
</data>
<data name="SettingsIgnoreOutputCM" xml:space="preserve">
<value>Benutzerdefiniertes Ausgabeverzeichnis für Kontextmenü ignorieren</value>
</data>
<data name="SettingsInstall" xml:space="preserve">
<value>Install …</value>
</data>
<data name="SettingsUninstall" xml:space="preserve">
<value>Deinstall …</value>
</data>
<data name="SettingsCancel" xml:space="preserve">
<value>Abbrechen</value>
</data>
<data name="ThemeAuto" xml:space="preserve">
<value>Automatisch</value>
</data>
<data name="ThemeLight" xml:space="preserve">
<value>Hell</value>
</data>
<data name="ThemeDark" xml:space="preserve">
<value>Dunkel</value>
</data>
<data name="tabPageMain.Text" xml:space="preserve">
<value>Hauptseite</value>
</data>
<data name="tabPageApkInfo.Text" xml:space="preserve">
<value>APK-Info</value>
</data>
<data name="tabPageDecode.Text" xml:space="preserve">
<value>Dekompilieren</value>
</data>
<data name="tabPageSign.Text" xml:space="preserve">
<value>Signieren</value>
</data>
<data name="tabPageZipAlign.Text" xml:space="preserve">
<value>Zip ausrichten</value>
</data>
<data name="splitApkTxt.Text" xml:space="preserve">
<value>Geteilte APKs zu einer APK zusammenführen:</value>
</data>
<data name="selSplitApkBtn.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="mergeApkBtn.Text" xml:space="preserve">
<value>Zusammenführen</value>
</data>
<data name="comApkOpenDir.Text" xml:space="preserve">
<value>APK-Ort kompilieren</value>
</data>
<data name="decOutOpenDirBtn.Text" xml:space="preserve">
<value>Ausgabeort dekompilieren</value>
</data>
<data name="signApkOpenDirBtn.Text" xml:space="preserve">
<value>APK-Ort signieren</value>
</data>
<data name="alignApkOpenDirBtn.Text" xml:space="preserve">
<value>APK-Verzeichnis zipalign</value>
</data>
<data name="decApkOpenDirBtn.Text" xml:space="preserve">
<value>APK-Ort dekompilieren</value>
</data>
<data name="compileOutputOpenDirBtn.Text" xml:space="preserve">
<value>Ausgabeort kompilieren</value>
</data>
<data name="label4.Text" xml:space="preserve">
<value>APK-Datei zum Signieren:</value>
</data>
<data name="button_SIGN_BrowseInputFile.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="button_SIGN_Sign.Text" xml:space="preserve">
<value>Signieren</value>
</data>
<data name="label3.Text" xml:space="preserve">
<value>APK-Dateiausrichtung optimieren:</value>
</data>
<data name="button_ZIPALIGN_Align.Text" xml:space="preserve">
<value>Ausrichtung optimieren</value>
</data>
<data name="button_ZIPALIGN_BrowseInputFile.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="button_BUILD_BrowseInputProjectDir.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="button_BUILD_Build.Text" xml:space="preserve">
<value>Kompilieren</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>APK/XAPK/APKS/ZIP/APKM-Datei:</value>
</data>
<data name="button_DECODE_Decode.Text" xml:space="preserve">
<value>Dekompilieren</value>
</data>
<data name="button_DECODE_BrowseInputAppPath.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="basicInfoTabPage.Text" xml:space="preserve">
<value>Basisinfos</value>
</data>
<data name="label31.Text" xml:space="preserve">
<value>Startaktivität:</value>
</data>
<data name="label30.Text" xml:space="preserve">
<value>Architekturen:</value>
</data>
<data name="label17.Text" xml:space="preserve">
<value>Datei:</value>
</data>
<data name="selApkFileInfoBtn.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="label18.Text" xml:space="preserve">
<value>Lokale:</value>
</data>
<data name="label15.Text" xml:space="preserve">
<value>Berechtigungen:</value>
</data>
<data name="label14.Text" xml:space="preserve">
<value>Dichten:</value>
</data>
<data name="label7.Text" xml:space="preserve">
<value>App-Name:</value>
</data>
<data name="label9.Text" xml:space="preserve">
<value>Paketname:</value>
</data>
<data name="label13.Text" xml:space="preserve">
<value>Bildschirmgrößen:</value>
</data>
<data name="label12.Text" xml:space="preserve">
<value>Ziel-SDK:</value>
</data>
<data name="groupBox_DECODE_Options.Text" xml:space="preserve">
<value>Optionen</value>
</data>
<data name="checkBox3.Text" xml:space="preserve">
<value>Anzahl der zu verwendenden Threads festlegen.</value>
</data>
<data name="checkBox7.Text" xml:space="preserve">
<value>Analysiere die APK-Informationen nicht, wenn du APK zum Dekompilieren auswählst</value>
</data>
<data name="decSetApiLvlChkBox.Text" xml:space="preserve">
<value>API-Ebene der zu generierenden Datei fest, z. B. 14 für ICS festlegen</value>
</data>
<data name="checkBox_DECODE_FixError.Text" xml:space="preserve">
<value>ApkTool-Fehler nach der Dekompilierung beheben</value>
</data>
<data name="checkBox_DECODE_OnlyMainClasses.Text" xml:space="preserve">
<value>Nur Haupt-Dex-Klassen (classes[0-9]*.dex) im Stammverzeichnis zerlegen</value>
</data>
<data name="button_DECODE_BrowseOutputDirectory.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="checkBox_DECODE_UseFramework.Text" xml:space="preserve">
<value>Verwendet Framework-Dateien in:</value>
</data>
<data name="button_DECODE_BrowseFrameDir.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="checkBox_DECODE_MatchOriginal.Text" xml:space="preserve">
<value>Hält die Dateien so nah wie möglich am Original. Verhindert einen Wiederaufbau.</value>
</data>
<data name="checkBox_DECODE_OutputDirectory.Text" xml:space="preserve">
<value>Ausgabeverzeichnis:</value>
</data>
<data name="checkBox_DECODE_KeepBrokenRes.Text" xml:space="preserve">
<value>Defekte Ressourcen beibehalten</value>
</data>
<data name="checkBox_DECODE_NoSrc.Text" xml:space="preserve">
<value>Quellen nicht entschlüsseln</value>
</data>
<data name="checkBox_DECODE_Force.Text" xml:space="preserve">
<value>Zielverzeichnis löschen erzwingen</value>
</data>
<data name="checkBox_DECODE_NoRes.Text" xml:space="preserve">
<value>Ressourcen nicht entschlüsseln</value>
</data>
<data name="checkBox_DECODE_NoDebugInfo.Text" xml:space="preserve">
<value>Keine Debug-Informationen schreiben aus (.local, .param, .line usw.)</value>
</data>
<data name="groupBox_BUILD_Options.Text" xml:space="preserve">
<value>Optionen</value>
</data>
<data name="checkBox_BUILD_NetSecConf.Text" xml:space="preserve">
<value>Ausgabe-APK eine generische Netzwerksicherheitskonfigurationsdatei hinzufügen</value>
</data>
<data name="useAapt2ChkBox.Text" xml:space="preserve">
<value>aapt2 verwenden (Aktualisiert apktool, um die experimentelle aapt2-Binärdatei zu verwenden)</value>
</data>
<data name="buildSetApiLvlChkBox.Text" xml:space="preserve">
<value>API-Ebene der zu generierenden Datei fest, z. B. 14 für ICS festlegen</value>
</data>
<data name="createUnsignApkChkBox.Text" xml:space="preserve">
<value>Nach Build eine unsignierte APK mit der Originalsignatur erstellen</value>
</data>
<data name="signAfterBuildChkBox.Text" xml:space="preserve">
<value>Nach Build/Zipalign signieren</value>
</data>
<data name="zipalignAfterBuildChkBox.Text" xml:space="preserve">
<value>Zipalign nach Build</value>
</data>
<data name="checkBox_BUILD_NoCrunch.Text" xml:space="preserve">
<value>Verarbeitung von Ressourcendateien während des Build-Schritts deaktivieren</value>
</data>
<data name="button_BUILD_BrowseOutputAppPath.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="checkBox_BUILD_ForceAll.Text" xml:space="preserve">
<value>Änderungserkennung überspringwen und alle Dateien erstellen</value>
</data>
<data name="button_BUILD_BrowseFrameDir.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="button_BUILD_BrowseAaptPath.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="checkBox_BUILD_OutputAppPath.Text" xml:space="preserve">
<value>APK-Ausgabeverzeichnis:</value>
</data>
<data name="checkBox_BUILD_CopyOriginal.Text" xml:space="preserve">
<value>Originalordner "AndroidManifest.xml" und "META-INF" kopieren</value>
</data>
<data name="checkBox_BUILD_UseAapt.Text" xml:space="preserve">
<value>Verwendete aapt.exe in:</value>
</data>
<data name="checkBox_BUILD_UseFramework.Text" xml:space="preserve">
<value>Verwendet Framework-Dateien in:</value>
</data>
<data name="groupBox_SIGN_Options.Text" xml:space="preserve">
<value>Optionen</value>
</data>
<data name="checkBox2.Text" xml:space="preserve">
<value>APK nach Signieren installieren (Stelle sicher, dass das Gerät zuerst auf der Registerkarte "ADB"
ausgewählt ist.)</value>
</data>
<data name="checkBox1.Text" xml:space="preserve">
<value>Eingabedatei überschreiben</value>
</data>
<data name="autoDelIdsigChkBox.Text" xml:space="preserve">
<value>IDSIG-Datei automatisch löschen</value>
</data>
<data name="label27.Text" xml:space="preserve">
<value>Schema v4:</value>
</data>
<data name="label26.Text" xml:space="preserve">
<value>Schema v3:</value>
</data>
<data name="label25.Text" xml:space="preserve">
<value>Schema v2:</value>
</data>
<data name="label24.Text" xml:space="preserve">
<value>Schema v1:</value>
</data>
<data name="selectKeyStoreFileBtn.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="label22.Text" xml:space="preserve">
<value>Es wird dringend empfohlen, deinen eigenen Schlüssel zu verwenden, der über Android Studio oder andere Tools erstellt wurde</value>
</data>
<data name="label21.Text" xml:space="preserve">
<value>Passwort:</value>
</data>
<data name="label20.Text" xml:space="preserve">
<value>keystore/jks-Datei:</value>
</data>
<data name="useKeyStoreChkBox.Text" xml:space="preserve">
<value>Keystore verwenden</value>
</data>
<data name="useSigningOutputDir.Text" xml:space="preserve">
<value>APK-Ausgabeverzeichnis:</value>
</data>
<data name="label_SIGN_PrivateKey.Text" xml:space="preserve">
<value>Privater Schlüssel:</value>
</data>
<data name="label_SIGN_PublicKey.Text" xml:space="preserve">
<value>Öffentlicher Schlüssel:</value>
</data>
<data name="button_SIGN_BrowseOutputFile.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="button_SIGN_BrowsePublicKey.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="button_SIGN_BrowsePrivateKey.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="groupBox_ZIPALIGN_Options.Text" xml:space="preserve">
<value>Optionen</value>
</data>
<data name="signAfterZipalignChkBox.Text" xml:space="preserve">
<value>Nach Zipalign signieren</value>
</data>
<data name="checkBox_ZIPALIGN_Recompress.Text" xml:space="preserve">
<value>Mit Zopfli erneut komprimieren</value>
</data>
<data name="label_ZIPALIGN_AlignmentBytes.Text" xml:space="preserve">
<value>Ausrichtung in Bytes, z.B. '4' bietet 32-Bit-Ausrichtung</value>
</data>
<data name="button_ZIPALIGN_BrowseOutputFile.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="checkBox_ZIPALIGN_CheckAlignment.Text" xml:space="preserve">
<value>Nur Ausrichtung prüfen (Datei wird nicht geändert)</value>
</data>
<data name="checkBox_ZIPALIGN_VerboseOutput.Text" xml:space="preserve">
<value>Ausführliche Ausgabe</value>
</data>
<data name="checkBox_ZIPALIGN_OverwriteOutputFile.Text" xml:space="preserve">
<value>Vorhandene Ausgabedatei überschreiben</value>
</data>
<data name="groupBox1.Text" xml:space="preserve">
<value>Optionen</value>
</data>
<data name="openFwFolderBtn.Text" xml:space="preserve">
<value>Framework-Ordner öffnen</value>
</data>
<data name="clearFwBtn.Text" xml:space="preserve">
<value>Framework bereinigen</value>
</data>
<data name="clearFwBeforeDecodeChkBox.Text" xml:space="preserve">
<value>Framework vor Dekompilierung bereinigen</value>
</data>
<data name="groupBox_IF_Options.Text" xml:space="preserve">
<value>Framework installieren</value>
</data>
<data name="checkBox_IF_Tag.Text" xml:space="preserve">
<value>Frameworks markieren mit:</value>
</data>
<data name="checkBox_IF_FramePath.Text" xml:space="preserve">
<value>Speichert Framework-Dateien in:</value>
</data>
<data name="button_IF_InstallFramework.Text" xml:space="preserve">
<value>Installieren</value>
</data>
<data name="button_IF_BrowseFrameDir.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="button_IF_BrowseInputFramePath.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="label29.Text" xml:space="preserve">
<value>Smali-Ordner zum Kompilieren:</value>
</data>
<data name="smaliUseOutputChkBox.Text" xml:space="preserve">
<value>Dex-Ausgabeverzeichnis:</value>
</data>
<data name="comSmaliBtn.Text" xml:space="preserve">
<value>Kompilieren</value>
</data>
<data name="smaliBrowseOutputBtn.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="smaliBrowseInputDirBtn.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="label28.Text" xml:space="preserve">
<value>Dex zum Dekompilieren:</value>
</data>
<data name="baksmaliUseOutputChkBox.Text" xml:space="preserve">
<value>Ordner-Ausgabeverzeichnis:</value>
</data>
<data name="baksmaliBrowseOutputBtn.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="decSmaliBtn.Text" xml:space="preserve">
<value>Dekompilieren</value>
</data>
<data name="baksmaliBrowseInputDexBtn.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="label33.Text" xml:space="preserve">
<value>Ausgewähltes Gerät:</value>
</data>
<data name="killAdbBtn.Text" xml:space="preserve">
<value>ADB-Prozess beenden</value>
</data>
<data name="installApkBtn.Text" xml:space="preserve">
<value>APK installieren</value>
</data>
<data name="refreshDevicesBtn.Text" xml:space="preserve">
<value>Aktualisieren</value>
</data>
<data name="selApkAdbBtn.Text" xml:space="preserve">
<value>…</value>
</data>
<data name="setVendorChkBox.Text" xml:space="preserve">
<value>Anbieter auf Play Store einstellen (com.android.vending)</value>
</data>
<data name="label32.Text" xml:space="preserve">
<value>Ausgewählte APK:</value>
</data>
<data name="toolStripStatusLabelStateText.Text" xml:space="preserve">
<value>Laden …</value>
</data>
<data name="copyToolStripMenuItem.Text" xml:space="preserve">
<value>Kopieren</value>
</data>
<data name="clearLogToolStripMenuItem.Text" xml:space="preserve">
<value>Protokoll löschen</value>
</data>
<data name="fileToolStripMenuItem.Text" xml:space="preserve">
<value>Datei</value>
</data>
<data name="newInsToolStripMenuItem.Text" xml:space="preserve">
<value>Neue Instanz</value>
</data>
<data name="saveLogToFileToolStripMenuItem.Text" xml:space="preserve">
<value>Protokoll in Datei speichern</value>
</data>
<data name="settingsToolStripMenuItem.Text" xml:space="preserve">
<value>Einstellungen</value>
</data>
<data name="openTempFolderToolStripMenuItem.Text" xml:space="preserve">
<value>Temporären Ordner öffnen</value>
</data>
<data name="clearTempFolderToolStripMenuItem.Text" xml:space="preserve">
<value>Temporären Ordner bereinigen</value>
</data>
<data name="exitToolStripMenuItem.Text" xml:space="preserve">
<value>Beenden</value>
</data>
<data name="helpToolStripMenuItem.Text" xml:space="preserve">
<value>Hilfe</value>
</data>
<data name="checkForUpdateToolStripMenuItem.Text" xml:space="preserve">
<value>Auf Update überprüfen</value>
</data>
<data name="reportAnIsuueToolStripMenuItem.Text" xml:space="preserve">
<value>Problem melden</value>
</data>
<data name="apktoolIssuesToolStripMenuItem.Text" xml:space="preserve">
<value>Apktool Fehlerverfolgung</value>
</data>
<data name="baksmaliIssuesToolStripMenuItem.Text" xml:space="preserve">
<value>Baksmali Fehlerverfolgung</value>
</data>
<data name="aboutToolStripMenuItem.Text" xml:space="preserve">
<value>Über</value>
</data>
<data name="label2.Text" xml:space="preserve">
<value>Dekompilierter APK-Ordner:</value>
</data>
<data name="useAPKEditorForDecompilingItem.Text" xml:space="preserve">
<value>APKEditor zum Dekompilieren verwenden</value>
</data>
<data name="settingsToolStripMenuItem1.Text" xml:space="preserve">
<value>Einstellungen</value>
</data>
<data name="zipalignOutputDirChkBox.Text" xml:space="preserve">
<value>APK-Ausgabeverzeichnis:</value>
</data>
<data name="button_OpenMainActivity.Text" xml:space="preserve">
<value>Main activity smali </value>
</data>
<data name="openApktoolYmlBtn.Text" xml:space="preserve">
<value>Apktool.yml</value>
</data>
<data name="openAndroidMainfestBtn.Text" xml:space="preserve">
<value>AndroidManifest.xml</value>
</data>
<data name="apkDlLinkBtn.Text" xml:space="preserve">
<value>Apk-DL</value>
</data>
<data name="apkSosLinkBtn.Text" xml:space="preserve">
<value>ApkSos</value>
</data>
<data name="apkMirrorLinkBtn.Text" xml:space="preserve">
<value>Apk Mirror</value>
</data>
<data name="apkSupportLinkBtn.Text" xml:space="preserve">
<value> Apk Mirror
Apk.support </value>
</data>
<data name="apkGkLinkBtn.Text" xml:space="preserve">
<value>ApkGk</value>
</data>
<data name="apkComboLinkBtn.Text" xml:space="preserve">
<value>ApkCombo</value>
</data>
<data name="apkAioLinkBtn.Text" xml:space="preserve">
<value>ApkAio</value>
</data>
<data name="apkPureLinkBtn.Text" xml:space="preserve">
<value>ApkPure</value>
</data>
<data name="psLinkBtn.Text" xml:space="preserve">
<value>Play Store</value>
</data>
<data name="label19.Text" xml:space="preserve">
<value>Links:</value>
</data>
<data name="label8.Text" xml:space="preserve">
<value>Version:</value>
</data>
<data name="label11.Text" xml:space="preserve">
<value>Version:</value>
</data>
<data name="label10.Text" xml:space="preserve">
<value>Build:</value>
</data>
<data name="useAliasChkBox.Text" xml:space="preserve">
<value>Alias:</value>
</data>
<data name="tabPageInstallFramework.Text" xml:space="preserve">
<value>Framework</value>
</data>
<data name="smaliGroupBox.Text" xml:space="preserve">
<value>Smali</value>
</data>
<data name="bakSmaliGroupBox.Text" xml:space="preserve">
<value>Baksmali</value>
</data>
<data name="tabPageBaksmali.Text" xml:space="preserve">
<value>Baksmali</value>
</data>
<data name="tabPageAdb.Text" xml:space="preserve">
<value>ADB</value>
</data>
<data name="toolStripStatusLabelStateImage.Text" xml:space="preserve">
<value>toolStripStatusLabel1</value>
</data>
<data name="statusStrip1.Text" xml:space="preserve">
<value>statusStrip1</value>
</data>
<data name="menuStrip1.Text" xml:space="preserve">
<value>menuStrip1</value>
</data>
</root>
+658 -1
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
@@ -543,4 +543,661 @@
<data name="SetLanguageRestartApplication" xml:space="preserve">
<value />
</data>
<data name="AboutVersion" xml:space="preserve">
<value>Version</value>
</data>
<data name="AboutCopyright" xml:space="preserve">
<value>Copyright</value>
</data>
<data name="AboutGithubRepo" xml:space="preserve">
<value>Github Repo</value>
</data>
<data name="AboutOK" xml:space="preserve">
<value>OK</value>
</data>
<data name="SettingsGeneral" xml:space="preserve">
<value>General</value>
</data>
<data name="SettingsLanguage" xml:space="preserve">
<value>Language</value>
</data>
<data name="SettingsContextMenu" xml:space="preserve">
<value>Context menu</value>
</data>
<data name="SettingsTheme" xml:space="preserve">
<value>Theme</value>
</data>
<data name="SettingsTempNote" xml:space="preserve">
<value>The process will be slower since files will be moved to temp folder </value>
</data>
<data name="SettingsAdminRights" xml:space="preserve">
<value>Administrator rights required</value>
</data>
<data name="SettingsClearLog" xml:space="preserve">
<value>Clear log before action</value>
</data>
<data name="SettingsPlaySound" xml:space="preserve">
<value>Play sound when done</value>
</data>
<data name="SettingsCustomTemp" xml:space="preserve">
<value>Custom temp location</value>
</data>
<data name="SettingsCustomJava" xml:space="preserve">
<value>Custom Java location</value>
</data>
<data name="SettingsUtf8" xml:space="preserve">
<value>UTF-8 filename support</value>
</data>
<data name="SettingsCustomJvmArgs" xml:space="preserve">
<value>Custom JVM arguments</value>
</data>
<data name="SettingsCheckUpdate" xml:space="preserve">
<value>Check for updates at startup</value>
</data>
<data name="SettingsCustomApktool" xml:space="preserve">
<value>Custom apktool location</value>
</data>
<data name="SettingsIgnoreOutputCM" xml:space="preserve">
<value>Ignore custom output directory for context menu</value>
</data>
<data name="SettingsInstall" xml:space="preserve">
<value>Install</value>
</data>
<data name="SettingsUninstall" xml:space="preserve">
<value>Uninstall</value>
</data>
<data name="SettingsCancel" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="ThemeAuto" xml:space="preserve">
<value>Auto</value>
</data>
<data name="ThemeLight" xml:space="preserve">
<value>Light</value>
</data>
<data name="ThemeDark" xml:space="preserve">
<value>Dark</value>
</data>
<data name="splitApkTxt.Text" xml:space="preserve">
<value>Merge split APK into single APK:</value>
</data>
<data name="selSplitApkBtn.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="mergeApkBtn.Text" xml:space="preserve">
<value>Merge</value>
</data>
<data name="comApkOpenDir.Text" xml:space="preserve">
<value>Compiled APK location</value>
</data>
<data name="decOutOpenDirBtn.Text" xml:space="preserve">
<value>Decompile output location</value>
</data>
<data name="signApkOpenDirBtn.Text" xml:space="preserve">
<value>Sign APK location</value>
</data>
<data name="alignApkOpenDirBtn.Text" xml:space="preserve">
<value>Zipalign APK location</value>
</data>
<data name="decApkOpenDirBtn.Text" xml:space="preserve">
<value>Decompiled APK location</value>
</data>
<data name="compileOutputOpenDirBtn.Text" xml:space="preserve">
<value>Compile output location</value>
</data>
<data name="button_OpenMainActivity.Text" xml:space="preserve">
<value>Main activity smali</value>
</data>
<data name="openApktoolYmlBtn.Text" xml:space="preserve">
<value>Apktool.yml</value>
</data>
<data name="openAndroidMainfestBtn.Text" xml:space="preserve">
<value>AndroidManifest.xml</value>
</data>
<data name="label4.Text" xml:space="preserve">
<value>APK File to sign:</value>
</data>
<data name="button_SIGN_BrowseInputFile.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="button_SIGN_Sign.Text" xml:space="preserve">
<value>Sign</value>
</data>
<data name="label3.Text" xml:space="preserve">
<value>APK file to align:</value>
</data>
<data name="button_ZIPALIGN_Align.Text" xml:space="preserve">
<value>Align</value>
</data>
<data name="button_ZIPALIGN_BrowseInputFile.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="label2.Text" xml:space="preserve">
<value>Decompiled APK folder:</value>
</data>
<data name="button_BUILD_BrowseInputProjectDir.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="button_BUILD_Build.Text" xml:space="preserve">
<value>Compile</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>APK/XAPK/APKS/ZIP/APKM File:</value>
</data>
<data name="button_DECODE_Decode.Text" xml:space="preserve">
<value>Decompile</value>
</data>
<data name="button_DECODE_BrowseInputAppPath.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="tabPageMain.Text" xml:space="preserve">
<value>Main</value>
</data>
<data name="sigTxtBox.Text" xml:space="preserve">
<value></value>
</data>
<data name="label5.Text" xml:space="preserve">
<value>Signature:</value>
</data>
<data name="label31.Text" xml:space="preserve">
<value>Launch activity:</value>
</data>
<data name="label30.Text" xml:space="preserve">
<value>Architectures:</value>
</data>
<data name="apkMirrorLinkBtn.Text" xml:space="preserve">
<value>Apk Mirror</value>
</data>
<data name="apkSupportLinkBtn.Text" xml:space="preserve">
<value>Apk.support</value>
</data>
<data name="apkGkLinkBtn.Text" xml:space="preserve">
<value>ApkGk</value>
</data>
<data name="label17.Text" xml:space="preserve">
<value>File:</value>
</data>
<data name="localsTxtBox.Text" xml:space="preserve">
<value></value>
</data>
<data name="selApkFileInfoBtn.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="label18.Text" xml:space="preserve">
<value>Locals: </value>
</data>
<data name="permTxtBox.Text" xml:space="preserve">
<value></value>
</data>
<data name="apkComboLinkBtn.Text" xml:space="preserve">
<value>ApkCombo</value>
</data>
<data name="label15.Text" xml:space="preserve">
<value>Permissions: </value>
</data>
<data name="label14.Text" xml:space="preserve">
<value>Densities: </value>
</data>
<data name="apkPureLinkBtn.Text" xml:space="preserve">
<value>ApkPure</value>
</data>
<data name="psLinkBtn.Text" xml:space="preserve">
<value>Play Store</value>
</data>
<data name="label19.Text" xml:space="preserve">
<value>Links:</value>
</data>
<data name="label7.Text" xml:space="preserve">
<value>App name:</value>
</data>
<data name="label9.Text" xml:space="preserve">
<value>Package name:</value>
</data>
<data name="label8.Text" xml:space="preserve">
<value>Version:</value>
</data>
<data name="label11.Text" xml:space="preserve">
<value>Min. SDK</value>
</data>
<data name="label10.Text" xml:space="preserve">
<value>Build:</value>
</data>
<data name="label13.Text" xml:space="preserve">
<value>Screen sizes: </value>
</data>
<data name="label12.Text" xml:space="preserve">
<value>Target SDK:</value>
</data>
<data name="basicInfoTabPage.Text" xml:space="preserve">
<value>Basic info</value>
</data>
<data name="fullInfoTextBox.Text" xml:space="preserve">
<value></value>
</data>
<data name="tabPageApkInfo.Text" xml:space="preserve">
<value>APK Info</value>
</data>
<data name="checkBox3.Text" xml:space="preserve">
<value>Set the number of threads to use.</value>
</data>
<data name="checkBox7.Text" xml:space="preserve">
<value>Don't parse APK info when selecting APK for decompiling</value>
</data>
<data name="decSetApiLvlChkBox.Text" xml:space="preserve">
<value>Set API level of the file to generate, e.g. 14 for ICS.</value>
</data>
<data name="checkBox_DECODE_FixError.Text" xml:space="preserve">
<value>Fix ApkTool errors after decompile</value>
</data>
<data name="checkBox_DECODE_OnlyMainClasses.Text" xml:space="preserve">
<value>Only disassemble the main dex classes (classes[0-9]*.dex) in the root. (&lt;2.12.1)</value>
</data>
<data name="button_DECODE_BrowseOutputDirectory.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="checkBox_DECODE_UseFramework.Text" xml:space="preserve">
<value>Uses framework files located in:</value>
</data>
<data name="button_DECODE_BrowseFrameDir.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="checkBox_DECODE_MatchOriginal.Text" xml:space="preserve">
<value>Keeps files to closest to original as possible. Prevents rebuild.</value>
</data>
<data name="checkBox_DECODE_OutputDirectory.Text" xml:space="preserve">
<value>Output directory:</value>
</data>
<data name="checkBox_DECODE_KeepBrokenRes.Text" xml:space="preserve">
<value>Keep broken resource.</value>
</data>
<data name="checkBox_DECODE_NoSrc.Text" xml:space="preserve">
<value>Do not decode sources.</value>
</data>
<data name="checkBox_DECODE_Force.Text" xml:space="preserve">
<value>Force delete destination directory.</value>
</data>
<data name="checkBox_DECODE_NoRes.Text" xml:space="preserve">
<value>Do not decode resources.</value>
</data>
<data name="checkBox_DECODE_NoDebugInfo.Text" xml:space="preserve">
<value>Don't write out debug info (.local, .param, .line, etc.)</value>
</data>
<data name="groupBox_DECODE_Options.Text" xml:space="preserve">
<value>Options</value>
</data>
<data name="tabPageDecode.Text" xml:space="preserve">
<value>Decode</value>
</data>
<data name="checkBox4.Text" xml:space="preserve">
<value>Set the number of threads to use.</value>
</data>
<data name="checkBox_BUILD_NetSecConf.Text" xml:space="preserve">
<value>Add a generic Network Security Configuration file in the output APK</value>
</data>
<data name="useAapt2ChkBox.Text" xml:space="preserve">
<value>Use aapt2 (Upgrades apktool to use experimental aapt2 binary.) (&lt; 2.11.1)</value>
</data>
<data name="buildSetApiLvlChkBox.Text" xml:space="preserve">
<value>Set API level of the file to generate, e.g. 14 for ICS.</value>
</data>
<data name="createUnsignApkChkBox.Text" xml:space="preserve">
<value>Create unsigned APK with original signature after build</value>
</data>
<data name="signAfterBuildChkBox.Text" xml:space="preserve">
<value>Sign after build / zipalign</value>
</data>
<data name="zipalignAfterBuildChkBox.Text" xml:space="preserve">
<value>Zipalign after build</value>
</data>
<data name="checkBox_BUILD_NoCrunch.Text" xml:space="preserve">
<value>Disable crunching of resource files during the build step.</value>
</data>
<data name="button_BUILD_BrowseOutputAppPath.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="checkBox_BUILD_ForceAll.Text" xml:space="preserve">
<value>Skip changes detection and build all files.</value>
</data>
<data name="button_BUILD_BrowseFrameDir.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="button_BUILD_BrowseAaptPath.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="checkBox_BUILD_OutputAppPath.Text" xml:space="preserve">
<value>APK output directory:</value>
</data>
<data name="checkBox_BUILD_CopyOriginal.Text" xml:space="preserve">
<value>Copy original AndroidManifest.xml and META-INF folder</value>
</data>
<data name="checkBox_BUILD_UseAapt.Text" xml:space="preserve">
<value>Uses aapt.exe located in:</value>
</data>
<data name="checkBox_BUILD_UseFramework.Text" xml:space="preserve">
<value>Uses framework files located in:</value>
</data>
<data name="groupBox_BUILD_Options.Text" xml:space="preserve">
<value>Options</value>
</data>
<data name="tabPageBuild.Text" xml:space="preserve">
<value>Build</value>
</data>
<data name="label23.Text" xml:space="preserve">
<value>Private key password:</value>
</data>
<data name="checkBox2.Text" xml:space="preserve">
<value>Install APK after signing (Make sure the device is selected in ADB tab first)</value>
</data>
<data name="checkBox1.Text" xml:space="preserve">
<value>Overwrite input file</value>
</data>
<data name="autoDelIdsigChkBox.Text" xml:space="preserve">
<value>Auto delete idsig file</value>
</data>
<data name="label27.Text" xml:space="preserve">
<value>Scheme v4:</value>
</data>
<data name="label26.Text" xml:space="preserve">
<value>Scheme v3:</value>
</data>
<data name="label25.Text" xml:space="preserve">
<value>Scheme v2:</value>
</data>
<data name="label24.Text" xml:space="preserve">
<value>Scheme v1:</value>
</data>
<data name="selectKeyStoreFileBtn.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="useAliasChkBox.Text" xml:space="preserve">
<value>Alias:</value>
</data>
<data name="label22.Text" xml:space="preserve">
<value>It is strongly recommended that you use your own key, created via Android Studio or other tools</value>
</data>
<data name="label21.Text" xml:space="preserve">
<value>Password:</value>
</data>
<data name="label20.Text" xml:space="preserve">
<value>keystore/jks file:</value>
</data>
<data name="useKeyStoreChkBox.Text" xml:space="preserve">
<value>Use keystore</value>
</data>
<data name="useSigningOutputDir.Text" xml:space="preserve">
<value>APK output directory:</value>
</data>
<data name="label_SIGN_PrivateKey.Text" xml:space="preserve">
<value>Private key:</value>
</data>
<data name="label_SIGN_PublicKey.Text" xml:space="preserve">
<value>Public key:</value>
</data>
<data name="button_SIGN_BrowseOutputFile.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="button_SIGN_BrowsePublicKey.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="button_SIGN_BrowsePrivateKey.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="groupBox_SIGN_Options.Text" xml:space="preserve">
<value>Options</value>
</data>
<data name="tabPageSign.Text" xml:space="preserve">
<value>Sign</value>
</data>
<data name="zipalignOutputDirChkBox.Text" xml:space="preserve">
<value>APK output directory:</value>
</data>
<data name="signAfterZipalignChkBox.Text" xml:space="preserve">
<value>Sign after zipalign</value>
</data>
<data name="checkBox_ZIPALIGN_Recompress.Text" xml:space="preserve">
<value>Recompress using Zopfli</value>
</data>
<data name="label_ZIPALIGN_AlignmentBytes.Text" xml:space="preserve">
<value>Alignment in bytes, e.g. '4' provides 32-bit alignment</value>
</data>
<data name="button_ZIPALIGN_BrowseOutputFile.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="checkBox_ZIPALIGN_CheckAlignment.Text" xml:space="preserve">
<value>Check alignment only (does not modify file)</value>
</data>
<data name="checkBox_ZIPALIGN_VerboseOutput.Text" xml:space="preserve">
<value>Verbose output</value>
</data>
<data name="checkBox_ZIPALIGN_OverwriteOutputFile.Text" xml:space="preserve">
<value>Overwrite existing output file</value>
</data>
<data name="groupBox_ZIPALIGN_Options.Text" xml:space="preserve">
<value>Options</value>
</data>
<data name="tabPageZipAlign.Text" xml:space="preserve">
<value>Zip align</value>
</data>
<data name="openFwFolderBtn.Text" xml:space="preserve">
<value>Open framework folder</value>
</data>
<data name="clearFwBtn.Text" xml:space="preserve">
<value>Clear framework</value>
</data>
<data name="clearFwBeforeDecodeChkBox.Text" xml:space="preserve">
<value>Clear framework before decompiling</value>
</data>
<data name="groupBox1.Text" xml:space="preserve">
<value>Options</value>
</data>
<data name="checkBox_IF_Tag.Text" xml:space="preserve">
<value>Tag frameworks using:</value>
</data>
<data name="checkBox_IF_FramePath.Text" xml:space="preserve">
<value>Stores framework files into:</value>
</data>
<data name="button_IF_InstallFramework.Text" xml:space="preserve">
<value>Install</value>
</data>
<data name="button_IF_BrowseFrameDir.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="button_IF_BrowseInputFramePath.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="groupBox_IF_Options.Text" xml:space="preserve">
<value>Install Framework</value>
</data>
<data name="tabPageInstallFramework.Text" xml:space="preserve">
<value>Framework</value>
</data>
<data name="label29.Text" xml:space="preserve">
<value>Smali folder to compile:</value>
</data>
<data name="smaliUseOutputChkBox.Text" xml:space="preserve">
<value>Dex output directory:</value>
</data>
<data name="comSmaliBtn.Text" xml:space="preserve">
<value>Compile</value>
</data>
<data name="smaliBrowseOutputBtn.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="smaliBrowseInputDirBtn.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="smaliGroupBox.Text" xml:space="preserve">
<value>Smali</value>
</data>
<data name="label28.Text" xml:space="preserve">
<value>Dex to decompile:</value>
</data>
<data name="baksmaliUseOutputChkBox.Text" xml:space="preserve">
<value>Folder output directory:</value>
</data>
<data name="baksmaliBrowseOutputBtn.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="decSmaliBtn.Text" xml:space="preserve">
<value>Decompile</value>
</data>
<data name="baksmaliBrowseInputDexBtn.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="bakSmaliGroupBox.Text" xml:space="preserve">
<value>Baksmali</value>
</data>
<data name="tabPageBaksmali.Text" xml:space="preserve">
<value>Baksmali</value>
</data>
<data name="label33.Text" xml:space="preserve">
<value>Selected device: </value>
</data>
<data name="killAdbBtn.Text" xml:space="preserve">
<value>Kill adb process</value>
</data>
<data name="installApkBtn.Text" xml:space="preserve">
<value>Install APK</value>
</data>
<data name="refreshDevicesBtn.Text" xml:space="preserve">
<value>Refresh</value>
</data>
<data name="selApkAdbBtn.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="overrideAbiCheckBox.Text" xml:space="preserve">
<value>Override platform's default ABI: </value>
</data>
<data name="setVendorChkBox.Text" xml:space="preserve">
<value>Set vendor to Play Store (com.android.vending)</value>
</data>
<data name="label32.Text" xml:space="preserve">
<value>Selected APK: </value>
</data>
<data name="tabPageAdb.Text" xml:space="preserve">
<value>ADB</value>
</data>
<data name="toolStripStatusLabelStateImage.Text" xml:space="preserve">
<value>toolStripStatusLabel1</value>
</data>
<data name="toolStripStatusLabelStateText.Text" xml:space="preserve">
<value>Loading...</value>
</data>
<data name="statusStrip1.Text" xml:space="preserve">
<value>statusStrip1</value>
</data>
<data name="copyToolStripMenuItem.Text" xml:space="preserve">
<value>Copy</value>
</data>
<data name="clearLogToolStripMenuItem.Text" xml:space="preserve">
<value>Clear log</value>
</data>
<data name="logTxtBox.Text" xml:space="preserve">
<value></value>
</data>
<data name="newInsToolStripMenuItem.Text" xml:space="preserve">
<value>New instance</value>
</data>
<data name="saveLogToFileToolStripMenuItem.Text" xml:space="preserve">
<value>Save log to file</value>
</data>
<data name="openTempFolderToolStripMenuItem.Text" xml:space="preserve">
<value>Open temp folder</value>
</data>
<data name="clearTempFolderToolStripMenuItem.Text" xml:space="preserve">
<value>Clear temp folder</value>
</data>
<data name="exitToolStripMenuItem.Text" xml:space="preserve">
<value>Exit</value>
</data>
<data name="fileToolStripMenuItem.Text" xml:space="preserve">
<value>File</value>
</data>
<data name="useAPKEditorForDecompilingItem.Text" xml:space="preserve">
<value>Use APKEditor for decompiling</value>
</data>
<data name="settingsToolStripMenuItem.Text" xml:space="preserve">
<value>Open settings...</value>
</data>
<data name="settingsToolStripMenuItem1.Text" xml:space="preserve">
<value>Settings</value>
</data>
<data name="checkForUpdateToolStripMenuItem.Text" xml:space="preserve">
<value>Check for update</value>
</data>
<data name="reportAnIsuueToolStripMenuItem.Text" xml:space="preserve">
<value>Report an issue</value>
</data>
<data name="apktoolIssuesToolStripMenuItem.Text" xml:space="preserve">
<value>Apktool issue tracker</value>
</data>
<data name="baksmaliIssuesToolStripMenuItem.Text" xml:space="preserve">
<value>Baksmali issue tracker</value>
</data>
<data name="aboutToolStripMenuItem.Text" xml:space="preserve">
<value>About</value>
</data>
<data name="helpToolStripMenuItem.Text" xml:space="preserve">
<value>Help</value>
</data>
<data name="menuStrip1.Text" xml:space="preserve">
<value>menuStrip1</value>
</data>
<data name="CopyAll" xml:space="preserve">
<value>Copy all</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading...</value>
</data>
<data name="Ready" xml:space="preserve">
<value>Ready</value>
</data>
<data name="SaveImageTitle" xml:space="preserve">
<value>Save an Image File</value>
</data>
<data name="PngImage" xml:space="preserve">
<value>PNG Image</value>
</data>
<data name="FilterAndroidPackage" xml:space="preserve">
<value>Android Package ({0})|{0}</value>
</data>
<data name="FilterSplitApk" xml:space="preserve">
<value>Split APK Package ({0})|{0}</value>
</data>
<data name="FilterApkJarZip" xml:space="preserve">
<value>APK / JAR / ZIP ({0})|{0}</value>
</data>
<data name="FilterKeystore" xml:space="preserve">
<value>Keystore ({0})|{0}</value>
</data>
<data name="FilterPublicKey" xml:space="preserve">
<value>Public key ({0})|{0}</value>
</data>
<data name="FilterPrivateKey" xml:space="preserve">
<value>Private key ({0})|{0}</value>
</data>
<data name="FilterApk" xml:space="preserve">
<value>APK ({0})|{0}</value>
</data>
<data name="FilterDex" xml:space="preserve">
<value>Dex ({0})|{0}</value>
</data>
<data name="FilterJavaExe" xml:space="preserve">
<value>Java ({0})|{0}</value>
</data>
<data name="FilterApktool" xml:space="preserve">
<value>Apktool ({0})|{0}</value>
</data>
<data name="SchemeDefault" xml:space="preserve">
<value>Default</value>
</data>
<data name="SchemeTrue" xml:space="preserve">
<value>True</value>
</data>
<data name="SchemeFalse" xml:space="preserve">
<value>False</value>
</data>
<data name="AaptDump" xml:space="preserve">
<value>AAPT dump</value>
</data>
</root>
+256 -1
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
@@ -543,4 +543,259 @@
<data name="SetLanguageRestartApplication" xml:space="preserve">
<value>Язык установлен. Хотите перезапустить программу?</value>
</data>
<data name="AboutVersion" xml:space="preserve">
<value>Версия</value>
</data>
<data name="AboutCopyright" xml:space="preserve">
<value>Авторские права</value>
</data>
<data name="AboutGithubRepo" xml:space="preserve">
<value>Сайт</value>
</data>
<data name="SettingsGeneral" xml:space="preserve">
<value>Общие</value>
</data>
<data name="SettingsLanguage" xml:space="preserve">
<value>Язык</value>
</data>
<data name="SettingsContextMenu" xml:space="preserve">
<value>Контекстное меню</value>
</data>
<data name="SettingsTheme" xml:space="preserve">
<value>Тема</value>
</data>
<data name="SettingsAdminRights" xml:space="preserve">
<value>Требуются права администратора</value>
</data>
<data name="SettingsClearLog" xml:space="preserve">
<value>Очищать журнал событий перед каждой операцией</value>
</data>
<data name="SettingsCustomJvmArgs" xml:space="preserve">
<value>Аргументы JVM</value>
</data>
<data name="SettingsCheckUpdate" xml:space="preserve">
<value>Проверять обновление при запуске (раз в сутки)</value>
</data>
<data name="SettingsCustomApktool" xml:space="preserve">
<value>Свой путь к Apktool</value>
</data>
<data name="SettingsInstall" xml:space="preserve">
<value>Установить</value>
</data>
<data name="SettingsUninstall" xml:space="preserve">
<value>Удалить</value>
</data>
<data name="SettingsCancel" xml:space="preserve">
<value>Отмена</value>
</data>
<data name="checkBox_DECODE_UseFramework.Text" xml:space="preserve">
<value>Использовать файлы фремворка из:</value>
</data>
<data name="checkBox_DECODE_Force.Text" xml:space="preserve">
<value>Перезаписывать файлы в каталоге назначения</value>
</data>
<data name="checkBox_DECODE_NoRes.Text" xml:space="preserve">
<value>Не декомпилировать ресурсы</value>
</data>
<data name="checkBox_DECODE_NoSrc.Text" xml:space="preserve">
<value>Не декомпилировать исходный код</value>
</data>
<data name="checkBox_BUILD_UseAapt.Text" xml:space="preserve">
<value>Использовать aapt.exe из</value>
</data>
<data name="checkBox_BUILD_ForceAll.Text" xml:space="preserve">
<value>Пропустить определение изменений и построить все файлы</value>
</data>
<data name="clearLogToolStripMenuItem.Text" xml:space="preserve">
<value>Очистить журнал</value>
</data>
<data name="menuItemSettings.Text" xml:space="preserve">
<value>Настройки</value>
</data>
<data name="menuItemExit.Text" xml:space="preserve">
<value>Выход</value>
</data>
<data name="menuItemFile.Text" xml:space="preserve">
<value>Файл</value>
</data>
<data name="menuItemCheckUpdate.Text" xml:space="preserve">
<value>Проверить обновление</value>
</data>
<data name="menuItemAbout.Text" xml:space="preserve">
<value>О программе</value>
</data>
<data name="menuItemHelp.Text" xml:space="preserve">
<value>Справка</value>
</data>
<data name="button_BUILD_Build.Text" xml:space="preserve">
<value>Собрать</value>
</data>
<data name="button_DECODE_Decode.Text" xml:space="preserve">
<value>Декомпилировать</value>
</data>
<data name="tabPageZipAlign.Text" xml:space="preserve">
<value>Выравнивание</value>
</data>
<data name="tabPageSign.Text" xml:space="preserve">
<value>Подпись</value>
</data>
<data name="toolStripStatusLabelStateText.Text" xml:space="preserve">
<value>Загрузка...</value>
</data>
<data name="checkBox_BUILD_CopyOriginal.Text" xml:space="preserve">
<value>Копировать оригинальный AndroidManifest.xml и папку META-INF в построенный apk</value>
</data>
<data name="checkBox_BUILD_UseFramework.Text" xml:space="preserve">
<value>Использовать файлы фремворка из:</value>
</data>
<data name="checkBox_DECODE_KeepBrokenRes.Text" xml:space="preserve">
<value>Сохранить испорченные ресурсы</value>
</data>
<data name="tabPageBuild.Text" xml:space="preserve">
<value>Сборка</value>
</data>
<data name="tabPageDecode.Text" xml:space="preserve">
<value>Декомпиляция</value>
</data>
<data name="checkBox_DECODE_OutputDirectory.Text" xml:space="preserve">
<value>Декомпилировать в каталог:</value>
</data>
<data name="checkBox_BUILD_OutputAppPath.Text" xml:space="preserve">
<value>Сохранить файл как:</value>
</data>
<data name="tabPageInstallFramework.Text" xml:space="preserve">
<value>Установка фреймворков</value>
</data>
<data name="groupBox_BUILD_Options.Text" xml:space="preserve">
<value>Опции</value>
</data>
<data name="groupBox_DECODE_Options.Text" xml:space="preserve">
<value>Опции</value>
</data>
<data name="groupBox_IF_Options.Text" xml:space="preserve">
<value>Опции</value>
</data>
<data name="button_IF_InstallFramework.Text" xml:space="preserve">
<value>Установить</value>
</data>
<data name="button_ZIPALIGN_Align.Text" xml:space="preserve">
<value>Выровнять</value>
</data>
<data name="label_ZIPALIGN_OutputFile.Text" xml:space="preserve">
<value>Сохранить файл как:</value>
</data>
<data name="groupBox_ZIPALIGN_Options.Text" xml:space="preserve">
<value>Опции</value>
</data>
<data name="checkBox_ZIPALIGN_OverwriteOutputFile.Text" xml:space="preserve">
<value>Перезаписать выходной файл, если он существует</value>
</data>
<data name="button_SIGN_Sign.Text" xml:space="preserve">
<value>Подписать</value>
</data>
<data name="checkBox_IF_FramePath.Text" xml:space="preserve">
<value>Устанавливать фреймворк в каталог:</value>
</data>
<data name="checkBox_ZIPALIGN_Recompress.Text" xml:space="preserve">
<value>Перепаковать с использованием алгоритма Zopfli</value>
</data>
<data name="checkBox_ZIPALIGN_VerboseOutput.Text" xml:space="preserve">
<value>Подробный вывод</value>
</data>
<data name="label_ZIPALIGN_AlignmentBytes.Text" xml:space="preserve">
<value>Выравнивание (в байтах), например, '4' для 32-битного выравнивания</value>
</data>
<data name="checkBox_DECODE_MatchOriginal.Text" xml:space="preserve">
<value>Сохранять файлы близко к оригиналу, насколько это возможно. Предотвращает ребилд.</value>
</data>
<data name="checkBox_ZIPALIGN_CheckAlignment.Text" xml:space="preserve">
<value>Только проверить выравнивание (не модифицирует файл)</value>
</data>
<data name="groupBox_SIGN_Options.Text" xml:space="preserve">
<value>Опции</value>
</data>
<data name="label_SIGN_OutputFile.Text" xml:space="preserve">
<value>Сохранить файл как:</value>
</data>
<data name="label_SIGN_PrivateKey.Text" xml:space="preserve">
<value>Закрытый ключ</value>
</data>
<data name="label_SIGN_PublicKey.Text" xml:space="preserve">
<value>Открытый ключ</value>
</data>
<data name="tabPageMain.Text" xml:space="preserve">
<value>Главная</value>
</data>
<data name="tabPageApkInfo.Text" xml:space="preserve">
<value>Инфо APK</value>
</data>
<data name="checkBox4.Text" xml:space="preserve">
<value>Количество потоков:</value>
</data>
<data name="checkBox_BUILD_NetSecConf.Text" xml:space="preserve">
<value>Добавить файл конфигурации сетевой безопасности (Network Security Configuration)</value>
</data>
<data name="useAapt2ChkBox.Text" xml:space="preserve">
<value>Использовать aapt2 (для версий apktool &lt; 2.11.1)</value>
</data>
<data name="buildSetApiLvlChkBox.Text" xml:space="preserve">
<value>Установить уровень API (напр. 14 для ICS)</value>
</data>
<data name="createUnsignApkChkBox.Text" xml:space="preserve">
<value>Создать неподписанный APK с оригинальной подписью (Core Patch)</value>
</data>
<data name="signAfterBuildChkBox.Text" xml:space="preserve">
<value>Подписать после сборки / выравнивания</value>
</data>
<data name="zipalignAfterBuildChkBox.Text" xml:space="preserve">
<value>Выровнять после сборки</value>
</data>
<data name="checkBox_BUILD_NoCrunch.Text" xml:space="preserve">
<value>Отключить сжатие ресурсов</value>
</data>
<data name="tabPageBaksmali.Text" xml:space="preserve">
<value>Baksmali / Smali</value>
</data>
<data name="tabPageAdb.Text" xml:space="preserve">
<value>ADB</value>
</data>
<data name="mergeApkBtn.Text" xml:space="preserve">
<value>Слияние APK</value>
</data>
<data name="selSplitApkBtn.Text" xml:space="preserve">
<value>Выбрать Split APK</value>
</data>
<data name="baksmaliUseOutputChkBox.Text" xml:space="preserve">
<value>Свой каталог вывода:</value>
</data>
<data name="smaliUseOutputChkBox.Text" xml:space="preserve">
<value>Свой каталог вывода:</value>
</data>
<data name="killAdbBtn.Text" xml:space="preserve">
<value>Перезапустить ADB</value>
</data>
<data name="installApkBtn.Text" xml:space="preserve">
<value>Установить APK</value>
</data>
<data name="refreshDevicesBtn.Text" xml:space="preserve">
<value>Обновить список</value>
</data>
<data name="selApkAdbBtn.Text" xml:space="preserve">
<value>Выбрать APK</value>
</data>
<data name="overrideAbiCheckBox.Text" xml:space="preserve">
<value>Переопределить ABI:</value>
</data>
<data name="bakSmaliGroupBox.Text" xml:space="preserve">
<value>Baksmali (DEX -&gt; Smali)</value>
</data>
<data name="smaliGroupBox.Text" xml:space="preserve">
<value>Smali (Smali -&gt; DEX)</value>
</data>
<data name="decSmaliBtn.Text" xml:space="preserve">
<value>Дизассемблировать</value>
</data>
<data name="comSmaliBtn.Text" xml:space="preserve">
<value>Ассемблировать</value>
</data>
</root>
+451 -1
View File
@@ -543,4 +543,454 @@
<data name="SetLanguageRestartApplication" xml:space="preserve">
<value />
</data>
</root>
<data name="AboutVersion" xml:space="preserve">
<value>Phiên bản</value>
</data>
<data name="AboutCopyright" xml:space="preserve">
<value>Bản quyền</value>
</data>
<data name="AboutGithubRepo" xml:space="preserve">
<value>Kho Github</value>
</data>
<data name="SettingsGeneral" xml:space="preserve">
<value>Chung</value>
</data>
<data name="SettingsLanguage" xml:space="preserve">
<value>Ngôn ngữ</value>
</data>
<data name="SettingsContextMenu" xml:space="preserve">
<value>Menu chuột phải</value>
</data>
<data name="SettingsTheme" xml:space="preserve">
<value>Giao diện</value>
</data>
<data name="SettingsTempNote" xml:space="preserve">
<value>Việc di chuyển các tệp trong quá trình xử lý vào thư mục tạm có thể mất thời gian, vui lòng kiên nhẫn chờ đợi</value>
</data>
<data name="SettingsAdminRights" xml:space="preserve">
<value>Yêu cầu quyền quản trị</value>
</data>
<data name="SettingsClearLog" xml:space="preserve">
<value>Xóa nhật ký trước khi thực hiện</value>
</data>
<data name="SettingsPlaySound" xml:space="preserve">
<value>Âm báo hoàn thành</value>
</data>
<data name="SettingsCustomTemp" xml:space="preserve">
<value>Vị trí bộ đệm tùy chỉnh</value>
</data>
<data name="SettingsCustomJava" xml:space="preserve">
<value>Vị trí Java tùy chỉnh</value>
</data>
<data name="SettingsUtf8" xml:space="preserve">
<value>Hỗ trợ tên tệp UTF-8 (bật khi tên tệp bị lỗi hiển thị)</value>
</data>
<data name="SettingsCustomJvmArgs" xml:space="preserve">
<value>Tùy chỉnh lệnh JVM</value>
</data>
<data name="SettingsCheckUpdate" xml:space="preserve">
<value>Kiểm tra cập nhật khi khởi động</value>
</data>
<data name="SettingsCustomApktool" xml:space="preserve">
<value>Vị trí apktool tùy chỉnh</value>
</data>
<data name="SettingsIgnoreOutputCM" xml:space="preserve">
<value>Bỏ qua thư mục đầu ra tùy chỉnh của menu chuột phải</value>
</data>
<data name="SettingsInstall" xml:space="preserve">
<value>Cài đặt</value>
</data>
<data name="SettingsUninstall" xml:space="preserve">
<value>Gỡ cài đặt</value>
</data>
<data name="SettingsCancel" xml:space="preserve">
<value>Hủy</value>
</data>
<data name="ThemeAuto" xml:space="preserve">
<value>Tự động</value>
</data>
<data name="ThemeLight" xml:space="preserve">
<value>Sáng</value>
</data>
<data name="ThemeDark" xml:space="preserve">
<value>Tối</value>
</data>
<data name="splitApkTxt.Text" xml:space="preserve">
<value>Hợp nhất các tệp APK bị chia nhỏ thành một tệp APK duy nhất:</value>
</data>
<data name="mergeApkBtn.Text" xml:space="preserve">
<value>Hợp nhất</value>
</data>
<data name="comApkOpenDir.Text" xml:space="preserve">
<value>Thư mục APK đã biên dịch</value>
</data>
<data name="decOutOpenDirBtn.Text" xml:space="preserve">
<value>Thư mục đầu ra dịch ngược</value>
</data>
<data name="signApkOpenDirBtn.Text" xml:space="preserve">
<value>Thư mục APK đã ký</value>
</data>
<data name="alignApkOpenDirBtn.Text" xml:space="preserve">
<value>Thư mục APK đã Zipalign</value>
</data>
<data name="decApkOpenDirBtn.Text" xml:space="preserve">
<value>Thư mục APK đã dịch ngược</value>
</data>
<data name="compileOutputOpenDirBtn.Text" xml:space="preserve">
<value>Thư mục đầu ra biên dịch</value>
</data>
<data name="button_OpenMainActivity.Text" xml:space="preserve">
<value>Smali của Activity khởi động</value>
</data>
<data name="label4.Text" xml:space="preserve">
<value>Ký APK:</value>
</data>
<data name="button_SIGN_Sign.Text" xml:space="preserve">
<value>Ký</value>
</data>
<data name="label3.Text" xml:space="preserve">
<value>Zipalign tệp APK:</value>
</data>
<data name="button_ZIPALIGN_Align.Text" xml:space="preserve">
<value>Zipalign</value>
</data>
<data name="label2.Text" xml:space="preserve">
<value>Thư mục APK đã dịch ngược:</value>
</data>
<data name="button_BUILD_Build.Text" xml:space="preserve">
<value>Biên dịch</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>Tệp APK/XAPK/APKS/ZIP/APKM:</value>
</data>
<data name="button_DECODE_Decode.Text" xml:space="preserve">
<value>Dịch ngược</value>
</data>
<data name="tabPageMain.Text" xml:space="preserve">
<value>Trang chính</value>
</data>
<data name="label31.Text" xml:space="preserve">
<value>Activity khởi động:</value>
</data>
<data name="label30.Text" xml:space="preserve">
<value>Kiến trúc:</value>
</data>
<data name="label17.Text" xml:space="preserve">
<value>Tệp:</value>
</data>
<data name="label18.Text" xml:space="preserve">
<value>Bản địa hóa:</value>
</data>
<data name="label15.Text" xml:space="preserve">
<value>Quyền:</value>
</data>
<data name="label14.Text" xml:space="preserve">
<value>Mật độ (DPI):</value>
</data>
<data name="label19.Text" xml:space="preserve">
<value>Liên kết cửa hàng:</value>
</data>
<data name="label7.Text" xml:space="preserve">
<value>Tên ứng dụng:</value>
</data>
<data name="label9.Text" xml:space="preserve">
<value>Tên gói ứng dụng:</value>
</data>
<data name="label8.Text" xml:space="preserve">
<value>Phiên bản:</value>
</data>
<data name="label11.Text" xml:space="preserve">
<value>SDK tương thích tối thiểu:</value>
</data>
<data name="label10.Text" xml:space="preserve">
<value>Tên mã:</value>
</data>
<data name="label13.Text" xml:space="preserve">
<value>Kích thước màn hình</value>
</data>
<data name="label12.Text" xml:space="preserve">
<value>SDK mục tiêu:</value>
</data>
<data name="basicInfoTabPage.Text" xml:space="preserve">
<value>Thông tin cơ bản</value>
</data>
<data name="tabPageApkInfo.Text" xml:space="preserve">
<value>Thông tin APK</value>
</data>
<data name="checkBox7.Text" xml:space="preserve">
<value>Không phân tích thông tin APK khi chọn APK để dịch ngược</value>
</data>
<data name="decSetApiLvlChkBox.Text" xml:space="preserve">
<value>Đặt cấp độ API cho các tệp sẽ được tạo, ví dụ: 14 cho ICS.</value>
</data>
<data name="checkBox_DECODE_FixError.Text" xml:space="preserve">
<value>Sửa lỗi ApkTool sau khi dịch ngược</value>
</data>
<data name="checkBox_DECODE_OnlyMainClasses.Text" xml:space="preserve">
<value>Chỉ dịch ngược các tệp dex chính trong thư mục gốc (classes[0-9]*.dex).</value>
</data>
<data name="checkBox_DECODE_UseFramework.Text" xml:space="preserve">
<value>Sử dụng vị trí tệp framework:</value>
</data>
<data name="checkBox_DECODE_MatchOriginal.Text" xml:space="preserve">
<value>Giữ các tệp gần với bản gốc nhất có thể, ngăn việc xây dựng lại</value>
</data>
<data name="checkBox_DECODE_OutputDirectory.Text" xml:space="preserve">
<value>Thư mục đầu ra:</value>
</data>
<data name="checkBox_DECODE_KeepBrokenRes.Text" xml:space="preserve">
<value>Giữ lại tài nguyên bị hỏng</value>
</data>
<data name="checkBox_DECODE_NoSrc.Text" xml:space="preserve">
<value>Không dịch ngược mã nguồn</value>
</data>
<data name="checkBox_DECODE_Force.Text" xml:space="preserve">
<value>Buộc xóa thư mục đích</value>
</data>
<data name="checkBox_DECODE_NoRes.Text" xml:space="preserve">
<value>Không dịch ngược tài nguyên (resources)</value>
</data>
<data name="checkBox_DECODE_NoDebugInfo.Text" xml:space="preserve">
<value>Không xuất thông tin gỡ lỗi (.local, .param, .line, v.v.)</value>
</data>
<data name="groupBox_DECODE_Options.Text" xml:space="preserve">
<value>Tùy chọn</value>
</data>
<data name="tabPageDecode.Text" xml:space="preserve">
<value>Dịch ngược</value>
</data>
<data name="checkBox_BUILD_NetSecConf.Text" xml:space="preserve">
<value>Thêm cấu hình bảo mật mạng chung vào APK đầu ra</value>
</data>
<data name="useAapt2ChkBox.Text" xml:space="preserve">
<value>Sử dụng aapt2 (Nâng cấp apktool để sử dụng tệp nhị phân aapt2 thử nghiệm)</value>
</data>
<data name="buildSetApiLvlChkBox.Text" xml:space="preserve">
<value>Đặt cấp độ API cho các tệp sẽ được tạo, ví dụ: 14 cho ICS.</value>
</data>
<data name="createUnsignApkChkBox.Text" xml:space="preserve">
<value>Tạo APK chưa ký với chữ ký gốc sau khi biên dịch</value>
</data>
<data name="signAfterBuildChkBox.Text" xml:space="preserve">
<value>Ký sau khi Biên dịch/Zipalign</value>
</data>
<data name="zipalignAfterBuildChkBox.Text" xml:space="preserve">
<value>Zipalign sau khi biên dịch</value>
</data>
<data name="checkBox_BUILD_NoCrunch.Text" xml:space="preserve">
<value>Vô hiệu hóa việc xử lý các tệp tài nguyên trong bước biên dịch</value>
</data>
<data name="checkBox_BUILD_ForceAll.Text" xml:space="preserve">
<value>Bỏ qua kiểm tra thay đổi và biên dịch tất cả các tệp</value>
</data>
<data name="checkBox_BUILD_OutputAppPath.Text" xml:space="preserve">
<value>Thư mục đầu ra APK</value>
</data>
<data name="checkBox_BUILD_CopyOriginal.Text" xml:space="preserve">
<value>Sao chép thư mục AndroidManifest.xml và META-INF gốc</value>
</data>
<data name="checkBox_BUILD_UseAapt.Text" xml:space="preserve">
<value>Sử dụng vị trí tệp aapt.exe:</value>
</data>
<data name="checkBox_BUILD_UseFramework.Text" xml:space="preserve">
<value>Sử dụng vị trí tệp framework:</value>
</data>
<data name="groupBox_BUILD_Options.Text" xml:space="preserve">
<value>Tùy chọn</value>
</data>
<data name="tabPageBuild.Text" xml:space="preserve">
<value>Biên dịch</value>
</data>
<data name="checkBox2.Text" xml:space="preserve">
<value>Cài đặt APK sau khi ký (đảm bảo đã chọn thiết bị trong tùy chọn ADB trước)</value>
</data>
<data name="checkBox1.Text" xml:space="preserve">
<value>Ghi đè tệp đầu vào</value>
</data>
<data name="autoDelIdsigChkBox.Text" xml:space="preserve">
<value>Tự động xóa tệp idsig</value>
</data>
<data name="label27.Text" xml:space="preserve">
<value>Lược đồ ký v4:</value>
</data>
<data name="label26.Text" xml:space="preserve">
<value>Lược đồ ký v3:</value>
</data>
<data name="label25.Text" xml:space="preserve">
<value>Lược đồ ký v2:</value>
</data>
<data name="label24.Text" xml:space="preserve">
<value>Lược đồ ký v1:</value>
</data>
<data name="useAliasChkBox.Text" xml:space="preserve">
<value>Tên bí danh (Alias)</value>
</data>
<data name="label22.Text" xml:space="preserve">
<value>Rất khuyến khích bạn sử dụng khóa của riêng mình, được tạo bằng Android Studio hoặc các công cụ khác</value>
</data>
<data name="label21.Text" xml:space="preserve">
<value>Mật khẩu:</value>
</data>
<data name="label20.Text" xml:space="preserve">
<value>Tệp keystore/jks:</value>
</data>
<data name="useKeyStoreChkBox.Text" xml:space="preserve">
<value>Sử dụng keystore</value>
</data>
<data name="useSigningOutputDir.Text" xml:space="preserve">
<value>Thư mục đầu ra APK:</value>
</data>
<data name="label_SIGN_PrivateKey.Text" xml:space="preserve">
<value>Khóa riêng:</value>
</data>
<data name="label_SIGN_PublicKey.Text" xml:space="preserve">
<value>Khóa công khai:</value>
</data>
<data name="groupBox_SIGN_Options.Text" xml:space="preserve">
<value>Tùy chọn</value>
</data>
<data name="tabPageSign.Text" xml:space="preserve">
<value>Ký</value>
</data>
<data name="zipalignOutputDirChkBox.Text" xml:space="preserve">
<value>Thư mục đầu ra APK:</value>
</data>
<data name="signAfterZipalignChkBox.Text" xml:space="preserve">
<value>Ký sau khi zipalign</value>
</data>
<data name="checkBox_ZIPALIGN_Recompress.Text" xml:space="preserve">
<value>Nén lại bằng Zopfli</value>
</data>
<data name="label_ZIPALIGN_AlignmentBytes.Text" xml:space="preserve">
<value>Căn chỉnh theo byte, ví dụ: '4' cung cấp căn chỉnh 32-bit</value>
</data>
<data name="checkBox_ZIPALIGN_CheckAlignment.Text" xml:space="preserve">
<value>Chỉ kiểm tra căn chỉnh (không sửa đổi tệp)</value>
</data>
<data name="checkBox_ZIPALIGN_VerboseOutput.Text" xml:space="preserve">
<value>Đầu ra chi tiết</value>
</data>
<data name="checkBox_ZIPALIGN_OverwriteOutputFile.Text" xml:space="preserve">
<value>Ghi đè tệp đầu ra hiện có</value>
</data>
<data name="groupBox_ZIPALIGN_Options.Text" xml:space="preserve">
<value>Tùy chọn</value>
</data>
<data name="tabPageZipAlign.Text" xml:space="preserve">
<value>Zipalign</value>
</data>
<data name="openFwFolderBtn.Text" xml:space="preserve">
<value>Mở thư mục framework</value>
</data>
<data name="clearFwBtn.Text" xml:space="preserve">
<value>Xóa bộ nhớ đệm framework</value>
</data>
<data name="clearFwBeforeDecodeChkBox.Text" xml:space="preserve">
<value>Xóa bộ nhớ đệm Framework trước khi dịch ngược</value>
</data>
<data name="groupBox1.Text" xml:space="preserve">
<value>Tùy chọn</value>
</data>
<data name="checkBox_IF_Tag.Text" xml:space="preserve">
<value>Gắn thẻ frameworks bằng:</value>
</data>
<data name="checkBox_IF_FramePath.Text" xml:space="preserve">
<value>Lưu trữ tệp framework vào:</value>
</data>
<data name="button_IF_InstallFramework.Text" xml:space="preserve">
<value>Cài đặt</value>
</data>
<data name="groupBox_IF_Options.Text" xml:space="preserve">
<value>Tùy chọn</value>
</data>
<data name="label29.Text" xml:space="preserve">
<value>Thư mục biên dịch Smali:</value>
</data>
<data name="smaliUseOutputChkBox.Text" xml:space="preserve">
<value>Thư mục đầu ra Dex:</value>
</data>
<data name="comSmaliBtn.Text" xml:space="preserve">
<value>Biên dịch</value>
</data>
<data name="label28.Text" xml:space="preserve">
<value>Dịch ngược Dex:</value>
</data>
<data name="baksmaliUseOutputChkBox.Text" xml:space="preserve">
<value>Thư mục đầu ra:</value>
</data>
<data name="decSmaliBtn.Text" xml:space="preserve">
<value>Dịch ngược</value>
</data>
<data name="label33.Text" xml:space="preserve">
<value>Chọn thiết bị</value>
</data>
<data name="killAdbBtn.Text" xml:space="preserve">
<value>Dừng tiến trình ADB</value>
</data>
<data name="installApkBtn.Text" xml:space="preserve">
<value>Cài đặt APK</value>
</data>
<data name="refreshDevicesBtn.Text" xml:space="preserve">
<value>Làm mới</value>
</data>
<data name="overrideAbiCheckBox.Text" xml:space="preserve">
<value>Ghi đè ABI mặc định của nền tảng:</value>
</data>
<data name="setVendorChkBox.Text" xml:space="preserve">
<value>Đặt nhà cung cấp là Play Store (com.android.vending)</value>
</data>
<data name="label32.Text" xml:space="preserve">
<value>Chọn APK: </value>
</data>
<data name="toolStripStatusLabelStateText.Text" xml:space="preserve">
<value>Đang tải...</value>
</data>
<data name="clearLogToolStripMenuItem.Text" xml:space="preserve">
<value>Xóa nhật ký</value>
</data>
<data name="newInsToolStripMenuItem.Text" xml:space="preserve">
<value>Tiến trình mới</value>
</data>
<data name="saveLogToFileToolStripMenuItem.Text" xml:space="preserve">
<value>Lưu nhật ký</value>
</data>
<data name="openTempFolderToolStripMenuItem.Text" xml:space="preserve">
<value>Mở thư mục tạm</value>
</data>
<data name="clearTempFolderToolStripMenuItem.Text" xml:space="preserve">
<value>Xóa thư mục tạm</value>
</data>
<data name="exitToolStripMenuItem.Text" xml:space="preserve">
<value>Thoát</value>
</data>
<data name="fileToolStripMenuItem.Text" xml:space="preserve">
<value>Tệp</value>
</data>
<data name="useAPKEditorForDecompilingItem.Text" xml:space="preserve">
<value>Sử dụng APKEditor để dịch ngược</value>
</data>
<data name="settingsToolStripMenuItem.Text" xml:space="preserve">
<value>Cài đặt</value>
</data>
<data name="checkForUpdateToolStripMenuItem.Text" xml:space="preserve">
<value>Kiểm tra cập nhật</value>
</data>
<data name="reportAnIsuueToolStripMenuItem.Text" xml:space="preserve">
<value>Báo cáo sự cố</value>
</data>
<data name="apktoolIssuesToolStripMenuItem.Text" xml:space="preserve">
<value>Sự cố Apktool</value>
</data>
<data name="baksmaliIssuesToolStripMenuItem.Text" xml:space="preserve">
<value>Sự cố Baksmali</value>
</data>
<data name="aboutToolStripMenuItem.Text" xml:space="preserve">
<value>Giới thiệu</value>
</data>
<data name="helpToolStripMenuItem.Text" xml:space="preserve">
<value>Trợ giúp</value>
</data>
<data name="checkBox_DECODE_UseApkEditorMerge.Text" xml:space="preserve">
<value>Sử dụng APKEditor.jar để hợp nhất/tách APK (nhanh hơn)</value>
</data>
</root>
+451 -1
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
@@ -540,4 +540,454 @@
<data name="CantDetectApkeditorVersion" xml:space="preserve">
<value>无法检测 APKEditor 版本</value>
</data>
<data name="AboutVersion" xml:space="preserve">
<value>版本</value>
</data>
<data name="AboutCopyright" xml:space="preserve">
<value>版权</value>
</data>
<data name="AboutGithubRepo" xml:space="preserve">
<value>Github 仓库</value>
</data>
<data name="SettingsGeneral" xml:space="preserve">
<value>常规</value>
</data>
<data name="SettingsLanguage" xml:space="preserve">
<value>语言</value>
</data>
<data name="SettingsContextMenu" xml:space="preserve">
<value>右键菜单</value>
</data>
<data name="SettingsTheme" xml:space="preserve">
<value>主题</value>
</data>
<data name="SettingsTempNote" xml:space="preserve">
<value>操作过程的文件移动到缓存目录中需要时间,请耐心等待</value>
</data>
<data name="SettingsAdminRights" xml:space="preserve">
<value>需要管理员权限</value>
</data>
<data name="SettingsClearLog" xml:space="preserve">
<value>操作前清除日志</value>
</data>
<data name="SettingsPlaySound" xml:space="preserve">
<value>完成提示音</value>
</data>
<data name="SettingsCustomTemp" xml:space="preserve">
<value>自定义缓存位置</value>
</data>
<data name="SettingsCustomJava" xml:space="preserve">
<value>自定义 Java 位置</value>
</data>
<data name="SettingsUtf8" xml:space="preserve">
<value>UTF-8 文件名支持,中文乱码开启</value>
</data>
<data name="SettingsCustomJvmArgs" xml:space="preserve">
<value>自定义 JVM 命令</value>
</data>
<data name="SettingsCheckUpdate" xml:space="preserve">
<value>启动时检查更新</value>
</data>
<data name="SettingsCustomApktool" xml:space="preserve">
<value>自定义 apktool 位置</value>
</data>
<data name="SettingsIgnoreOutputCM" xml:space="preserve">
<value>忽略右键菜单的自定义输出目录</value>
</data>
<data name="SettingsInstall" xml:space="preserve">
<value>安装</value>
</data>
<data name="SettingsUninstall" xml:space="preserve">
<value>卸载</value>
</data>
<data name="SettingsCancel" xml:space="preserve">
<value>取消</value>
</data>
<data name="ThemeAuto" xml:space="preserve">
<value>自动</value>
</data>
<data name="ThemeLight" xml:space="preserve">
<value>浅色</value>
</data>
<data name="ThemeDark" xml:space="preserve">
<value>深色</value>
</data>
<data name="splitApkTxt.Text" xml:space="preserve">
<value>将拆分的 APK 合并为单个 APK:</value>
</data>
<data name="mergeApkBtn.Text" xml:space="preserve">
<value>合并</value>
</data>
<data name="comApkOpenDir.Text" xml:space="preserve">
<value>编译的 APK 目录</value>
</data>
<data name="decOutOpenDirBtn.Text" xml:space="preserve">
<value>反编译输出目录</value>
</data>
<data name="signApkOpenDirBtn.Text" xml:space="preserve">
<value>签名的 APK 目录</value>
</data>
<data name="alignApkOpenDirBtn.Text" xml:space="preserve">
<value>Zip 对齐的 APK 目录</value>
</data>
<data name="decApkOpenDirBtn.Text" xml:space="preserve">
<value>反编译的 APK 目录</value>
</data>
<data name="compileOutputOpenDirBtn.Text" xml:space="preserve">
<value>编译输出目录</value>
</data>
<data name="button_OpenMainActivity.Text" xml:space="preserve">
<value>启动项 smail</value>
</data>
<data name="label4.Text" xml:space="preserve">
<value>APK 签名:</value>
</data>
<data name="button_SIGN_Sign.Text" xml:space="preserve">
<value>签名</value>
</data>
<data name="label3.Text" xml:space="preserve">
<value>APK 文件对齐优化:</value>
</data>
<data name="button_ZIPALIGN_Align.Text" xml:space="preserve">
<value>对齐优化</value>
</data>
<data name="label2.Text" xml:space="preserve">
<value>反编译 APK 目录:</value>
</data>
<data name="button_BUILD_Build.Text" xml:space="preserve">
<value>编译</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>APK/XAPK/APKS/ZIP/APKM 文件:</value>
</data>
<data name="button_DECODE_Decode.Text" xml:space="preserve">
<value>反编译</value>
</data>
<data name="tabPageMain.Text" xml:space="preserve">
<value>首页</value>
</data>
<data name="label31.Text" xml:space="preserve">
<value>启动 activity:</value>
</data>
<data name="label30.Text" xml:space="preserve">
<value>架构:</value>
</data>
<data name="label17.Text" xml:space="preserve">
<value>文件:</value>
</data>
<data name="label18.Text" xml:space="preserve">
<value>本地化:</value>
</data>
<data name="label15.Text" xml:space="preserve">
<value>权限:</value>
</data>
<data name="label14.Text" xml:space="preserve">
<value>密度:</value>
</data>
<data name="label19.Text" xml:space="preserve">
<value>商店链接:</value>
</data>
<data name="label7.Text" xml:space="preserve">
<value>应用名:</value>
</data>
<data name="label9.Text" xml:space="preserve">
<value>应用包名:</value>
</data>
<data name="label8.Text" xml:space="preserve">
<value>版本:</value>
</data>
<data name="label11.Text" xml:space="preserve">
<value>最小兼容 SDK:</value>
</data>
<data name="label10.Text" xml:space="preserve">
<value>代号:</value>
</data>
<data name="label13.Text" xml:space="preserve">
<value>屏幕尺寸</value>
</data>
<data name="label12.Text" xml:space="preserve">
<value>目标 SDK:</value>
</data>
<data name="basicInfoTabPage.Text" xml:space="preserve">
<value>基本信息</value>
</data>
<data name="tabPageApkInfo.Text" xml:space="preserve">
<value>APK 信息</value>
</data>
<data name="checkBox7.Text" xml:space="preserve">
<value>在选择 APK 进行反编译时,不要解析 APK 信息</value>
</data>
<data name="decSetApiLvlChkBox.Text" xml:space="preserve">
<value>设置要生成的文件的 API 级别,例如 ICS 的 14。</value>
</data>
<data name="checkBox_DECODE_FixError.Text" xml:space="preserve">
<value>修复反编译后的 ApkTool 错误</value>
</data>
<data name="checkBox_DECODE_OnlyMainClasses.Text" xml:space="preserve">
<value>只反汇编根目录中的主索引类(classes[0-9]*.dex)。</value>
</data>
<data name="checkBox_DECODE_UseFramework.Text" xml:space="preserve">
<value>使用的 framework 文件位置:</value>
</data>
<data name="checkBox_DECODE_MatchOriginal.Text" xml:space="preserve">
<value>尽可能保持文件最接近原始,防止重建</value>
</data>
<data name="checkBox_DECODE_OutputDirectory.Text" xml:space="preserve">
<value>输出目录:</value>
</data>
<data name="checkBox_DECODE_KeepBrokenRes.Text" xml:space="preserve">
<value>保留损坏资源</value>
</data>
<data name="checkBox_DECODE_NoSrc.Text" xml:space="preserve">
<value>不反编译源码</value>
</data>
<data name="checkBox_DECODE_Force.Text" xml:space="preserve">
<value>强制删除目标目录</value>
</data>
<data name="checkBox_DECODE_NoRes.Text" xml:space="preserve">
<value>不反编译 resouces</value>
</data>
<data name="checkBox_DECODE_NoDebugInfo.Text" xml:space="preserve">
<value>不要输出调试信息(.Local, .param, .line等)</value>
</data>
<data name="groupBox_DECODE_Options.Text" xml:space="preserve">
<value>选项</value>
</data>
<data name="tabPageDecode.Text" xml:space="preserve">
<value>反编译</value>
</data>
<data name="checkBox_BUILD_NetSecConf.Text" xml:space="preserve">
<value>在输出 APK 中添加通用的网络安全配置文件</value>
</data>
<data name="useAapt2ChkBox.Text" xml:space="preserve">
<value>使用 aapt2(升级 apktool 使用实验性 aapt2 二进制)</value>
</data>
<data name="buildSetApiLvlChkBox.Text" xml:space="preserve">
<value>设置要生成的文件的 API 级别,例如 ICS 的 14。</value>
</data>
<data name="createUnsignApkChkBox.Text" xml:space="preserve">
<value>构建后创建具有原始签名的未签名 APK</value>
</data>
<data name="signAfterBuildChkBox.Text" xml:space="preserve">
<value>在 构建/zip对齐 后进行签名</value>
</data>
<data name="zipalignAfterBuildChkBox.Text" xml:space="preserve">
<value>在构建后进行 zip对齐</value>
</data>
<data name="checkBox_BUILD_NoCrunch.Text" xml:space="preserve">
<value>在构建步骤中禁用对 resource 文件的处理</value>
</data>
<data name="checkBox_BUILD_ForceAll.Text" xml:space="preserve">
<value>跳过变更检测并构建所有文件</value>
</data>
<data name="checkBox_BUILD_OutputAppPath.Text" xml:space="preserve">
<value>APK 输出目录</value>
</data>
<data name="checkBox_BUILD_CopyOriginal.Text" xml:space="preserve">
<value>复制原来的 AndroidManifest.xml 和 META-INF 文件夹</value>
</data>
<data name="checkBox_BUILD_UseAapt.Text" xml:space="preserve">
<value>使用的 aapt.exe 文件位置:</value>
</data>
<data name="checkBox_BUILD_UseFramework.Text" xml:space="preserve">
<value>使用的 framework 文件位置:</value>
</data>
<data name="groupBox_BUILD_Options.Text" xml:space="preserve">
<value>选项</value>
</data>
<data name="tabPageBuild.Text" xml:space="preserve">
<value>构建</value>
</data>
<data name="checkBox2.Text" xml:space="preserve">
<value>签名后安装 APK(确保首先在 ADB 选项中选择设备)</value>
</data>
<data name="checkBox1.Text" xml:space="preserve">
<value>覆盖输入文件</value>
</data>
<data name="autoDelIdsigChkBox.Text" xml:space="preserve">
<value>自动删除 idsig 文件</value>
</data>
<data name="label27.Text" xml:space="preserve">
<value>签名方案 v4:</value>
</data>
<data name="label26.Text" xml:space="preserve">
<value>签名方案 v3:</value>
</data>
<data name="label25.Text" xml:space="preserve">
<value>签名方案 v2:</value>
</data>
<data name="label24.Text" xml:space="preserve">
<value>签名方案 v1:</value>
</data>
<data name="useAliasChkBox.Text" xml:space="preserve">
<value>别名</value>
</data>
<data name="label22.Text" xml:space="preserve">
<value>强烈建议您使用自己的密钥,通过 Android Studio 或其他工具创建</value>
</data>
<data name="label21.Text" xml:space="preserve">
<value>密码:</value>
</data>
<data name="label20.Text" xml:space="preserve">
<value>keystore/jks 文件:</value>
</data>
<data name="useKeyStoreChkBox.Text" xml:space="preserve">
<value>使用 keystore</value>
</data>
<data name="useSigningOutputDir.Text" xml:space="preserve">
<value>APK 输出目录:</value>
</data>
<data name="label_SIGN_PrivateKey.Text" xml:space="preserve">
<value>私钥:</value>
</data>
<data name="label_SIGN_PublicKey.Text" xml:space="preserve">
<value>公钥:</value>
</data>
<data name="groupBox_SIGN_Options.Text" xml:space="preserve">
<value>选项</value>
</data>
<data name="tabPageSign.Text" xml:space="preserve">
<value>签名</value>
</data>
<data name="zipalignOutputDirChkBox.Text" xml:space="preserve">
<value>APK 输出目录:</value>
</data>
<data name="signAfterZipalignChkBox.Text" xml:space="preserve">
<value>zip对齐后进行签名</value>
</data>
<data name="checkBox_ZIPALIGN_Recompress.Text" xml:space="preserve">
<value>使用 Zopfli 重新压缩</value>
</data>
<data name="label_ZIPALIGN_AlignmentBytes.Text" xml:space="preserve">
<value>以 bytes 为单位的对齐,例如: '4' 提供 32-bit 对齐</value>
</data>
<data name="checkBox_ZIPALIGN_CheckAlignment.Text" xml:space="preserve">
<value>只检查对齐(不修改文件)</value>
</data>
<data name="checkBox_ZIPALIGN_VerboseOutput.Text" xml:space="preserve">
<value>详细输出</value>
</data>
<data name="checkBox_ZIPALIGN_OverwriteOutputFile.Text" xml:space="preserve">
<value>覆盖现有的输出文件</value>
</data>
<data name="groupBox_ZIPALIGN_Options.Text" xml:space="preserve">
<value>选项</value>
</data>
<data name="tabPageZipAlign.Text" xml:space="preserve">
<value>Zip对齐</value>
</data>
<data name="openFwFolderBtn.Text" xml:space="preserve">
<value>打开 framework 目录</value>
</data>
<data name="clearFwBtn.Text" xml:space="preserve">
<value>清空 framework 缓存</value>
</data>
<data name="clearFwBeforeDecodeChkBox.Text" xml:space="preserve">
<value>反编译前清空 Framework 缓存</value>
</data>
<data name="groupBox1.Text" xml:space="preserve">
<value>选项</value>
</data>
<data name="checkBox_IF_Tag.Text" xml:space="preserve">
<value>标签 frameworks 使用:</value>
</data>
<data name="checkBox_IF_FramePath.Text" xml:space="preserve">
<value>将 framework 文件存储到:</value>
</data>
<data name="button_IF_InstallFramework.Text" xml:space="preserve">
<value>安装</value>
</data>
<data name="groupBox_IF_Options.Text" xml:space="preserve">
<value>选项</value>
</data>
<data name="label29.Text" xml:space="preserve">
<value>Smali 编译目录:</value>
</data>
<data name="smaliUseOutputChkBox.Text" xml:space="preserve">
<value>Dex 输出目录:</value>
</data>
<data name="comSmaliBtn.Text" xml:space="preserve">
<value>编译</value>
</data>
<data name="label28.Text" xml:space="preserve">
<value>Dex 反编译:</value>
</data>
<data name="baksmaliUseOutputChkBox.Text" xml:space="preserve">
<value>输出目录:</value>
</data>
<data name="decSmaliBtn.Text" xml:space="preserve">
<value>反编译</value>
</data>
<data name="label33.Text" xml:space="preserve">
<value>选择设备</value>
</data>
<data name="killAdbBtn.Text" xml:space="preserve">
<value>结束 ADB 进程</value>
</data>
<data name="installApkBtn.Text" xml:space="preserve">
<value>安装 APK</value>
</data>
<data name="refreshDevicesBtn.Text" xml:space="preserve">
<value>刷新</value>
</data>
<data name="overrideAbiCheckBox.Text" xml:space="preserve">
<value>覆盖平台的默认 ABI:</value>
</data>
<data name="setVendorChkBox.Text" xml:space="preserve">
<value>设置 vendor 为 Play Store (com.android.vending)</value>
</data>
<data name="label32.Text" xml:space="preserve">
<value>选择 APK: </value>
</data>
<data name="toolStripStatusLabelStateText.Text" xml:space="preserve">
<value>加载中...</value>
</data>
<data name="clearLogToolStripMenuItem.Text" xml:space="preserve">
<value>清除日志</value>
</data>
<data name="newInsToolStripMenuItem.Text" xml:space="preserve">
<value>新进程</value>
</data>
<data name="saveLogToFileToolStripMenuItem.Text" xml:space="preserve">
<value>保存日志</value>
</data>
<data name="openTempFolderToolStripMenuItem.Text" xml:space="preserve">
<value>打开缓存目录</value>
</data>
<data name="clearTempFolderToolStripMenuItem.Text" xml:space="preserve">
<value>清空缓存目录</value>
</data>
<data name="exitToolStripMenuItem.Text" xml:space="preserve">
<value>退出</value>
</data>
<data name="fileToolStripMenuItem.Text" xml:space="preserve">
<value>文件</value>
</data>
<data name="useAPKEditorForDecompilingItem.Text" xml:space="preserve">
<value>使用 APKEditor 进行反编译</value>
</data>
<data name="settingsToolStripMenuItem.Text" xml:space="preserve">
<value>设置</value>
</data>
<data name="checkForUpdateToolStripMenuItem.Text" xml:space="preserve">
<value>检查更新</value>
</data>
<data name="reportAnIsuueToolStripMenuItem.Text" xml:space="preserve">
<value>反馈问题</value>
</data>
<data name="apktoolIssuesToolStripMenuItem.Text" xml:space="preserve">
<value>Apktool 问题反馈</value>
</data>
<data name="baksmaliIssuesToolStripMenuItem.Text" xml:space="preserve">
<value>Baksmail 问题反馈</value>
</data>
<data name="aboutToolStripMenuItem.Text" xml:space="preserve">
<value>关于</value>
</data>
<data name="helpToolStripMenuItem.Text" xml:space="preserve">
<value>帮助</value>
</data>
<data name="checkBox_DECODE_UseApkEditorMerge.Text" xml:space="preserve">
<value>使用 APKEditor.jar 合并、分离 APK(速度更快)</value>
</data>
</root>
+9 -12
View File
@@ -1,8 +1,8 @@
using APKToolGUI.Languages;
using APKToolGUI.Controls;
using APKToolGUI.Languages;
using APKToolGUI.Properties;
using APKToolGUI.Utils;
using Bluegrams.Application;
using Dark.Net;
using OSVersionExtension;
using System;
using System.Collections.Generic;
@@ -96,16 +96,13 @@ namespace APKToolGUI
TEMP_MAIN = TempDirectory();
Directory.CreateDirectory(TEMP_PATH);
Theme theme = (Theme)Settings.Default.Theme;
if (IsWin10OrAbove())
DarkNet.Instance.SetCurrentProcessTheme(theme);
// Set the process app mode before any window is created so that
// Win32 popup/context menus render dark too. The WPF MainWindow
// applies its own immersive dark title bar internally.
NativeDarkMode.SetProcessTheme((Theme)Settings.Default.Theme);
Form mainForm = new FormMain();
if (IsWin10OrAbove())
DarkNet.Instance.SetWindowThemeForms(mainForm, theme);
Application.Run(mainForm);
var app = new System.Windows.Application();
app.Run(new Forms.MainWindow());
}
}
}
@@ -126,7 +123,7 @@ namespace APKToolGUI
public static bool IsDarkTheme()
{
if (IsWin10OrAbove())
return DarkNet.Instance.EffectiveCurrentProcessThemeIsDark;
return NativeDarkMode.EffectiveIsDark((Theme)Settings.Default.Theme);
else if (Settings.Default.Theme == 2)
return true;
return false;
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("3.3.2.1")]
[assembly: AssemblyFileVersion("3.3.2.1")]
[assembly: AssemblyVersion("3.3.2.3")]
[assembly: AssemblyFileVersion("3.3.2.3")]
+13 -15
View File
@@ -12,7 +12,7 @@ namespace APKToolGUI.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.14.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "18.6.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
@@ -770,20 +770,6 @@ namespace APKToolGUI.Properties {
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Bluegrams.Application.PortableSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
[global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)]
public string Sign_KeyPassword {
get {
return ((string)(this["Sign_KeyPassword"]));
}
set {
this["Sign_KeyPassword"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Bluegrams.Application.PortableSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -1388,5 +1374,17 @@ namespace APKToolGUI.Properties {
this["Build_SetJobs"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string Sign_KeyPassword {
get {
return ((string)(this["Sign_KeyPassword"]));
}
set {
this["Sign_KeyPassword"] = value;
}
}
}
}
+3
View File
@@ -296,5 +296,8 @@
<Setting Name="Build_SetJobs" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="Sign_KeyPassword" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings>
</SettingsFile>
+513
View File
@@ -0,0 +1,513 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ctrl="clr-namespace:APKToolGUI.Controls">
<!--
Shared implicit styles giving the common WPF controls a dark/light look.
Colours come from DynamicResource brushes filled in by Controls/WpfTheme.cs.
Merge this dictionary into a window, then call WpfTheme.Apply(this, dark).
Reused across the staged WinForms->WPF conversion (AboutWindow, SettingsWindow, ...).
-->
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
</Style>
<Style TargetType="Label">
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="Background" Value="{DynamicResource PanelBackground}"/>
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
<Setter Property="BorderBrush" Value="{DynamicResource PanelBorder}"/>
<Setter Property="CaretBrush" Value="{DynamicResource PrimaryText}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="3,2"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
</Style>
<!-- Flat button that looks right in both themes (no light-blue Aero hover). -->
<Style TargetType="Button">
<Setter Property="Background" Value="{DynamicResource ButtonBackground}"/>
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
<Setter Property="BorderBrush" Value="{DynamicResource ButtonBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="10,4"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"
Margin="{TemplateBinding Padding}" RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="Background" Value="{DynamicResource ButtonHover}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="border" Property="Background" Value="{DynamicResource ButtonPressed}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="border" Property="Opacity" Value="0.5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="CheckBox">
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
<Setter Property="Background" Value="{DynamicResource ControlBackground}"/>
<Setter Property="BorderBrush" Value="{DynamicResource PanelBorder}"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<StackPanel Orientation="Horizontal" Background="Transparent">
<Border x:Name="box" Width="15" Height="15" VerticalAlignment="Center"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1">
<Path x:Name="check" Margin="2" Stretch="Uniform"
Data="M0,4 L3,8 L9,0" Visibility="Collapsed"
Stroke="White" StrokeThickness="1.6"
StrokeEndLineCap="Round" StrokeStartLineCap="Round"/>
</Border>
<ContentPresenter Margin="6,0,0,0" VerticalAlignment="Center" RecognizesAccessKey="True"/>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="check" Property="Visibility" Value="Visible"/>
<Setter TargetName="box" Property="Background" Value="{DynamicResource Accent}"/>
<Setter TargetName="box" Property="BorderBrush" Value="{DynamicResource Accent}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="box" Property="BorderBrush" Value="{DynamicResource Accent}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="GroupBox">
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
<Setter Property="BorderBrush" Value="{DynamicResource PanelBorder}"/>
<Setter Property="Margin" Value="0,0,0,10"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupBox">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{TemplateBinding Header}"
FontWeight="SemiBold" Margin="2,0,0,4"
Foreground="{DynamicResource PrimaryText}"/>
<Border Grid.Row="1" Padding="10"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1"
SnapsToDevicePixels="True">
<ContentPresenter/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="ComboBoxItem">
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Padding" Value="6,3"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBoxItem">
<Border x:Name="bd" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource Accent}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Minimal flat dark/light scroll bar (thumb on a track, no arrow buttons). -->
<Style x:Key="ScrollBarThumb" TargetType="Thumb">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Border CornerRadius="3" Margin="2" Background="{DynamicResource ScrollThumb}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ScrollBarPageButton" TargetType="RepeatButton">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton">
<Border Background="Transparent"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="ScrollBar">
<Setter Property="Background" Value="{DynamicResource ScrollTrack}"/>
<Setter Property="Width" Value="12"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollBar">
<Grid Background="{TemplateBinding Background}">
<Track Name="PART_Track" IsDirectionReversed="True">
<Track.DecreaseRepeatButton>
<RepeatButton Style="{StaticResource ScrollBarPageButton}" Command="ScrollBar.PageUpCommand"/>
</Track.DecreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource ScrollBarThumb}"/>
</Track.Thumb>
<Track.IncreaseRepeatButton>
<RepeatButton Style="{StaticResource ScrollBarPageButton}" Command="ScrollBar.PageDownCommand"/>
</Track.IncreaseRepeatButton>
</Track>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Orientation" Value="Horizontal">
<Setter Property="Width" Value="Auto"/>
<Setter Property="Height" Value="12"/>
<Setter TargetName="PART_Track" Property="IsDirectionReversed" Value="False"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="ComboBox">
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
<Setter Property="Background" Value="{DynamicResource ControlBackground}"/>
<Setter Property="BorderBrush" Value="{DynamicResource PanelBorder}"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Height" Value="24"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton Name="ToggleButton" Focusable="False" ClickMode="Press"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Border Background="{DynamicResource ControlBackground}"
BorderBrush="{DynamicResource PanelBorder}" BorderThickness="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Path Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center"
Data="M0,0 L4,4 L8,0 Z" Fill="{DynamicResource PrimaryText}"/>
</Grid>
</Border>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<ContentPresenter Name="ContentSite" IsHitTestVisible="False"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
VerticalAlignment="Center" HorizontalAlignment="Left"
Margin="7,0,24,0"/>
<Popup Name="Popup" Placement="Bottom" Focusable="False" AllowsTransparency="True"
IsOpen="{TemplateBinding IsDropDownOpen}" PopupAnimation="Slide">
<Border Background="{DynamicResource ControlBackground}"
BorderBrush="{DynamicResource PanelBorder}" BorderThickness="1"
MinWidth="{Binding ActualWidth, RelativeSource={RelativeSource TemplatedParent}}"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<ScrollViewer>
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained"/>
</ScrollViewer>
</Border>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ===== Tabs ===== -->
<Style TargetType="TabControl">
<Setter Property="Background" Value="{DynamicResource WindowBackground}"/>
<Setter Property="BorderBrush" Value="{DynamicResource PanelBorder}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabControl">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TabPanel Grid.Row="0" Panel.ZIndex="1" IsItemsHost="True" Margin="2,2,2,0" Background="Transparent"/>
<Border Grid.Row="1" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1">
<ContentPresenter ContentSource="SelectedContent"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="TabItem">
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Border x:Name="bd" Margin="0,0,2,0" Padding="11,5"
Background="{DynamicResource TabBackground}"
BorderBrush="{DynamicResource PanelBorder}" BorderThickness="1,1,1,0">
<ContentPresenter ContentSource="Header" VerticalAlignment="Center" RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource ButtonHover}"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource WindowBackground}"/>
<Setter TargetName="bd" Property="Margin" Value="0,0,2,-1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ===== Menu ===== -->
<Style TargetType="Menu">
<Setter Property="Background" Value="{DynamicResource MenuBar}"/>
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
</Style>
<ControlTemplate x:Key="TopLevelMenuHeaderTemplate" TargetType="MenuItem">
<Border x:Name="bd" Background="{TemplateBinding Background}" Padding="9,4">
<Grid>
<ContentPresenter ContentSource="Header" RecognizesAccessKey="True"/>
<Popup x:Name="Popup" Placement="Bottom" Focusable="False" AllowsTransparency="True"
IsOpen="{TemplateBinding IsSubmenuOpen}" PopupAnimation="Fade">
<Border Background="{DynamicResource MenuPopup}" BorderBrush="{DynamicResource PanelBorder}"
BorderThickness="1" Padding="0,2">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource MenuHighlight}"/>
</Trigger>
<Trigger Property="IsSubmenuOpen" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource MenuHighlight}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="SubmenuItemTemplate" TargetType="MenuItem">
<Border x:Name="bd" Background="{TemplateBinding Background}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="26"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="14"/>
</Grid.ColumnDefinitions>
<Border x:Name="check" Grid.Column="0" Width="15" Height="15" Visibility="Collapsed"
Background="{DynamicResource Accent}" BorderBrush="{DynamicResource Accent}" BorderThickness="1">
<Path Data="M0,4 L3,8 L9,0" Stroke="White" StrokeThickness="1.6" Margin="2"/>
</Border>
<ContentPresenter Grid.Column="1" ContentSource="Header" RecognizesAccessKey="True"
VerticalAlignment="Center" Margin="2,5"/>
<TextBlock Grid.Column="2" Text="{TemplateBinding InputGestureText}" Opacity="0.7"
VerticalAlignment="Center" Margin="24,0,8,0"/>
<Path x:Name="arrow" Grid.Column="3" Data="M0,0 L4,4 L0,8 Z" Fill="{DynamicResource PrimaryText}"
VerticalAlignment="Center" Visibility="Collapsed"/>
<Popup x:Name="Popup" Placement="Right" Focusable="False" AllowsTransparency="True"
IsOpen="{TemplateBinding IsSubmenuOpen}">
<Border Background="{DynamicResource MenuPopup}" BorderBrush="{DynamicResource PanelBorder}"
BorderThickness="1" Padding="0,2">
<StackPanel IsItemsHost="True"/>
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Role" Value="SubmenuHeader">
<Setter TargetName="arrow" Property="Visibility" Value="Visible"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="check" Property="Visibility" Value="Visible"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter TargetName="bd" Property="Background" Value="{DynamicResource MenuHighlight}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style TargetType="MenuItem">
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template" Value="{StaticResource SubmenuItemTemplate}"/>
<Style.Triggers>
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Template" Value="{StaticResource TopLevelMenuHeaderTemplate}"/>
</Trigger>
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Template" Value="{StaticResource TopLevelMenuHeaderTemplate}"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="Separator">
<Setter Property="Background" Value="{DynamicResource PanelBorder}"/>
<Setter Property="Margin" Value="6,3"/>
<Setter Property="Height" Value="1"/>
</Style>
<!-- Explicit opaque template: the default ContextMenu popup is semi-transparent, which
looked glitchy over the constantly-redrawing LogView. -->
<Style TargetType="ContextMenu">
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContextMenu">
<Border Background="{DynamicResource MenuPopup}" BorderBrush="{DynamicResource PanelBorder}"
BorderThickness="1" Padding="0,2" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="PasswordBox">
<Setter Property="Background" Value="{DynamicResource PanelBackground}"/>
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
<Setter Property="BorderBrush" Value="{DynamicResource PanelBorder}"/>
<Setter Property="CaretBrush" Value="{DynamicResource PrimaryText}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="3,2"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
</Style>
<!-- ===== Status bar / progress / misc ===== -->
<Style TargetType="StatusBar">
<Setter Property="Background" Value="{DynamicResource MenuBar}"/>
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
</Style>
<Style TargetType="StatusBarItem">
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
</Style>
<Style TargetType="ProgressBar">
<Setter Property="Background" Value="{DynamicResource ControlBackground}"/>
<Setter Property="BorderBrush" Value="{DynamicResource PanelBorder}"/>
<Setter Property="Foreground" Value="{DynamicResource Accent}"/>
<Setter Property="BorderThickness" Value="1"/>
</Style>
<Style TargetType="RichTextBox">
<Setter Property="Background" Value="{DynamicResource LogBackground}"/>
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
<Setter Property="BorderBrush" Value="{DynamicResource PanelBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="CaretBrush" Value="{DynamicResource PrimaryText}"/>
</Style>
<Style TargetType="ListBox">
<Setter Property="Background" Value="{DynamicResource PanelBackground}"/>
<Setter Property="Foreground" Value="{DynamicResource PrimaryText}"/>
<Setter Property="BorderBrush" Value="{DynamicResource PanelBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
</Style>
<Style TargetType="GridSplitter">
<Setter Property="Background" Value="{DynamicResource PanelBorder}"/>
</Style>
<!-- ===== NumericUpDown ===== -->
<Style x:Key="SpinnerButton" TargetType="RepeatButton">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Background" Value="{DynamicResource ButtonBackground}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton">
<Border x:Name="b" Background="{TemplateBinding Background}"
BorderBrush="{DynamicResource PanelBorder}" BorderThickness="1,0,0,0">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="b" Property="Background" Value="{DynamicResource ButtonHover}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="b" Property="Background" Value="{DynamicResource ButtonPressed}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ctrl:NumericUpDown}">
<Setter Property="Height" Value="24"/>
<Setter Property="Background" Value="{DynamicResource PanelBackground}"/>
<Setter Property="BorderBrush" Value="{DynamicResource PanelBorder}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ctrl:NumericUpDown}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1" SnapsToDevicePixels="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="17"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="PART_TextBox" Grid.Column="0" BorderThickness="0" Background="Transparent"
Foreground="{DynamicResource PrimaryText}" CaretBrush="{DynamicResource PrimaryText}"
VerticalContentAlignment="Center" Padding="4,0"/>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<RepeatButton x:Name="PART_Up" Grid.Row="0" Style="{StaticResource SpinnerButton}">
<Path Data="M0,4 L4,0 L8,4 Z" Fill="{DynamicResource PrimaryText}"/>
</RepeatButton>
<RepeatButton x:Name="PART_Down" Grid.Row="1" Style="{StaticResource SpinnerButton}">
<Path Data="M0,0 L4,4 L8,0 Z" Fill="{DynamicResource PrimaryText}"/>
</RepeatButton>
</Grid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
+376
View File
@@ -0,0 +1,376 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using Ionic.Zip; // DotNetZip NuGet: Install-Package DotNetZip
namespace APKToolGUI.Utils
{
// Resolves an APK's launcher icon by parsing resources.arsc directly. Handles apps whose
// resource names have been optimized/obfuscated (so the aapt-reported path no longer maps to a
// real entry) and adaptive icons (defined only as anydpi XML, no pixels) by falling back to the
// foreground layer raster. Returns the raw PNG/WebP/JPG bytes, or null when nothing usable is found.
public static class ApkIconExtractor
{
private const int DENSITY_MDPI = 160;
private const int DENSITY_HDPI = 240;
private const int DENSITY_XHDPI = 320;
private const int DENSITY_XXHDPI = 480;
private const int DENSITY_XXXHDPI = 640;
private const ushort CHUNK_STRING_POOL = 0x0001;
private const ushort CHUNK_TABLE = 0x0002;
private const ushort CHUNK_PACKAGE = 0x0200;
private const ushort CHUNK_TYPE_SPEC = 0x0202;
private const ushort CHUNK_TYPE = 0x0201;
private const byte VALUE_TYPE_STRING = 0x03;
private const uint NO_ENTRY = 0xFFFFFFFF;
// Launcher-icon entry-key names to match exactly (the real app icon).
private static readonly string[] PrimaryIconKeys =
{ "ic_launcher", "icon", "app_icon", "ic_launcher_round", "icon_round", "launcher_icon" };
// Raster extensions we can actually decode into a Bitmap. Adaptive-icon XML
// definitions (.xml) are intentionally excluded — they carry no pixels.
private static readonly string[] RasterExtensions = { ".png", ".webp", ".jpg", ".jpeg" };
// Best → worst density bucket. Anything outside the standard set (tvdpi, nodpi,
// anydpi, default, …) gets the lowest rank but is still accepted as a last resort.
private static int DensityRank(int density)
{
switch (density)
{
case DENSITY_XXXHDPI: return 6;
case DENSITY_XXHDPI: return 5;
case DENSITY_XHDPI: return 4;
case DENSITY_HDPI: return 3;
case DENSITY_MDPI: return 2;
default: return 1;
}
}
// ── Public API ───────────────────────────────────────────────
public static byte[] ExtractIcon(string apkPath)
{
if (string.IsNullOrEmpty(apkPath) || !File.Exists(apkPath))
return null;
try
{
using (var zip = ZipFile.Read(apkPath)) // Ionic.Zip API
{
byte[] arsc = ReadEntry(zip, "resources.arsc");
if (arsc == null)
{
Debug.WriteLine("resources.arsc not present in " + Path.GetFileName(apkPath));
return null;
}
string iconPath = FindBestIconPath(arsc);
if (string.IsNullOrEmpty(iconPath))
{
Debug.WriteLine("No launcher icon raster found in resources.arsc of " + Path.GetFileName(apkPath));
return null;
}
Debug.WriteLine($"[ApkIconExtractor] {Path.GetFileName(apkPath)} → {iconPath}");
return ReadEntry(zip, iconPath); // null if listed but physically absent (e.g. in a split)
}
}
catch (Exception ex)
{
Debug.WriteLine("ApkIconExtractor failed for " + Path.GetFileName(apkPath) + ": " + ex.Message);
return null;
}
}
// ── Ionic.Zip entry reader ───────────────────────────────────
/// <summary>
/// Reads a ZIP entry by name into a byte array.
/// Ionic.Zip uses forward-slash paths and is case-sensitive on most platforms.
/// </summary>
private static byte[] ReadEntry(ZipFile zip, string entryName)
{
// Ionic.Zip indexer returns null if not found (no exception)
ZipEntry entry = zip[entryName];
if (entry == null)
{
// Try case-insensitive fallback (some APKs use mixed casing)
foreach (ZipEntry e in zip)
{
if (string.Equals(e.FileName, entryName, StringComparison.OrdinalIgnoreCase))
{
entry = e;
break;
}
}
}
if (entry == null)
return null;
using (var ms = new MemoryStream())
{
entry.Extract(ms); // Ionic.Zip extracts directly into a stream
return ms.ToArray();
}
}
// ── resources.arsc parser ────────────────────────────────────
// Scans the resource table for the app's launcher icon and returns the best raster
// file path. Prefers a real launcher-icon raster (ic_launcher/icon/...); if the icon
// is an adaptive icon (defined only as anydpi XML, so no pixels), falls back to its
// foreground layer, which is a real PNG/WebP. Returns null if nothing usable is found.
private static string FindBestIconPath(byte[] d)
{
if (d == null || d.Length < 12 || ReadU16(d, 0) != CHUNK_TABLE)
return null;
ushort tableHdrSize = ReadU16(d, 2);
uint packageCount = ReadU32(d, 8);
int pos = tableHdrSize;
var globalStrings = ReadStringPool(d, pos, out int globalPoolSize);
pos += globalPoolSize;
string bestPrimary = null; int bestPrimaryRank = 0;
string bestForeground = null; int bestForegroundRank = 0;
for (int p = 0; p < packageCount && pos + 8 <= d.Length; p++)
{
int pkgStart = pos;
ushort pkgHdrSize = ReadU16(d, pkgStart + 2);
uint pkgSize = ReadU32(d, pkgStart + 4);
uint typeStrOff = ReadU32(d, pkgStart + 268);
uint keyStrOff = ReadU32(d, pkgStart + 276);
var typeStrings = ReadStringPool(d, pkgStart + (int)typeStrOff, out _);
var keyStrings = ReadStringPool(d, pkgStart + (int)keyStrOff, out _);
// Launcher icons live under the mipmap or drawable type.
int mipmapTypeId = FindIndex(typeStrings, "mipmap") + 1;
int drawableTypeId = FindIndex(typeStrings, "drawable") + 1;
// Pre-resolve the key-pool indices we care about so per-entry checks are O(1).
var primaryKeyIdx = new HashSet<int>();
var foregroundKeyIdx = new HashSet<int>();
for (int i = 0; i < keyStrings.Count; i++)
{
string k = keyStrings[i];
if (string.IsNullOrEmpty(k)) continue;
if (Array.IndexOf(PrimaryIconKeys, k) >= 0)
primaryKeyIdx.Add(i);
else if (k.IndexOf("foreground", StringComparison.OrdinalIgnoreCase) >= 0 &&
(k.IndexOf("launcher", StringComparison.OrdinalIgnoreCase) >= 0 ||
k.IndexOf("icon", StringComparison.OrdinalIgnoreCase) >= 0))
foregroundKeyIdx.Add(i);
}
if ((mipmapTypeId == 0 && drawableTypeId == 0) ||
(primaryKeyIdx.Count == 0 && foregroundKeyIdx.Count == 0))
{
pos = pkgStart + (int)pkgSize;
continue;
}
int chunkPos = pkgStart + pkgHdrSize;
int pkgEnd = pkgStart + (int)pkgSize;
while (chunkPos + 8 <= d.Length && chunkPos < pkgEnd)
{
ushort chunkType = ReadU16(d, chunkPos);
ushort chunkHdrSize = ReadU16(d, chunkPos + 2);
uint chunkSize = ReadU32(d, chunkPos + 4);
if (chunkSize == 0) break;
if (chunkType == CHUNK_TYPE)
{
byte typeId = d[chunkPos + 8];
if (typeId == mipmapTypeId || typeId == drawableTypeId)
ScanTypeChunk(d, chunkPos, chunkHdrSize, globalStrings,
primaryKeyIdx, foregroundKeyIdx,
ref bestPrimary, ref bestPrimaryRank,
ref bestForeground, ref bestForegroundRank);
}
chunkPos += (int)chunkSize;
}
pos = pkgStart + (int)pkgSize;
}
// A genuine launcher-icon raster wins; otherwise use the adaptive foreground layer.
return bestPrimary ?? bestForeground;
}
// Inspects every entry in one TYPE (config) chunk, updating the best primary/foreground
// raster seen so far. Entries are matched by their `key` pool index, not by position.
private static void ScanTypeChunk(
byte[] d, int chunkPos, ushort chunkHdrSize,
List<string> globalStrings,
HashSet<int> primaryKeyIdx, HashSet<int> foregroundKeyIdx,
ref string bestPrimary, ref int bestPrimaryRank,
ref string bestForeground, ref int bestForegroundRank)
{
byte typeFlags = d[chunkPos + 9]; // FLAG_SPARSE = 0x01
uint entryCount = ReadU32(d, chunkPos + 12);
uint entriesStart = ReadU32(d, chunkPos + 16);
int density = ReadU16(d, chunkPos + 20 + 14);
int rank = DensityRank(density);
// The offset table starts right after the chunk header (which includes the
// ResTable_config block). Each slot is a dense uint32 offset, or — when
// FLAG_SPARSE is set — a packed { uint16 entryIdx; uint16 offset/4 } pair.
int offsetTablePos = chunkPos + chunkHdrSize;
bool sparse = (typeFlags & 0x01) != 0;
for (int i = 0; i < (int)entryCount; i++)
{
uint entryOffset;
if (sparse)
{
entryOffset = (uint)ReadU16(d, offsetTablePos + i * 4 + 2) * 4;
}
else
{
entryOffset = ReadU32(d, offsetTablePos + i * 4);
if (entryOffset == NO_ENTRY) continue;
}
int entryPos = chunkPos + (int)entriesStart + (int)entryOffset;
if (entryPos + 8 > d.Length) continue;
ushort entryFlags = ReadU16(d, entryPos + 2);
int entryKey = (int)ReadU32(d, entryPos + 4);
bool isPrimary = primaryKeyIdx.Contains(entryKey);
bool isForeground = !isPrimary && foregroundKeyIdx.Contains(entryKey);
if (!isPrimary && !isForeground) continue;
if ((entryFlags & 0x0001) != 0) continue; // complex (<adaptive-icon>) — no file path
int valuePos = entryPos + 8;
if (valuePos + 8 > d.Length) continue;
byte dataType = d[valuePos + 3];
uint dataVal = ReadU32(d, valuePos + 4);
if (dataType != VALUE_TYPE_STRING || dataVal >= (uint)globalStrings.Count) continue;
string path = globalStrings[(int)dataVal];
if (string.IsNullOrEmpty(path) || !HasRasterExtension(path)) continue; // skip .xml adaptive defs
if (isPrimary && rank > bestPrimaryRank)
{
bestPrimary = path;
bestPrimaryRank = rank;
}
else if (isForeground && rank > bestForegroundRank)
{
bestForeground = path;
bestForegroundRank = rank;
}
}
}
private static bool HasRasterExtension(string path)
{
foreach (var ext in RasterExtensions)
if (path.EndsWith(ext, StringComparison.OrdinalIgnoreCase))
return true;
return false;
}
// ── String pool parser ───────────────────────────────────────
private static List<string> ReadStringPool(byte[] d, int pos, out int chunkSizeOut)
{
ushort headerSize = ReadU16(d, pos + 2);
uint chunkSize = ReadU32(d, pos + 4);
uint stringCount = ReadU32(d, pos + 8);
uint flags = ReadU32(d, pos + 16);
uint stringsStart = ReadU32(d, pos + 20);
bool isUtf8 = (flags & 0x100) != 0;
int offsetsBase = pos + headerSize;
int stringsBase = pos + (int)stringsStart;
var strings = new List<string>((int)stringCount);
for (int i = 0; i < (int)stringCount; i++)
{
uint strOffset = ReadU32(d, offsetsBase + i * 4);
int strPos = stringsBase + (int)strOffset;
try
{
strings.Add(isUtf8
? DecodeUtf8String(d, strPos)
: DecodeUtf16String(d, strPos));
}
catch
{
strings.Add(string.Empty);
}
}
chunkSizeOut = (int)chunkSize;
return strings;
}
private static string DecodeUtf8String(byte[] d, int pos)
{
if ((d[pos] & 0x80) != 0) pos += 2; else pos++;
int byteLen;
if ((d[pos] & 0x80) != 0)
{
byteLen = ((d[pos] & 0x7F) << 8) | d[pos + 1];
pos += 2;
}
else
{
byteLen = d[pos];
pos++;
}
return Encoding.UTF8.GetString(d, pos, byteLen);
}
private static string DecodeUtf16String(byte[] d, int pos)
{
int charLen;
if ((ReadU16(d, pos) & 0x8000) != 0)
{
charLen = ((ReadU16(d, pos) & 0x7FFF) << 16) | ReadU16(d, pos + 2);
pos += 4;
}
else
{
charLen = ReadU16(d, pos);
pos += 2;
}
return Encoding.Unicode.GetString(d, pos, charLen * 2);
}
// ── Low-level helpers ────────────────────────────────────────
private static int FindIndex(List<string> list, string value)
{
for (int i = 0; i < list.Count; i++)
if (list[i] == value) return i;
return -1;
}
private static ushort ReadU16(byte[] d, int pos) =>
(ushort)(d[pos] | (d[pos + 1] << 8));
private static uint ReadU32(byte[] d, int pos) =>
(uint)(d[pos] | (d[pos + 1] << 8) | (d[pos + 2] << 16) | (d[pos + 3] << 24));
}
}
+22
View File
@@ -31,5 +31,27 @@ namespace APKToolGUI.Utils
return null;
}
}
// Decodes raw image bytes (e.g. an APK launcher icon resolved in memory) into a Bitmap.
// Returns a standalone copy so the backing MemoryStream can be disposed immediately and
// the result remains usable for saving. Returns null on null/empty input or a format
// GDI+ can't decode (e.g. WebP).
public static Bitmap LoadBitmap(byte[] data)
{
if (data == null || data.Length == 0)
return null;
try
{
using (var memoryStream = new MemoryStream(data))
using (var temp = new Bitmap(memoryStream))
{
return new Bitmap(temp);
}
}
catch
{
return null;
}
}
}
}
-143
View File
@@ -1,143 +0,0 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Markup;
namespace SaveToGameWpf.Logic.Utils
{
public static class DragDropUtils
{
private static readonly string[] EmptyStrings = new string[0];
public static string[] GetFilesDrop(this DragEventArgs args)
{
return (string[])args.Data.GetData(DataFormats.FileDrop) ?? EmptyStrings;
}
public static string[] GetFilesDrop(this DragEventArgs args, string ending)
{
// ReSharper disable once ConvertIfStatementToReturnStatement
if (string.IsNullOrEmpty(ending))
return args.GetFilesDrop();
return args.GetFilesDrop(it => it.EndsWith(ending, StringComparison.Ordinal));
}
public static string[] GetFilesDrop(this DragEventArgs args, Func<string, bool> filter)
{
var items = args.GetFilesDrop();
if (items == null)
return EmptyStrings;
return filter == null ? items : items.Where(filter).ToArray();
}
public static void CheckDragEnter(this DragEventArgs e, params string[] extensions)
{
string[] files = e.GetFilesDrop();
if (files.Length == 0)
{
e.Effect = DragDropEffects.None;
return;
}
if (extensions == null && Directory.Exists(files[0]))
e.Effect = DragDropEffects.Copy;
else if (extensions != null && extensions.Any(ext => files[0].EndsWith(ext, StringComparison.Ordinal)))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
public static bool CheckDragOver(this DragEventArgs e, params string[] extensions)
{
string[] files = e.GetFilesDrop();
if (files.Length == 0)
{
e.Effect = DragDropEffects.None;
return false;
}
if (extensions == null && Directory.Exists(files[0]))
{
e.Effect = DragDropEffects.Move;
return true;
}
else if (extensions != null && files.Length == 1 && extensions.Any(ext => files[0].EndsWith(ext, StringComparison.Ordinal)))
{
e.Effect = DragDropEffects.Move;
return true;
}
e.Effect = DragDropEffects.None;
return false;
}
public static bool CheckManyDragOver(this DragEventArgs e, params string[] extensions)
{
string[] files = e.GetFilesDrop();
if (files.Length == 0)
{
e.Effect = DragDropEffects.None;
return false;
}
if (extensions == null && Directory.Exists(files[0]))
{
e.Effect = DragDropEffects.Move;
return true;
}
else if (extensions != null && extensions.Any(ext => files[0].EndsWith(ext, StringComparison.Ordinal)))
{
e.Effect = DragDropEffects.Move;
return true;
}
e.Effect = DragDropEffects.None;
return false;
}
public static bool DropOneByEnd(this DragEventArgs e, Action<string> onSuccess, params string[] extensions)
{
string[] files = e.GetFilesDrop();
if (files.Length == 0)
return false;
if (extensions == null && Directory.Exists(files[0]))
{
onSuccess(files[0]);
return true;
}
else if (extensions.Any(ext => files[0].EndsWith(ext, StringComparison.Ordinal)))
{
onSuccess(files[0]);
return true;
}
return false;
}
public static bool DropManyByEnd(this DragEventArgs e, Action<string[]> onSuccess, params string[] extensions)
{
if (extensions == null || extensions.Length == 0)
return false;
foreach (string apk in extensions)
{
Debug.WriteLine(apk);
string[] files = e.GetFilesDrop(apk);
if (files.Length > 0)
{
onSuccess(files);
return true;
}
}
return false;
}
}
}
+19 -33
View File
@@ -1,4 +1,4 @@
using APKToolGUI;
using APKToolGUI;
using APKToolGUI.Properties;
using System;
using System.Collections.Generic;
@@ -13,50 +13,36 @@ namespace APKToolGUI.Utils
public static class Log
{
/// <summary>
/// log message with level VERBOSE (may be disabled)
/// Active log sink. Set by the main window (<c>MainWindow.ToLog</c>) at startup.
/// </summary>
/// <param name="s">the string to log</param>
public static Action<ApktoolEventType, string> Output;
private static void Send(ApktoolEventType type, string s)
{
Output?.Invoke(type, s);
}
/// <summary>log message with level VERBOSE (may be disabled)</summary>
public static void v(string s)
{
if (!Settings.Default.DebugMode) return;
FormMain.Instance.ToLog(ApktoolEventType.None, s);
Send(ApktoolEventType.None, s);
}
/// <summary>
/// log message with level DEBUG (may be disabled)
/// </summary>
/// <param name="s">the string to log</param>
/// <summary>log message with level DEBUG (may be disabled)</summary>
public static void d(string s)
{
if (!Settings.Default.DebugMode) return;
FormMain.Instance.ToLog(ApktoolEventType.Infomation, s);
Send(ApktoolEventType.Infomation, s);
}
/// <summary>
/// log message with level INFO
/// </summary>
/// <param name="s">the string to log</param>
public static void i(string s)
{
FormMain.Instance.ToLog(ApktoolEventType.Infomation, s);
}
/// <summary>log message with level INFO</summary>
public static void i(string s) => Send(ApktoolEventType.Infomation, s);
/// <summary>
/// log message with level WARNING
/// </summary>
/// <param name="s">the string to log</param>
public static void w(string s)
{
FormMain.Instance.ToLog(ApktoolEventType.Warning, s);
}
/// <summary>log message with level WARNING</summary>
public static void w(string s) => Send(ApktoolEventType.Warning, s);
/// <summary>
/// log message with level ERROR
/// </summary>
/// <param name="s">the string to log</param>
public static void e(string s)
{
FormMain.Instance.ToLog(ApktoolEventType.Error, s);
}
/// <summary>log message with level ERROR</summary>
public static void e(string s) => Send(ApktoolEventType.Error, s);
}
}
+3 -3
View File
@@ -169,9 +169,6 @@
<setting name="Sign_KeystorePassword" serializeAs="String">
<value />
</setting>
<setting name="Sign_KeyPassword" serializeAs="String">
<value />
</setting>
<setting name="Sign_UseOutputDir" serializeAs="String">
<value>False</value>
</setting>
@@ -304,6 +301,9 @@
<setting name="Build_SetJobs" serializeAs="String">
<value>False</value>
</setting>
<setting name="Sign_KeyPassword" serializeAs="String">
<value />
</setting>
</APKToolGUI.Properties.Settings>
</userSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" /></startup>
-1
View File
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Costura.Fody" version="6.0.0" targetFramework="net48" developmentDependency="true" />
<package id="DarkNet" version="2.3.0" targetFramework="net48" />
<package id="Fody" version="6.9.3" targetFramework="net48" developmentDependency="true" />
<package id="Microsoft.Bcl.HashCode" version="6.0.0" targetFramework="net48" />
<package id="Microsoft.NETCore.Platforms" version="7.0.4" targetFramework="net48" />
+1 -13
View File
@@ -47,22 +47,10 @@ If you remain unsure, you can compile the app yourself or refrain from using it
- German
### Translation
If you like to help translate with your native language, I recommend using Visual Studio 2022. You don't need any programming knowledge, you just edit the GUI and the `.resx` files
Create new `.resx` file under `Languages` folder, and `Forms/FormXXX.cs/`. To create a new `.resx` under `Forms/FormXXX.cs/`, open the form and select the form to show the properties. In the properties, scroll down until you see Language, and select any language you would like to translate.
<details>
<summary>Video tutorial</summary>
https://user-images.githubusercontent.com/40742924/227244601-6f796141-ac2d-4c60-b5cd-7f6872604cd7.mp4
</details>
If you would like to help with translations in your native language, I recommend using Visual Studio. No programming knowledge is required; you just need to use it to edit or create a new `.resx` file in the `Languages` folder.
If you can't use Visual Studio, you can use translator tools like [resxtranslator](https://github.com/HakanL/resxtranslator) or [RESX Translator automat](https://www.utilstudio.com/en/resx-translator/), but make sure the `.resx` file is added to [APKToolGUI.csproj](https://github.com/AndnixSH/APKToolGUI/blob/master/APKToolGUI/APKToolGUI.csproj), otherwise Visual Studio would not be able to detect it
3rd party tools can't be translated.
Make pull request when you are done
# Issues
+7
View File
@@ -1,3 +1,10 @@
3.3.2.3
- Updated Apktool to 3.0.2
- Add separate key password field for APK signing
- Updated Russian localization
- Correct signing/build option handling and drag-drop stability
- Support Apktool 3.0.x flags
3.3.2.2
- Updated APKEditor to 1.4.7
- Updated Apktool to 3.0.1