Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 735d448

Browse files
add optional Explorer context menu to Install (and run) selected APK file to device (fixes #181)
1 parent 54dab25 commit 735d448

File tree

5 files changed

+239
-5
lines changed

5 files changed

+239
-5
lines changed

‎UnityLauncherPro/MainWindow.xaml‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
xmlns:System="clr-namespace:System;assembly=mscorlib"
88
xmlns:converters="clr-namespace:UnityLauncherPro.Converters" x:Class="UnityLauncherPro.MainWindow"
99
mc:Ignorable="d"
10-
Title="UnityLauncherPro" Height="650" Width="880" WindowStartupLocation="CenterScreen" Background="{DynamicResource ThemeDarkestBackground}" MinWidth="780" MinHeight="650" AllowsTransparency="True" WindowStyle="None" Margin="0" KeyDown="OnWindowKeyDown" Closing="Window_Closing" SizeChanged="Window_SizeChanged" Icon="Images/icon.ico" SourceInitialized="Window_SourceInitialized" MouseDown="Window_MouseDown">
10+
Title="UnityLauncherPro" Height="670" Width="880" WindowStartupLocation="CenterScreen" Background="{DynamicResource ThemeDarkestBackground}" MinWidth="780" MinHeight="650" AllowsTransparency="True" WindowStyle="None" Margin="0" KeyDown="OnWindowKeyDown" Closing="Window_Closing" SizeChanged="Window_SizeChanged" Icon="Images/icon.ico" SourceInitialized="Window_SourceInitialized" MouseDown="Window_MouseDown">
1111
<Window.Resources>
1212
<converters:LastModifiedConverter x:Key="lastModifiedConverter"/>
1313
<converters:LastModifiedConverterTooltip x:Key="LastModifiedConverterTooltip"/>
@@ -842,7 +842,8 @@
842842

843843
<GroupBox Grid.Row="3" Header="System" VerticalAlignment="Top" Margin="0,0,3,0">
844844
<StackPanel Grid.Row="3" Orientation="Vertical" Margin="3,5,0,0" >
845-
<CheckBox x:Name="chkRegisterExplorerMenu" Content="Register Explorer context menu" Unchecked="ChkRegisterExplorerMenu_CheckedChanged" Checked="ChkRegisterExplorerMenu_CheckedChanged" ToolTip="Install registry entry for Explorer context menu" HorizontalAlignment="Left"/>
845+
<CheckBox x:Name="chkRegisterExplorerMenu" Content="Register Explorer context menu" Unchecked="ChkRegisterExplorerMenu_CheckedChanged" Checked="ChkRegisterExplorerMenu_CheckedChanged" ToolTip="Add registry entry for Explorer context menu" HorizontalAlignment="Left"/>
846+
<CheckBox x:Name="chkRegisterInstallAPKMenu" Content="Register 'Install APK' Explorer context menu" ToolTip="Add registry entry for Explorer 'Install APK' context menu" HorizontalAlignment="Left" Checked="chkRegisterInstallAPKMenu_Checked" Unchecked="chkRegisterInstallAPKMenu_Checked"/>
846847
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
847848
<CheckBox x:Name="chkRunAutomatically" Content="Run automatically on startup" ToolTip="Run automatically using startup registry key" HorizontalAlignment="Left" Checked="ChkRunAutomatically_Checked" Unchecked="ChkRunAutomatically_Checked"/>
848849
<CheckBox x:Name="chkRunAutomaticallyMinimized" Content="as minimized" ToolTip="Minimize to tray when started automatically" HorizontalAlignment="Left" Checked="ChkRunAutomaticallyMinimized_Checked" Unchecked="ChkRunAutomaticallyMinimized_Checked" Margin="5,0,0,3"/>

‎UnityLauncherPro/MainWindow.xaml.cs‎

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,32 @@ void HandleCommandLineLaunch()
276276
string[] args = Environment.GetCommandLineArgs();
277277
if (args != null && args.Length > 2)
278278
{
279+
280+
279281
// first argument needs to be -projectPath
280282
var commandLineArgs = args[1];
283+
284+
// if install argument, then just try to install this file (APK)
285+
if (commandLineArgs == "-install")
286+
{
287+
Console.WriteLine("Launching from commandline...");
288+
289+
// path
290+
var apkPath = args[2];
291+
292+
// resolve full path if path parameter isn't a rooted path
293+
//if (!Path.IsPathRooted(apkPath))
294+
//{
295+
// apkPath = Directory.GetCurrentDirectory() + apkPath;
296+
//}
297+
//MessageBox.Show("APK install not implemented yet: " + apkPath);
298+
// try installing it
299+
Tools.InstallAPK(apkPath);
300+
Environment.Exit(0);
301+
}
302+
else
303+
304+
281305
if (commandLineArgs == "-projectPath")
282306
{
283307
Console.WriteLine("Launching from commandline...");
@@ -328,7 +352,7 @@ void HandleCommandLineLaunch()
328352
}
329353

330354
// quit after launch if enabled in settings
331-
if (Properties.Settings.Default.closeAfterExplorer == true)
355+
if (Settings.Default.closeAfterExplorer == true)
332356
{
333357
Environment.Exit(0);
334358
}
@@ -493,6 +517,7 @@ void LoadSettings()
493517

494518
chkMinimizeToTaskbar.IsChecked = Settings.Default.minimizeToTaskbar;
495519
chkRegisterExplorerMenu.IsChecked = Settings.Default.registerExplorerMenu;
520+
chkRegisterInstallAPKMenu.IsChecked = Settings.Default.registerExplorerMenuAPK;
496521

497522
// update settings window
498523
chkQuitAfterCommandline.IsChecked = Settings.Default.closeAfterExplorer;
@@ -3562,7 +3587,7 @@ private void menuInstallLastAPK_Click(object sender, RoutedEventArgs e)
35623587
}
35633588

35643589
// install the apk using ADB using cmd (-r = replace app)
3565-
var cmd = "cmd.exe";// /C adb install -r \"{playerPath}\"";
3590+
var cmd = "cmd.exe";
35663591
var pars = $"/C adb install -r \"{playerPath}\"";
35673592

35683593
string packageName = null;
@@ -3928,7 +3953,7 @@ private async void chkDisableUnityHubLaunch_Checked(object sender, RoutedEventAr
39283953
{
39293954
if (!this.IsActive) return; // Don't run code during window initialization
39303955

3931-
Console.WriteLine((bool)chkDisableUnityHubLaunch.IsChecked);
3956+
//Console.WriteLine((bool)chkDisableUnityHubLaunch.IsChecked);
39323957

39333958
if ((bool)chkDisableUnityHubLaunch.IsChecked)
39343959
{
@@ -3987,6 +4012,24 @@ private async Task CloseHubPipeAsync()
39874012
}
39884013
}
39894014

4015+
private void chkRegisterInstallAPKMenu_Checked(object sender, RoutedEventArgs e)
4016+
{
4017+
if (this.IsActive == false) return; // dont run code on window init
4018+
4019+
if ((bool)chkRegisterInstallAPKMenu.IsChecked)
4020+
{
4021+
Tools.AddContextMenuRegistryAPKInstall(contextRegRoot);
4022+
}
4023+
else // remove
4024+
{
4025+
Tools.RemoveContextMenuRegistryAPKInstall(contextRegRoot);
4026+
}
4027+
4028+
Settings.Default.registerExplorerMenuAPK = (bool)chkRegisterInstallAPKMenu.IsChecked;
4029+
Settings.Default.Save();
4030+
4031+
}
4032+
39904033

39914034

39924035
//private void menuProjectProperties_Click(object sender, RoutedEventArgs e)

‎UnityLauncherPro/Properties/Settings.Designer.cs‎

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎UnityLauncherPro/Properties/Settings.settings‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,5 +154,8 @@
154154
<Setting Name="disableUnityHubLaunch" Type="System.Boolean" Scope="User">
155155
<Value Profile="(Default)">False</Value>
156156
</Setting>
157+
<Setting Name="registerExplorerMenuAPK" Type="System.Boolean" Scope="User">
158+
<Value Profile="(Default)">False</Value>
159+
</Setting>
157160
</Settings>
158161
</SettingsFile>

‎UnityLauncherPro/Tools.cs‎

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Microsoft.Win32;
22
using System;
33
using System.Collections.Generic;
4+
using System.ComponentModel;
45
using System.Diagnostics;
56
using System.IO;
67
using System.Linq;
@@ -1278,6 +1279,56 @@ public static void AddContextMenuRegistry(string contextRegRoot)
12781279
}
12791280
}
12801281

1282+
public static void AddContextMenuRegistryAPKInstall(string contextRegRoot)
1283+
{
1284+
// Define the registry key path for .apk file association
1285+
string apkFileTypeRegPath = @"Software\Classes\.apk";
1286+
1287+
// Open or create the registry key for .apk files
1288+
RegistryKey apkKey = Registry.CurrentUser.OpenSubKey(apkFileTypeRegPath, true);
1289+
1290+
if (apkKey == null)
1291+
{
1292+
apkKey = Registry.CurrentUser.CreateSubKey(apkFileTypeRegPath);
1293+
}
1294+
1295+
if (apkKey != null)
1296+
{
1297+
// Create or open the Shell subkey for context menu options
1298+
RegistryKey shellKey = apkKey.CreateSubKey("shell", true);
1299+
1300+
if (shellKey != null)
1301+
{
1302+
var appName = "UnityLauncherPro";
1303+
// Create a subkey for the app's context menu item
1304+
RegistryKey appKey = shellKey.CreateSubKey(appName, true);
1305+
1306+
if (appKey != null)
1307+
{
1308+
appKey.SetValue("", "Install with " + appName); // Display name in context menu
1309+
appKey.SetValue("Icon", "\"" + Process.GetCurrentProcess().MainModule.FileName + "\"");
1310+
appKey.SetValue("Position", "Bottom"); // Set position to adjust order
1311+
1312+
// Create the command subkey to specify the action
1313+
RegistryKey commandKey = appKey.CreateSubKey("command", true);
1314+
1315+
if (commandKey != null)
1316+
{
1317+
// Build the command string to launch with -install argument
1318+
var executeString = "\"" + Process.GetCurrentProcess().MainModule.FileName + "\" -install \"%1\"";
1319+
commandKey.SetValue("", executeString);
1320+
}
1321+
}
1322+
}
1323+
}
1324+
else
1325+
{
1326+
Console.WriteLine("Error> Cannot create or access registry key for .apk file association: " + apkFileTypeRegPath);
1327+
}
1328+
}
1329+
1330+
1331+
12811332
/// <summary>
12821333
/// uninstall context menu item from registry
12831334
/// </summary>
@@ -1305,6 +1356,37 @@ public static void RemoveContextMenuRegistry(string contextRegRoot)
13051356
}
13061357
}
13071358

1359+
public static void RemoveContextMenuRegistryAPKInstall(string contextRegRoot)
1360+
{
1361+
// Define the registry key path for .apk file association
1362+
string apkFileTypeRegPath = @"Software\Classes\.apk\shell";
1363+
1364+
// Open the registry key for the shell context menu
1365+
RegistryKey shellKey = Registry.CurrentUser.OpenSubKey(apkFileTypeRegPath, true);
1366+
1367+
if (shellKey != null)
1368+
{
1369+
var appName = "UnityLauncherPro";
1370+
1371+
// Check if the app's context menu key exists
1372+
RegistryKey appKey = shellKey.OpenSubKey(appName, false);
1373+
if (appKey != null)
1374+
{
1375+
// Delete the app's context menu key
1376+
shellKey.DeleteSubKeyTree(appName);
1377+
Console.WriteLine("Removed context menu for .apk files.");
1378+
}
1379+
else
1380+
{
1381+
Console.WriteLine("No context menu found for .apk files.");
1382+
}
1383+
}
1384+
else
1385+
{
1386+
Console.WriteLine("Error> Cannot find registry key for .apk shell context: " + apkFileTypeRegPath);
1387+
}
1388+
}
1389+
13081390
/// <summary>
13091391
/// reads .git/HEAD file from the project to get current branch name
13101392
/// </summary>
@@ -2505,6 +2587,99 @@ internal static string GetSRP(string projectPath)
25052587
}
25062588

25072589
}
2590+
2591+
internal static void InstallAPK(string ApkPath)
2592+
{
2593+
try
2594+
{
2595+
var cmd = "cmd.exe";
2596+
var pars = $"/C adb install -r \"{ApkPath}\""; // Use /C to execute and close the window after finishing
2597+
2598+
var processStartInfo = new ProcessStartInfo
2599+
{
2600+
FileName = cmd,
2601+
Arguments = pars,
2602+
RedirectStandardOutput = true, // Capture output to wait for completion
2603+
RedirectStandardError = true,
2604+
UseShellExecute = false,
2605+
CreateNoWindow = false
2606+
};
2607+
2608+
string installOutput = null;
2609+
string installError = null;
2610+
2611+
using (var installProcess = Process.Start(processStartInfo))
2612+
{
2613+
installOutput = installProcess.StandardOutput.ReadToEnd();
2614+
installError = installProcess.StandardError.ReadToEnd();
2615+
installProcess.WaitForExit();
2616+
2617+
if (installProcess.ExitCode != 0 || !string.IsNullOrEmpty(installError))
2618+
{
2619+
SetStatus($"Error installing APK: {installError.Trim()}\n{installOutput.Trim()}");
2620+
return;
2621+
}
2622+
}
2623+
2624+
// Attempt to extract package name using aapt
2625+
var aaptCmd = $"aapt dump badging \"{ApkPath}\" | findstr package:";
2626+
var aaptProcessStartInfo = new ProcessStartInfo
2627+
{
2628+
FileName = "cmd.exe",
2629+
Arguments = $"/C {aaptCmd}",
2630+
RedirectStandardOutput = true,
2631+
UseShellExecute = false,
2632+
CreateNoWindow = true
2633+
};
2634+
2635+
string packageName = null;
2636+
using (var process = Process.Start(aaptProcessStartInfo))
2637+
{
2638+
var output = process.StandardOutput.ReadToEnd();
2639+
process.WaitForExit();
2640+
2641+
var match = System.Text.RegularExpressions.Regex.Match(output, "package: name='(.*?)'");
2642+
if (match.Success)
2643+
{
2644+
packageName = match.Groups[1].Value;
2645+
}
2646+
}
2647+
2648+
if (!string.IsNullOrEmpty(packageName))
2649+
{
2650+
// Run the application using adb
2651+
var runPars = $"/C adb shell monkey -p {packageName} 1";
2652+
var runProcessStartInfo = new ProcessStartInfo
2653+
{
2654+
FileName = cmd,
2655+
Arguments = runPars,
2656+
UseShellExecute = true,
2657+
CreateNoWindow = false,
2658+
WindowStyle = ProcessWindowStyle.Normal
2659+
};
2660+
Process.Start(runProcessStartInfo);
2661+
2662+
SetStatus($"Installed and launched APK with package name: {packageName}");
2663+
}
2664+
else
2665+
{
2666+
SetStatus("ADB install completed, but failed to extract package name. Application not launched.");
2667+
}
2668+
}
2669+
catch (Win32Exception ex)
2670+
{
2671+
// Handle case where adb or aapt is not found
2672+
SetStatus($"Error: Required tool not found. Ensure adb and aapt are installed and added to PATH. Details: {ex.Message}");
2673+
}
2674+
catch (Exception ex)
2675+
{
2676+
// Handle other unexpected exceptions
2677+
SetStatus($"An unexpected error occurred: {ex.Message}");
2678+
}
2679+
}
2680+
2681+
2682+
25082683
} // class
25092684

25102685
} // namespace

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /