From c8f322cec47bea4bc97aef9beeda45b6a2ef56ad Mon Sep 17 00:00:00 2001 From: unitycoder Date: Thu, 9 Jan 2025 20:46:34 +0200 Subject: [PATCH 01/67] add tooltip to statusbar (otherwise cannot see long messages), display crash scene recovery dialog only once (fixes #174) --- UnityLauncherPro/MainWindow.xaml.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/UnityLauncherPro/MainWindow.xaml.cs b/UnityLauncherPro/MainWindow.xaml.cs index 819606f..fd9dcfc 100644 --- a/UnityLauncherPro/MainWindow.xaml.cs +++ b/UnityLauncherPro/MainWindow.xaml.cs @@ -3479,6 +3479,7 @@ public void SetStatus(string msg, MessageType messageType = MessageType.Info) } txtStatus.Text = msg; + txtStatus.ToolTip = msg; } public void SetBuildStatus(System.Windows.Media.Color color) From fffd6a31dedd8f4406e9ea5b85759f225f32274d Mon Sep 17 00:00:00 2001 From: unitycoder Date: Thu, 9 Jan 2025 20:47:18 +0200 Subject: [PATCH 02/67] fix crash scene backup dialog appears twice #174 --- UnityLauncherPro/Tools.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/UnityLauncherPro/Tools.cs b/UnityLauncherPro/Tools.cs index 3dd3954..7ce8ffb 100644 --- a/UnityLauncherPro/Tools.cs +++ b/UnityLauncherPro/Tools.cs @@ -256,13 +256,6 @@ public static Process LaunchProject(Project proj, DataGrid dataGridRef = null, b Directory.CreateDirectory(assetsFolder); } - // when opening project, check for crashed backup scene first - var cancelLaunch = CheckCrashBackupScene(proj.Path); - if (cancelLaunch == true) - { - return null; - } - // if its upgrade, we dont want to check current version if (upgrade == false) { @@ -283,6 +276,13 @@ public static Process LaunchProject(Project proj, DataGrid dataGridRef = null, b return null; } + // when opening project, check for crashed backup scene first + var cancelLaunch = CheckCrashBackupScene(proj.Path); + if (cancelLaunch == true) + { + return null; + } + Process newProcess = new Process(); try { From ecc66e95a411269d59e51973af61a27923ac9bae Mon Sep 17 00:00:00 2001 From: unitycoder Date: Thu, 9 Jan 2025 22:39:40 +0200 Subject: [PATCH 03/67] updates: clear filter when checking updates for selected unity fixes #180, apply search filter after updates list is loaded --- UnityLauncherPro/MainWindow.xaml.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/UnityLauncherPro/MainWindow.xaml.cs b/UnityLauncherPro/MainWindow.xaml.cs index fd9dcfc..b464fe2 100644 --- a/UnityLauncherPro/MainWindow.xaml.cs +++ b/UnityLauncherPro/MainWindow.xaml.cs @@ -844,6 +844,11 @@ async Task CallGetUnityUpdates() updatesSource = items.ToArray(); if (updatesSource == null) return; dataGridUpdates.ItemsSource = updatesSource; + // if search string is set, then filter it (after data is loaded) + if (string.IsNullOrEmpty(txtSearchBoxUpdates.Text) == false) + { + FilterUpdates(); + } } async void GoLookForUpdatesForThisUnity() @@ -857,7 +862,10 @@ async void GoLookForUpdatesForThisUnity() if (dataGridUpdates.ItemsSource != null) { tabControl.SelectedIndex = 2; - txtSearchBoxUpdates.Text = ""; // need to clear old results first + // need to clear old results first + txtSearchBoxUpdates.Text = ""; + // reset filter + rdoAll.IsChecked = true; // NOTE for now, just set filter to current version, minus patch version "2021.1.7f1" > "2021.1" txtSearchBoxUpdates.Text = unity.Version.Substring(0, unity.Version.LastIndexOf('.')); @@ -1168,6 +1176,11 @@ private async void OnTabSelectionChanged(object sender, SelectionChangedEventArg updatesSource = items.ToArray(); if (updatesSource == null) return; dataGridUpdates.ItemsSource = updatesSource; + // if search string is set, then filter it (after data is loaded) + if (string.IsNullOrEmpty(txtSearchBoxUpdates.Text) == false) + { + FilterUpdates(); + } } } } From 54dab25c3333ad0fdf2bf330cecf72fbdf7e5da1 Mon Sep 17 00:00:00 2001 From: unitycoder Date: Wed, 15 Jan 2025 22:30:46 +0200 Subject: [PATCH 04/67] add tooltip to LastModified column (to see exact timestamp) --- .../Converters/LastModifiedConverter.cs | 18 +++++++++++++++++ UnityLauncherPro/MainWindow.xaml | 20 ++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/UnityLauncherPro/Converters/LastModifiedConverter.cs b/UnityLauncherPro/Converters/LastModifiedConverter.cs index 710dd14..a0f2b45 100644 --- a/UnityLauncherPro/Converters/LastModifiedConverter.cs +++ b/UnityLauncherPro/Converters/LastModifiedConverter.cs @@ -23,5 +23,23 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu return DateTime.ParseExact((string)value, MainWindow.currentDateFormat, culture); } + } + + // just for tooltip + [ValueConversion(typeof(DateTime), typeof(String))] + public class LastModifiedConverterTooltip : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null) return null; + DateTime date = (DateTime)value; + return date.ToString(MainWindow.currentDateFormat); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return DateTime.ParseExact((string)value, MainWindow.currentDateFormat, culture); + } + } } diff --git a/UnityLauncherPro/MainWindow.xaml b/UnityLauncherPro/MainWindow.xaml index 54de073..4eac88e 100644 --- a/UnityLauncherPro/MainWindow.xaml +++ b/UnityLauncherPro/MainWindow.xaml @@ -10,6 +10,7 @@ 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"> + @@ -142,13 +143,30 @@ - + + + + + From 735d4481589a0f4f367a622f09a5fbda96b4addc Mon Sep 17 00:00:00 2001 From: unitycoder Date: Wed, 15 Jan 2025 23:58:09 +0200 Subject: [PATCH 05/67] add optional Explorer context menu to Install (and run) selected APK file to device (fixes #181) --- UnityLauncherPro/MainWindow.xaml | 5 +- UnityLauncherPro/MainWindow.xaml.cs | 49 ++++- .../Properties/Settings.Designer.cs | 12 ++ UnityLauncherPro/Properties/Settings.settings | 3 + UnityLauncherPro/Tools.cs | 175 ++++++++++++++++++ 5 files changed, 239 insertions(+), 5 deletions(-) diff --git a/UnityLauncherPro/MainWindow.xaml b/UnityLauncherPro/MainWindow.xaml index 4eac88e..7607b39 100644 --- a/UnityLauncherPro/MainWindow.xaml +++ b/UnityLauncherPro/MainWindow.xaml @@ -7,7 +7,7 @@ xmlns:System="clr-namespace:System;assembly=mscorlib" xmlns:converters="clr-namespace:UnityLauncherPro.Converters" x:Class="UnityLauncherPro.MainWindow" mc:Ignorable="d" - 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"> + 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"> @@ -842,7 +842,8 @@ - + + diff --git a/UnityLauncherPro/MainWindow.xaml.cs b/UnityLauncherPro/MainWindow.xaml.cs index b464fe2..d0897a4 100644 --- a/UnityLauncherPro/MainWindow.xaml.cs +++ b/UnityLauncherPro/MainWindow.xaml.cs @@ -276,8 +276,32 @@ void HandleCommandLineLaunch() string[] args = Environment.GetCommandLineArgs(); if (args != null && args.Length > 2) { + + // first argument needs to be -projectPath var commandLineArgs = args[1]; + + // if install argument, then just try to install this file (APK) + if (commandLineArgs == "-install") + { + Console.WriteLine("Launching from commandline..."); + + // path + var apkPath = args[2]; + + // resolve full path if path parameter isn't a rooted path + //if (!Path.IsPathRooted(apkPath)) + //{ + // apkPath = Directory.GetCurrentDirectory() + apkPath; + //} + //MessageBox.Show("APK install not implemented yet: " + apkPath); + // try installing it + Tools.InstallAPK(apkPath); + Environment.Exit(0); + } + else + + if (commandLineArgs == "-projectPath") { Console.WriteLine("Launching from commandline..."); @@ -328,7 +352,7 @@ void HandleCommandLineLaunch() } // quit after launch if enabled in settings - if (Properties.Settings.Default.closeAfterExplorer == true) + if (Settings.Default.closeAfterExplorer == true) { Environment.Exit(0); } @@ -493,6 +517,7 @@ void LoadSettings() chkMinimizeToTaskbar.IsChecked = Settings.Default.minimizeToTaskbar; chkRegisterExplorerMenu.IsChecked = Settings.Default.registerExplorerMenu; + chkRegisterInstallAPKMenu.IsChecked = Settings.Default.registerExplorerMenuAPK; // update settings window chkQuitAfterCommandline.IsChecked = Settings.Default.closeAfterExplorer; @@ -3562,7 +3587,7 @@ private void menuInstallLastAPK_Click(object sender, RoutedEventArgs e) } // install the apk using ADB using cmd (-r = replace app) - var cmd = "cmd.exe";// /C adb install -r \"{playerPath}\""; + var cmd = "cmd.exe"; var pars = $"/C adb install -r \"{playerPath}\""; string packageName = null; @@ -3928,7 +3953,7 @@ private async void chkDisableUnityHubLaunch_Checked(object sender, RoutedEventAr { if (!this.IsActive) return; // Don't run code during window initialization - Console.WriteLine((bool)chkDisableUnityHubLaunch.IsChecked); + //Console.WriteLine((bool)chkDisableUnityHubLaunch.IsChecked); if ((bool)chkDisableUnityHubLaunch.IsChecked) { @@ -3987,6 +4012,24 @@ private async Task CloseHubPipeAsync() } } + private void chkRegisterInstallAPKMenu_Checked(object sender, RoutedEventArgs e) + { + if (this.IsActive == false) return; // dont run code on window init + + if ((bool)chkRegisterInstallAPKMenu.IsChecked) + { + Tools.AddContextMenuRegistryAPKInstall(contextRegRoot); + } + else // remove + { + Tools.RemoveContextMenuRegistryAPKInstall(contextRegRoot); + } + + Settings.Default.registerExplorerMenuAPK = (bool)chkRegisterInstallAPKMenu.IsChecked; + Settings.Default.Save(); + + } + //private void menuProjectProperties_Click(object sender, RoutedEventArgs e) diff --git a/UnityLauncherPro/Properties/Settings.Designer.cs b/UnityLauncherPro/Properties/Settings.Designer.cs index f024741..c5b100d 100644 --- a/UnityLauncherPro/Properties/Settings.Designer.cs +++ b/UnityLauncherPro/Properties/Settings.Designer.cs @@ -613,5 +613,17 @@ public bool disableUnityHubLaunch { this["disableUnityHubLaunch"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool registerExplorerMenuAPK { + get { + return ((bool)(this["registerExplorerMenuAPK"])); + } + set { + this["registerExplorerMenuAPK"] = value; + } + } } } diff --git a/UnityLauncherPro/Properties/Settings.settings b/UnityLauncherPro/Properties/Settings.settings index 918912e..0af7fcb 100644 --- a/UnityLauncherPro/Properties/Settings.settings +++ b/UnityLauncherPro/Properties/Settings.settings @@ -154,5 +154,8 @@ False + + False + \ No newline at end of file diff --git a/UnityLauncherPro/Tools.cs b/UnityLauncherPro/Tools.cs index 7ce8ffb..588c387 100644 --- a/UnityLauncherPro/Tools.cs +++ b/UnityLauncherPro/Tools.cs @@ -1,6 +1,7 @@ using Microsoft.Win32; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; @@ -1278,6 +1279,56 @@ public static void AddContextMenuRegistry(string contextRegRoot) } } + public static void AddContextMenuRegistryAPKInstall(string contextRegRoot) + { + // Define the registry key path for .apk file association + string apkFileTypeRegPath = @"Software\Classes\.apk"; + + // Open or create the registry key for .apk files + RegistryKey apkKey = Registry.CurrentUser.OpenSubKey(apkFileTypeRegPath, true); + + if (apkKey == null) + { + apkKey = Registry.CurrentUser.CreateSubKey(apkFileTypeRegPath); + } + + if (apkKey != null) + { + // Create or open the Shell subkey for context menu options + RegistryKey shellKey = apkKey.CreateSubKey("shell", true); + + if (shellKey != null) + { + var appName = "UnityLauncherPro"; + // Create a subkey for the app's context menu item + RegistryKey appKey = shellKey.CreateSubKey(appName, true); + + if (appKey != null) + { + appKey.SetValue("", "Install with " + appName); // Display name in context menu + appKey.SetValue("Icon", "\"" + Process.GetCurrentProcess().MainModule.FileName + "\""); + appKey.SetValue("Position", "Bottom"); // Set position to adjust order + + // Create the command subkey to specify the action + RegistryKey commandKey = appKey.CreateSubKey("command", true); + + if (commandKey != null) + { + // Build the command string to launch with -install argument + var executeString = "\"" + Process.GetCurrentProcess().MainModule.FileName + "\" -install \"%1\""; + commandKey.SetValue("", executeString); + } + } + } + } + else + { + Console.WriteLine("Error> Cannot create or access registry key for .apk file association: " + apkFileTypeRegPath); + } + } + + + /// /// uninstall context menu item from registry /// @@ -1305,6 +1356,37 @@ public static void RemoveContextMenuRegistry(string contextRegRoot) } } + public static void RemoveContextMenuRegistryAPKInstall(string contextRegRoot) + { + // Define the registry key path for .apk file association + string apkFileTypeRegPath = @"Software\Classes\.apk\shell"; + + // Open the registry key for the shell context menu + RegistryKey shellKey = Registry.CurrentUser.OpenSubKey(apkFileTypeRegPath, true); + + if (shellKey != null) + { + var appName = "UnityLauncherPro"; + + // Check if the app's context menu key exists + RegistryKey appKey = shellKey.OpenSubKey(appName, false); + if (appKey != null) + { + // Delete the app's context menu key + shellKey.DeleteSubKeyTree(appName); + Console.WriteLine("Removed context menu for .apk files."); + } + else + { + Console.WriteLine("No context menu found for .apk files."); + } + } + else + { + Console.WriteLine("Error> Cannot find registry key for .apk shell context: " + apkFileTypeRegPath); + } + } + /// /// reads .git/HEAD file from the project to get current branch name /// @@ -2505,6 +2587,99 @@ internal static string GetSRP(string projectPath) } } + + internal static void InstallAPK(string ApkPath) + { + try + { + var cmd = "cmd.exe"; + var pars = $"/C adb install -r \"{ApkPath}\""; // Use /C to execute and close the window after finishing + + var processStartInfo = new ProcessStartInfo + { + FileName = cmd, + Arguments = pars, + RedirectStandardOutput = true, // Capture output to wait for completion + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = false + }; + + string installOutput = null; + string installError = null; + + using (var installProcess = Process.Start(processStartInfo)) + { + installOutput = installProcess.StandardOutput.ReadToEnd(); + installError = installProcess.StandardError.ReadToEnd(); + installProcess.WaitForExit(); + + if (installProcess.ExitCode != 0 || !string.IsNullOrEmpty(installError)) + { + SetStatus($"Error installing APK: {installError.Trim()}\n{installOutput.Trim()}"); + return; + } + } + + // Attempt to extract package name using aapt + var aaptCmd = $"aapt dump badging \"{ApkPath}\" | findstr package:"; + var aaptProcessStartInfo = new ProcessStartInfo + { + FileName = "cmd.exe", + Arguments = $"/C {aaptCmd}", + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + string packageName = null; + using (var process = Process.Start(aaptProcessStartInfo)) + { + var output = process.StandardOutput.ReadToEnd(); + process.WaitForExit(); + + var match = System.Text.RegularExpressions.Regex.Match(output, "package: name='(.*?)'"); + if (match.Success) + { + packageName = match.Groups[1].Value; + } + } + + if (!string.IsNullOrEmpty(packageName)) + { + // Run the application using adb + var runPars = $"/C adb shell monkey -p {packageName} 1"; + var runProcessStartInfo = new ProcessStartInfo + { + FileName = cmd, + Arguments = runPars, + UseShellExecute = true, + CreateNoWindow = false, + WindowStyle = ProcessWindowStyle.Normal + }; + Process.Start(runProcessStartInfo); + + SetStatus($"Installed and launched APK with package name: {packageName}"); + } + else + { + SetStatus("ADB install completed, but failed to extract package name. Application not launched."); + } + } + catch (Win32Exception ex) + { + // Handle case where adb or aapt is not found + SetStatus($"Error: Required tool not found. Ensure adb and aapt are installed and added to PATH. Details: {ex.Message}"); + } + catch (Exception ex) + { + // Handle other unexpected exceptions + SetStatus($"An unexpected error occurred: {ex.Message}"); + } + } + + + } // class } // namespace From 6cacad49b5bbef9d7cb9e6698adc871069fb7843 Mon Sep 17 00:00:00 2001 From: mika Date: Mon, 20 Jan 2025 20:14:22 +0200 Subject: [PATCH 06/67] test #GITBUILD --- .github/workflows/main.yml | 64 +++++++++++++++----------------------- 1 file changed, 25 insertions(+), 39 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ba5e6aa..9504c75 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,76 +1,62 @@ -# This is a basic workflow to help you get started with Actions name: CI -# Controls when the workflow will run on: - # Triggers the workflow on push or pull request events but only for the master branch push: branches: [ master ] - - # Allows you to run this workflow manually from the Actions tab workflow_dispatch: -# A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: - # This workflow contains a single job called "build" build: - # The type of runner that the job will run on runs-on: windows-2019 - # Steps represent a sequence of tasks that will be executed as part of the job steps: - - name: Check Commit and Install 7Zip PowerShell Module + - name: Check Commit Message shell: powershell run: | - # cancel early, if not build commit $strVal ='${{ github.event.commits[0].message }}' - # Convert commit message to a single line if multiline $singleLineStrVal = $strVal -replace "`r`n", " " -replace "`n", " " - if($singleLineStrVal -match '#GITBUILD') - { - Write-Host 'True' + if($singleLineStrVal -match '#GITBUILD') { + Write-Host 'Build commit detected. Proceeding with build...' + echo "build_trigger=true" >> $env:GITHUB_ENV } else { - Write-Host 'False' - exit(1) - } - Install-Module 7Zip4PowerShell -Force -Verbose + Write-Host 'No build commit. Skipping build steps...' + echo "build_trigger=false" >> $env:GITHUB_ENV - uses: actions/checkout@v2 - - name: Restore NuGet packages - run: nuget restore UnityLauncherPro.sln - - - name: Build Binary - shell: cmd - run: call .\Build.cmd - - - name: Build Artifact - shell: cmd - run: call .\ArtifactBuild.cmd + - name: Conditional Build Steps + if: env.build_trigger == 'true' + steps: + - name: Install 7Zip PowerShell Module + shell: powershell + run: Install-Module 7Zip4PowerShell -Force -Verbose + + - name: Restore NuGet packages + run: nuget restore UnityLauncherPro.sln + + - name: Build Binary + shell: cmd + run: call .\Build.cmd + + - name: Build Artifact + shell: cmd + run: call .\ArtifactBuild.cmd - name: Get current date and time id: datetime run: | echo "current_datetime=$(date +'%d/%m/%Y %H:%M')" >> $GITHUB_ENV - # Step to get previous tag and commits - name: Get commits since last release id: get_commits shell: bash run: | - # Get the most recent tag PREV_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "none") if [ "$PREV_TAG" = "none" ]; then - echo "No previous tag found, listing all commits" COMMITS=$(git log --pretty=format:"* %s" --no-merges) else - echo "Previous tag: $PREV_TAG" - # List commits since last tag COMMITS=$(git log $PREV_TAG..HEAD --pretty=format:"* %s" --no-merges) fi - echo "Commits since last release: $COMMITS" - - # Save commits to environment file for later use echo "commits=$COMMITS" >> $GITHUB_ENV - name: Create Release @@ -87,8 +73,8 @@ jobs: ### Commits in this release: ${{ env.commits }} draft: false - prerelease: false - + prerelease: false + - name: Upload Release Asset id: upload-release-asset uses: actions/upload-release-asset@v1 From eed9d9acbba14f105ddc38dc30ea18f64932be9c Mon Sep 17 00:00:00 2001 From: mika Date: Mon, 20 Jan 2025 20:16:19 +0200 Subject: [PATCH 07/67] test #GITBUILD --- .github/workflows/main.yml | 57 ++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9504c75..dbbdef7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,64 +1,92 @@ name: CI on: + # Triggers the workflow on push or pull request events but only for the master branch push: branches: [ master ] + + # Allows you to run this workflow manually from the Actions tab workflow_dispatch: jobs: + # This workflow contains a single job called "build" build: + # The type of runner that the job will run on runs-on: windows-2019 + # Steps represent a sequence of tasks that will be executed as part of the job steps: + # Step to check if the commit message contains #GITBUILD - name: Check Commit Message shell: powershell run: | - $strVal ='${{ github.event.commits[0].message }}' + # Get the commit message + $strVal = '${{ github.event.commits[0].message }}' + # Convert commit message to a single line if multiline $singleLineStrVal = $strVal -replace "`r`n", " " -replace "`n", " " - if($singleLineStrVal -match '#GITBUILD') { + if ($singleLineStrVal -match '#GITBUILD') { Write-Host 'Build commit detected. Proceeding with build...' echo "build_trigger=true" >> $env:GITHUB_ENV } else { Write-Host 'No build commit. Skipping build steps...' echo "build_trigger=false" >> $env:GITHUB_ENV + # Step to ensure the repository is checked out - uses: actions/checkout@v2 + # Conditional steps for building the project - name: Conditional Build Steps if: env.build_trigger == 'true' - steps: - - name: Install 7Zip PowerShell Module - shell: powershell - run: Install-Module 7Zip4PowerShell -Force -Verbose + run: echo "Build steps will proceed because commit contains #GITBUILD." - - name: Restore NuGet packages - run: nuget restore UnityLauncherPro.sln + # Install 7Zip PowerShell module + - name: Install 7Zip PowerShell Module + if: env.build_trigger == 'true' + shell: powershell + run: Install-Module 7Zip4PowerShell -Force -Verbose - - name: Build Binary - shell: cmd - run: call .\Build.cmd + # Restore NuGet packages + - name: Restore NuGet packages + if: env.build_trigger == 'true' + run: nuget restore UnityLauncherPro.sln - - name: Build Artifact - shell: cmd - run: call .\ArtifactBuild.cmd + # Build the binary + - name: Build Binary + if: env.build_trigger == 'true' + shell: cmd + run: call .\Build.cmd + + # Build the artifact + - name: Build Artifact + if: env.build_trigger == 'true' + shell: cmd + run: call .\ArtifactBuild.cmd + # Get the current date and time - name: Get current date and time id: datetime run: | + # Save the current date and time to an environment variable echo "current_datetime=$(date +'%d/%m/%Y %H:%M')" >> $GITHUB_ENV + # Step to get previous tag and commits - name: Get commits since last release id: get_commits shell: bash run: | + # Get the most recent tag PREV_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "none") if [ "$PREV_TAG" = "none" ]; then + echo "No previous tag found, listing all commits" COMMITS=$(git log --pretty=format:"* %s" --no-merges) else + echo "Previous tag: $PREV_TAG" + # List commits since last tag COMMITS=$(git log $PREV_TAG..HEAD --pretty=format:"* %s" --no-merges) fi echo "commits=$COMMITS" >> $GITHUB_ENV + # Create a release - name: Create Release id: create_release uses: actions/create-release@latest @@ -75,6 +103,7 @@ jobs: draft: false prerelease: false + # Upload the release asset - name: Upload Release Asset id: upload-release-asset uses: actions/upload-release-asset@v1 From 61e8412d3b8ba99d41fb9addb6590cc405539c0a Mon Sep 17 00:00:00 2001 From: mika Date: Mon, 20 Jan 2025 20:20:09 +0200 Subject: [PATCH 08/67] test #GITBUILD --- .github/workflows/main.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dbbdef7..071e784 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -30,14 +30,15 @@ jobs: } else { Write-Host 'No build commit. Skipping build steps...' echo "build_trigger=false" >> $env:GITHUB_ENV + } # Step to ensure the repository is checked out - uses: actions/checkout@v2 - # Conditional steps for building the project - - name: Conditional Build Steps - if: env.build_trigger == 'true' - run: echo "Build steps will proceed because commit contains #GITBUILD." + # Inform if build steps are skipped + - name: Inform Skipped Build Steps + if: env.build_trigger != 'true' + run: echo "Skipping build steps because the commit message does not contain #GITBUILD." # Install 7Zip PowerShell module - name: Install 7Zip PowerShell Module @@ -79,7 +80,7 @@ jobs: if [ "$PREV_TAG" = "none" ]; then echo "No previous tag found, listing all commits" COMMITS=$(git log --pretty=format:"* %s" --no-merges) - else + else: echo "Previous tag: $PREV_TAG" # List commits since last tag COMMITS=$(git log $PREV_TAG..HEAD --pretty=format:"* %s" --no-merges) From ceae82ab49663e6f2d65026b50b51dccd590cc42 Mon Sep 17 00:00:00 2001 From: mika Date: Mon, 20 Jan 2025 20:25:20 +0200 Subject: [PATCH 09/67] test #GITBUILD --- .github/workflows/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 071e784..15c2917 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -80,11 +80,12 @@ jobs: if [ "$PREV_TAG" = "none" ]; then echo "No previous tag found, listing all commits" COMMITS=$(git log --pretty=format:"* %s" --no-merges) - else: + else echo "Previous tag: $PREV_TAG" # List commits since last tag COMMITS=$(git log $PREV_TAG..HEAD --pretty=format:"* %s" --no-merges) fi + # Save commits to the environment echo "commits=$COMMITS" >> $GITHUB_ENV # Create a release From 481cd51da27ddf346e5ffcb707aab7e79c60e4aa Mon Sep 17 00:00:00 2001 From: mika Date: Mon, 20 Jan 2025 20:29:44 +0200 Subject: [PATCH 10/67] test no build --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 15c2917..4f879ae 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -116,3 +116,4 @@ jobs: asset_path: ./UnityLauncherPro.zip asset_name: UnityLauncherPro.zip asset_content_type: application/zip + From e577e8357472c70b1afa09a4c6cfbd30d828124e Mon Sep 17 00:00:00 2001 From: mika Date: Mon, 20 Jan 2025 20:36:02 +0200 Subject: [PATCH 11/67] test no build --- .github/workflows/main.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4f879ae..7d7a92f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -38,7 +38,9 @@ jobs: # Inform if build steps are skipped - name: Inform Skipped Build Steps if: env.build_trigger != 'true' - run: echo "Skipping build steps because the commit message does not contain #GITBUILD." + shell: powershell + run: | + Write-Host "Skipping build steps because the commit message does not contain #GITBUILD." # Install 7Zip PowerShell module - name: Install 7Zip PowerShell Module @@ -116,4 +118,3 @@ jobs: asset_path: ./UnityLauncherPro.zip asset_name: UnityLauncherPro.zip asset_content_type: application/zip - From 39275f4a83f30acba244b4bcc2679133ec34afea Mon Sep 17 00:00:00 2001 From: mika Date: Mon, 20 Jan 2025 20:39:19 +0200 Subject: [PATCH 12/67] test no build --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7d7a92f..72de79f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -94,6 +94,7 @@ jobs: - name: Create Release id: create_release uses: actions/create-release@latest + if: env.build_trigger == 'true' # Execute only if build was triggered env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -111,6 +112,7 @@ jobs: - name: Upload Release Asset id: upload-release-asset uses: actions/upload-release-asset@v1 + if: env.build_trigger == 'true' # Execute only if build was triggered env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From 63d3763e25c45ae08842e949616c38fd18947eb9 Mon Sep 17 00:00:00 2001 From: mika Date: Mon, 20 Jan 2025 20:43:19 +0200 Subject: [PATCH 13/67] test no build 2 --- .github/workflows/main.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 72de79f..55732d2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -68,6 +68,7 @@ jobs: # Get the current date and time - name: Get current date and time id: datetime + if: env.build_trigger == 'true' # Only run if build was triggered run: | # Save the current date and time to an environment variable echo "current_datetime=$(date +'%d/%m/%Y %H:%M')" >> $GITHUB_ENV @@ -75,6 +76,7 @@ jobs: # Step to get previous tag and commits - name: Get commits since last release id: get_commits + if: env.build_trigger == 'true' # Only run if build was triggered shell: bash run: | # Get the most recent tag @@ -93,8 +95,8 @@ jobs: # Create a release - name: Create Release id: create_release - uses: actions/create-release@latest if: env.build_trigger == 'true' # Execute only if build was triggered + uses: actions/create-release@latest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -111,8 +113,8 @@ jobs: # Upload the release asset - name: Upload Release Asset id: upload-release-asset - uses: actions/upload-release-asset@v1 if: env.build_trigger == 'true' # Execute only if build was triggered + uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From 9bde3e2830330a3d293106f430b6980b9199bc8c Mon Sep 17 00:00:00 2001 From: mika Date: Mon, 20 Jan 2025 20:45:01 +0200 Subject: [PATCH 14/67] test #GITBUILD --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 55732d2..ba9367a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -122,3 +122,4 @@ jobs: asset_path: ./UnityLauncherPro.zip asset_name: UnityLauncherPro.zip asset_content_type: application/zip + From 758e4c289b518910342b16d84d7e1b42e8c978e4 Mon Sep 17 00:00:00 2001 From: unitycoder Date: Sun, 2 Feb 2025 16:40:20 +0200 Subject: [PATCH 15/67] newproject: add forceDX11 checkbox (fixes #182) --- UnityLauncherPro/MainWindow.xaml.cs | 2 +- UnityLauncherPro/NewProject.xaml | 18 +++++++++++------- UnityLauncherPro/NewProject.xaml.cs | 10 ++++++++++ UnityLauncherPro/Tools.cs | 4 ++-- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/UnityLauncherPro/MainWindow.xaml.cs b/UnityLauncherPro/MainWindow.xaml.cs index d0897a4..a0f8913 100644 --- a/UnityLauncherPro/MainWindow.xaml.cs +++ b/UnityLauncherPro/MainWindow.xaml.cs @@ -2124,7 +2124,7 @@ void CreateNewEmptyProject(string targetFolder = null) Console.WriteLine("Create project " + NewProject.newVersion + " : " + rootFolder); if (string.IsNullOrEmpty(rootFolder)) return; - var p = Tools.FastCreateProject(NewProject.newVersion, rootFolder, NewProject.newProjectName, NewProject.templateZipPath, NewProject.platformsForThisUnity, NewProject.selectedPlatform, (bool)chkUseInitScript.IsChecked, initScriptFileFullPath); + var p = Tools.FastCreateProject(NewProject.newVersion, rootFolder, NewProject.newProjectName, NewProject.templateZipPath, NewProject.platformsForThisUnity, NewProject.selectedPlatform, (bool)chkUseInitScript.IsChecked, initScriptFileFullPath, NewProject.forceDX11); // add to list (just in case new project fails to start, then folder is already generated..) if (p != null) AddNewProjectToList(p); diff --git a/UnityLauncherPro/NewProject.xaml b/UnityLauncherPro/NewProject.xaml index b42bb4c..f8d009c 100644 --- a/UnityLauncherPro/NewProject.xaml +++ b/UnityLauncherPro/NewProject.xaml @@ -5,7 +5,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:UnityLauncherPro" mc:Ignorable="d" - Title="Create New Project" Height="480" Width="450" Background="{DynamicResource ThemeDarkestBackground}" PreviewKeyDown="Window_PreviewKeyDown" ResizeMode="NoResize" WindowStartupLocation="CenterOwner" ShowInTaskbar="True"> + Title="Create New Project" Height="480" Width="500" Background="{DynamicResource ThemeDarkestBackground}" PreviewKeyDown="Window_PreviewKeyDown" ResizeMode="NoResize" WindowStartupLocation="CenterOwner" ShowInTaskbar="True"> @@ -20,24 +20,28 @@ - - - + + + + - - - + + + + + - + From e6a8728964beba523d4a6426d8c6ba41ceb1e59a Mon Sep 17 00:00:00 2001 From: unitycoder Date: Tue, 8 Apr 2025 22:38:21 +0300 Subject: [PATCH 25/67] add tools button: exclude editor folders from windows defender, add context menu: exclude project from defender fixes #87, clear(set) statusbar when enable streamer mode, --- UnityLauncherPro/MainWindow.xaml | 6 +++ UnityLauncherPro/MainWindow.xaml.cs | 36 +++++++++++++++++ UnityLauncherPro/Tools.cs | 60 +++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) diff --git a/UnityLauncherPro/MainWindow.xaml b/UnityLauncherPro/MainWindow.xaml index d8f4c5b..518c70e 100644 --- a/UnityLauncherPro/MainWindow.xaml +++ b/UnityLauncherPro/MainWindow.xaml @@ -228,6 +228,9 @@ + + + @@ -598,6 +601,9 @@ + diff --git a/UnityLauncherPro/MainWindow.xaml.cs b/UnityLauncherPro/MainWindow.xaml.cs index d122815..c32801f 100644 --- a/UnityLauncherPro/MainWindow.xaml.cs +++ b/UnityLauncherPro/MainWindow.xaml.cs @@ -2187,6 +2187,8 @@ private void ChkStreamerMode_Checked(object sender, RoutedEventArgs e) { RefreshRecentProjects(); } + + SetStatus("Streamer mode " + (isChecked ? "enabled" : "disabled"), MessageType.Info); } private void ChkShowPlatform_Checked(object sender, RoutedEventArgs e) @@ -4030,7 +4032,41 @@ private void chkRegisterInstallAPKMenu_Checked(object sender, RoutedEventArgs e) } + private void btnExcludeFolderForDefender_Click(object sender, RoutedEventArgs e) + { + var foldersToExclude = new List(); + foreach (var unity in unityInstallationsSource) + { + var unityEditorFolder = Path.GetDirectoryName(unity.Path); + //Console.WriteLine(unityEditorFolder); + if (Directory.Exists(unityEditorFolder)) + { + foldersToExclude.Add(unityEditorFolder); + } + } + + Tools.RunExclusionElevated(foldersToExclude); + } + private void menuExcludeFromDefender_Click(object sender, RoutedEventArgs e) + { + var proj = GetSelectedProject(); + if (proj == null) return; + if (Directory.Exists(proj.Path) == false) return; + + var foldersToExclude = new List(); + foldersToExclude.Add(proj.Path); + var res = Tools.RunExclusionElevated(foldersToExclude, silent: true); + var tempPath = ((chkStreamerMode.IsChecked == true) ? "***" : proj.Path); + if (res == false) + { + SetStatus("Failed to add exclusion for: " + tempPath); + } + else + { + SetStatus("Added exclusion for project path: " + tempPath); + } + } //private void menuProjectProperties_Click(object sender, RoutedEventArgs e) //{ diff --git a/UnityLauncherPro/Tools.cs b/UnityLauncherPro/Tools.cs index 9863af7..363f782 100644 --- a/UnityLauncherPro/Tools.cs +++ b/UnityLauncherPro/Tools.cs @@ -2696,6 +2696,66 @@ internal static void InstallAPK(string ApkPath) } } + // exclude folders from windows defender + internal static bool RunExclusionElevated(IEnumerable paths, bool silent = false) + { + var escapedPaths = new List(); + foreach (var rawPath in paths) + { + var path = rawPath.Trim(); + string safePath = path.Replace("'", "''"); + escapedPaths.Add($"'{safePath}'"); + } + + string joinedPaths = string.Join(", ", escapedPaths); + string psCommand = $"Add-MpPreference -ExclusionPath {joinedPaths}"; + + string fullCommand; + + if (silent) + { + // No output, just run the command silently + fullCommand = psCommand; + } + else + { + // Show command and keep window open + var quotedPathsForDisplay = string.Join(", ", escapedPaths.ConvertAll(p => $"'{p.Trim('\'')}'")); + string displayCommand = $"Add-MpPreference -ExclusionPath {quotedPathsForDisplay}"; + fullCommand = $"Write-Host 'Running: {displayCommand}'; {psCommand}; Write-Host ''; Write-Host 'Done. Press any key to exit...'; pause"; + } + + var startInfo = new ProcessStartInfo + { + FileName = "powershell.exe", + Arguments = silent + ? $"-WindowStyle Hidden -Command \"{fullCommand}\"" + : $"-NoExit -Command \"{fullCommand}\"", + UseShellExecute = true, + Verb = "runas", // Requires admin rights + WindowStyle = silent ? ProcessWindowStyle.Hidden : ProcessWindowStyle.Normal + }; + + try + { + Process.Start(startInfo); + } + catch (Win32Exception) + { + if (!silent) + { + MessageBox.Show("Operation cancelled or failed due to insufficient privileges.", "Cancelled", MessageBoxButton.OK, MessageBoxImage.Warning); + } + return false; + } + + return true; + } + + + + + } // class From ee7cb29287cdc9c834692ebe9710bfd9a599baf9 Mon Sep 17 00:00:00 2001 From: unitycoder Date: Wed, 9 Apr 2025 23:04:28 +0300 Subject: [PATCH 26/67] move crash recovery scene fixes #186 --- UnityLauncherPro/Tools.cs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/UnityLauncherPro/Tools.cs b/UnityLauncherPro/Tools.cs index 363f782..3521de3 100644 --- a/UnityLauncherPro/Tools.cs +++ b/UnityLauncherPro/Tools.cs @@ -400,7 +400,7 @@ static bool CheckCrashBackupScene(string projectPath) var recoveryFile = Path.Combine(projectPath, "Temp", "__Backupscenes", "0.backup"); if (File.Exists(recoveryFile)) { - var result = MessageBox.Show("Crash recovery scene found, do you want to copy it into Assets/_Recovery/-folder?", "UnityLauncherPro - Scene Recovery", MessageBoxButton.YesNo, MessageBoxImage.Question); + var result = MessageBox.Show("Crash recovery scene found, do you want to MOVE it into Assets/_Recovery/-folder?", "UnityLauncherPro - Scene Recovery", MessageBoxButton.YesNo, MessageBoxImage.Question); if (result == MessageBoxResult.Yes) { var restoreFolder = Path.Combine(projectPath, "Assets", "_Recovery"); @@ -412,7 +412,22 @@ static bool CheckCrashBackupScene(string projectPath) { Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; var uniqueFileName = "Recovered_Scene" + unixTimestamp + ".unity"; - File.Copy(recoveryFile, Path.Combine(restoreFolder, uniqueFileName)); + + try + { + File.Move(recoveryFile, Path.Combine(restoreFolder, uniqueFileName)); + // remove folder, otherwise unity 6000.2 asks for recovery + Directory.Delete(Path.Combine(projectPath, "Temp", "__Backupscenes"), true); + + Console.WriteLine("moved file to "+ uniqueFileName); + } + catch (IOException) + { + // if move failed, try copy + File.Copy(recoveryFile, Path.Combine(restoreFolder, uniqueFileName)); + Console.WriteLine("copied file"); + } + Console.WriteLine("Recovered crashed scene into: " + restoreFolder); } else @@ -2746,7 +2761,7 @@ internal static bool RunExclusionElevated(IEnumerable paths, bool silent { MessageBox.Show("Operation cancelled or failed due to insufficient privileges.", "Cancelled", MessageBoxButton.OK, MessageBoxImage.Warning); } - return false; + return false; } return true; From d46c20fa4e5d29b1b448155ea0af4d02d08f655a Mon Sep 17 00:00:00 2001 From: unitycoder Date: Thu, 10 Apr 2025 00:16:47 +0300 Subject: [PATCH 27/67] clean unused usings --- UnityLauncherPro/App.xaml.cs | 8 +------- UnityLauncherPro/Data/ThemeColor.cs | 1 - UnityLauncherPro/UpgradeWindow.xaml.cs | 4 +--- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/UnityLauncherPro/App.xaml.cs b/UnityLauncherPro/App.xaml.cs index 180b5f2..d14e416 100644 --- a/UnityLauncherPro/App.xaml.cs +++ b/UnityLauncherPro/App.xaml.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Linq; -using System.Threading.Tasks; -using System.Windows; +using System.Windows; namespace UnityLauncherPro { diff --git a/UnityLauncherPro/Data/ThemeColor.cs b/UnityLauncherPro/Data/ThemeColor.cs index 24a6232..2dcbd02 100644 --- a/UnityLauncherPro/Data/ThemeColor.cs +++ b/UnityLauncherPro/Data/ThemeColor.cs @@ -1,5 +1,4 @@ using System; -using System.ComponentModel; using System.Globalization; using System.Windows.Data; using System.Windows.Media; diff --git a/UnityLauncherPro/UpgradeWindow.xaml.cs b/UnityLauncherPro/UpgradeWindow.xaml.cs index 866c05e..128e3f9 100644 --- a/UnityLauncherPro/UpgradeWindow.xaml.cs +++ b/UnityLauncherPro/UpgradeWindow.xaml.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Input; From bb7fb4dab8df404ef418ca0b06a0d40048a07f53 Mon Sep 17 00:00:00 2001 From: unitycoder Date: Sat, 12 Apr 2025 23:13:42 +0300 Subject: [PATCH 28/67] optimize startup #54 (remove origResourceColors) --- UnityLauncherPro/MainWindow.xaml.cs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/UnityLauncherPro/MainWindow.xaml.cs b/UnityLauncherPro/MainWindow.xaml.cs index c32801f..ca18efd 100644 --- a/UnityLauncherPro/MainWindow.xaml.cs +++ b/UnityLauncherPro/MainWindow.xaml.cs @@ -66,8 +66,6 @@ public partial class MainWindow : Window string defaultDateFormat = "dd/MM/yyyy HH:mm:ss"; string adbLogCatArgs = defaultAdbLogCatArgs; - Dictionary origResourceColors = new Dictionary(); - string currentBuildReportProjectPath = null; string currentBuildPluginsRelativePath = null; //List> buildReports = new List>(); @@ -168,12 +166,6 @@ void Start() // build notifyicon (using windows.forms) notifyIcon.MouseClick += new System.Windows.Forms.MouseEventHandler(NotifyIcon_MouseClick); - // get original colors - foreach (DictionaryEntry item in Application.Current.Resources.MergedDictionaries[0]) - { - origResourceColors[item.Key.ToString()] = (SolidColorBrush)item.Value; - } - ApplyTheme(txtCustomThemeFile.Text); // for autostart with minimized @@ -198,7 +190,7 @@ void Start() if (Settings.Default.disableUnityHubLaunch == true) StartHubPipe(); isInitializing = false; - } + } // Start() private static NamedPipeServerStream hubPipeServer; private CancellationTokenSource _hubCancellationTokenSource; @@ -2762,9 +2754,12 @@ void ApplyTheme(string themeFile) void ResetTheme() { - foreach (KeyValuePair item in origResourceColors) + foreach (DictionaryEntry item in Application.Current.Resources.MergedDictionaries[0]) { - Application.Current.Resources[item.Key] = item.Value; + if (item.Key is string key && item.Value is SolidColorBrush brush) + { + Application.Current.Resources[key] = brush; + } } } From 3bee9e4386213cebbbe5b44611acc206f4ae5650 Mon Sep 17 00:00:00 2001 From: unitycoder Date: Sun, 13 Apr 2025 22:56:37 +0300 Subject: [PATCH 29/67] optimizing startup time: cleanup setfocustogrid, use delayed setfocustogrid --- UnityLauncherPro/MainWindow.xaml.cs | 4 ++- UnityLauncherPro/Tools.cs | 39 ++++++++++++----------------- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/UnityLauncherPro/MainWindow.xaml.cs b/UnityLauncherPro/MainWindow.xaml.cs index ca18efd..4509092 100644 --- a/UnityLauncherPro/MainWindow.xaml.cs +++ b/UnityLauncherPro/MainWindow.xaml.cs @@ -22,6 +22,7 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shell; +using System.Windows.Threading; using UnityLauncherPro.Data; using UnityLauncherPro.Helpers; using UnityLauncherPro.Properties; @@ -1318,7 +1319,8 @@ private void GridRecent_Loaded(object sender, RoutedEventArgs e) // if coming from explorer launch, and missing unity version, projectsource is still null? if (projectsSource != null) SetStatus("Ready (" + projectsSource.Count + " projects)"); RefreshSorting(); - Tools.SetFocusToGrid(gridRecent); + //Tools.SetFocusToGrid(gridRecent); + Dispatcher.InvokeAsync(() => Tools.SetFocusToGrid(gridRecent), DispatcherPriority.ApplicationIdle); } void RefreshSorting() diff --git a/UnityLauncherPro/Tools.cs b/UnityLauncherPro/Tools.cs index 3521de3..9caf003 100644 --- a/UnityLauncherPro/Tools.cs +++ b/UnityLauncherPro/Tools.cs @@ -17,6 +17,7 @@ using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; +using System.Windows.Threading; using UnityLauncherPro.Helpers; namespace UnityLauncherPro @@ -1592,47 +1593,39 @@ public static bool HasFocus(DependencyObject obj, Control control, bool checkChi public static void SetFocusToGrid(DataGrid targetGrid, int index = -1) { - // set main component focus - //targetGrid.Focus(); - //Keyboard.Focus(targetGrid); - - // no items if (targetGrid.Items.Count < 1) return; - // keep current row selected if (index == -1 && targetGrid.SelectedIndex > -1) index = targetGrid.SelectedIndex; - - // if no item selected, pick first if (index == -1) index = 0; targetGrid.SelectedIndex = index; - // set full focus + // Try get the row, if not realized yet, defer DataGridRow row = (DataGridRow)targetGrid.ItemContainerGenerator.ContainerFromIndex(index); if (row == null) { - targetGrid.UpdateLayout(); - if (index < targetGrid.Items.Count) - { - // scroll selected into view - targetGrid.ScrollIntoView(targetGrid.Items[index]); - row = (DataGridRow)targetGrid.ItemContainerGenerator.ContainerFromIndex(index); - } - else + targetGrid.ScrollIntoView(targetGrid.Items[index]); + // Defer the focus once row is generated + targetGrid.Dispatcher.InvokeAsync(() => { - Console.WriteLine("selected row out of bounds: " + index); - } + var newRow = (DataGridRow)targetGrid.ItemContainerGenerator.ContainerFromIndex(index); + if (newRow != null) + { + newRow.MoveFocus(new TraversalRequest(FocusNavigationDirection.Up)); + newRow.Focus(); + Keyboard.Focus(newRow); + } + }, DispatcherPriority.Background); } - // NOTE does this causes move below? - //row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); - if (row != null) + else { - row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Up)); // works better than Up + row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Up)); row.Focus(); Keyboard.Focus(row); } } + public static string BrowseForOutputFolder(string title, string initialDirectory = null) { // https://stackoverflow.com/a/50261723/5452781 From baa9b5c6fb58b3246a8fe219dfa7b7aaafa43589 Mon Sep 17 00:00:00 2001 From: mika Date: Thu, 17 Apr 2025 16:09:19 +0300 Subject: [PATCH 30/67] Update README.md added JetBrains supporter badge (for their Open Source Development License!) --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index d2ab77c..383ade0 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,9 @@ Handle all your Unity versions and Projects easily! - Select template for new project (template based on selected unity version) - And more: https://github.com/unitycoder/UnityLauncherPro/wiki/Launcher-Comparison +### Powered by +[![JetBrains logo.](https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.svg)](https://jb.gg/OpenSourceSupport) + ### Forum Thread https://forum.unity.com/threads/unity-launcher-launch-correct-unity-versions-for-each-project-automatically.488718/ From 249719a14ee8904b1ba984898f4b509e66e82924 Mon Sep 17 00:00:00 2001 From: mika Date: Tue, 22 Apr 2025 21:11:06 +0300 Subject: [PATCH 31/67] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 383ade0..b9414bb 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Pre-releases are sometimes available from dev branch: https://github.com/unityco ![image](https://github.com/unitycoder/UnityLauncherPro/assets/5438317/6f8dce07-c640-42db-a1ef-d8bcc7a80cc2) -![image](https://user-images.githubusercontent.com/5438317/206923022-4b4bb8ed-0351-408f-b1d3-82bd6eefbc45.png) +![Image](https://github.com/user-attachments/assets/e5f79e61-95e7-4792-92e2-616f76d601ed) ### Perform tasks on selected project ![image](https://github.com/unitycoder/UnityLauncherPro/assets/5438317/a0b468ba-e3a6-420b-8155-78bc32814752) From 4ced24b4560211a07c67024f802b8c37ba705e1a Mon Sep 17 00:00:00 2001 From: mika Date: Tue, 22 Apr 2025 21:19:34 +0300 Subject: [PATCH 32/67] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b9414bb..93dafb4 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Pre-releases are sometimes available from dev branch: https://github.com/unityco ![image](https://github.com/unitycoder/UnityLauncherPro/assets/5438317/6f8dce07-c640-42db-a1ef-d8bcc7a80cc2) -![Image](https://github.com/user-attachments/assets/e5f79e61-95e7-4792-92e2-616f76d601ed) +![Image](https://github.com/user-attachments/assets/fa4e004a-f3c6-47d5-996f-9b603048ad18) ### Perform tasks on selected project ![image](https://github.com/unitycoder/UnityLauncherPro/assets/5438317/a0b468ba-e3a6-420b-8155-78bc32814752) From 2ad723a7c677828836c2aa929d6d53a08c9848fb Mon Sep 17 00:00:00 2001 From: unitycoder Date: Thu, 24 Apr 2025 15:21:12 +0300 Subject: [PATCH 33/67] optimize startup time (disable save prefs on few fields, disable dummy placeholder data in grid to avoid Clear(), adjust GetTargetPlatform method --- UnityLauncherPro/MainWindow.xaml | 5 +-- UnityLauncherPro/MainWindow.xaml.cs | 24 ++++++++----- UnityLauncherPro/Tools.cs | 54 +++++++++++++++++++---------- 3 files changed, 53 insertions(+), 30 deletions(-) diff --git a/UnityLauncherPro/MainWindow.xaml b/UnityLauncherPro/MainWindow.xaml index 518c70e..14449c6 100644 --- a/UnityLauncherPro/MainWindow.xaml +++ b/UnityLauncherPro/MainWindow.xaml @@ -237,7 +237,8 @@ - + + diff --git a/UnityLauncherPro/MainWindow.xaml.cs b/UnityLauncherPro/MainWindow.xaml.cs index 4509092..b61c2a1 100644 --- a/UnityLauncherPro/MainWindow.xaml.cs +++ b/UnityLauncherPro/MainWindow.xaml.cs @@ -113,8 +113,6 @@ void Init() { lblVersion.Content = "Build: " + Version.Stamp; } - - CheckCustomIcon(); } void Start() @@ -153,7 +151,7 @@ void Start() //Console.WriteLine("projectsSource.Count: " + projectsSource.Count); - gridRecent.Items.Clear(); + //gridRecent.Items.Clear(); // not needed? gridRecent.ItemsSource = projectsSource; // clear updates grid @@ -190,6 +188,8 @@ void Start() if (Settings.Default.disableUnityHubLaunch == true) StartHubPipe(); + CheckCustomIcon(); + isInitializing = false; } // Start() @@ -2043,8 +2043,10 @@ private void BtnBrowseProjectRootFolder_Click(object sender, RoutedEventArgs e) private void TxtRootFolderForNewProjects_TextChanged(object sender, TextChangedEventArgs e) { - Properties.Settings.Default.newProjectsRoot = txtRootFolderForNewProjects.Text; - Properties.Settings.Default.Save(); + if (this.IsActive == false) return; // dont run code on window init + + Settings.Default.newProjectsRoot = txtRootFolderForNewProjects.Text; + Settings.Default.Save(); } @@ -2263,8 +2265,8 @@ private void ChkEnableProjectRename_Checked(object sender, RoutedEventArgs e) { if (this.IsActive == false) return; // dont run code on window init - Properties.Settings.Default.enableProjectRename = (bool)chkEnableProjectRename.IsChecked; - Properties.Settings.Default.Save(); + Settings.Default.enableProjectRename = (bool)chkEnableProjectRename.IsChecked; + Settings.Default.Save(); } private void MenuItemKillProcess_Click(object sender, RoutedEventArgs e) @@ -2666,8 +2668,10 @@ private void MenuStartWebGLServer_Click(object sender, RoutedEventArgs e) private void TxtWebglRelativePath_TextChanged(object sender, TextChangedEventArgs e) { - Properties.Settings.Default.webglBuildPath = txtWebglRelativePath.Text; - Properties.Settings.Default.Save(); + if (this.IsActive == false) return; // dont run code on window init + + Settings.Default.webglBuildPath = txtWebglRelativePath.Text; + Settings.Default.Save(); } private void MenuItemBrowsePersistentDataPath_Click(object sender, RoutedEventArgs e) @@ -3232,6 +3236,8 @@ private void MenuCreateDesktopShortCut_Click(object sender, RoutedEventArgs e) private void TxtShortcutBatchFileFolder_TextChanged(object sender, TextChangedEventArgs e) { + if (this.IsActive == false) return; // dont run code on window init + var folder = ((TextBox)sender).Text; if (Directory.Exists(folder)) { diff --git a/UnityLauncherPro/Tools.cs b/UnityLauncherPro/Tools.cs index 9caf003..3097b5d 100644 --- a/UnityLauncherPro/Tools.cs +++ b/UnityLauncherPro/Tools.cs @@ -1493,48 +1493,64 @@ private static string ExtractPlasticBranch(string plasticSelectorPath) return null; } - - //public static Platform GetTargetPlatform(string projectPath) static string GetTargetPlatformRaw(string projectPath) { string results = null; - //Platform results = Platform.Unknown; // get buildtarget from .csproj // StandaloneWindows64:19 // get main csproj file var csproj = Path.Combine(projectPath, "Assembly-CSharp.csproj"); + // TODO check projname also, if no assembly-.., NOTE already checked above - //var csproj = Path.Combine(projectPath, projectName + ".csproj"); + // var csproj = Path.Combine(projectPath, projectName + ".csproj"); + if (File.Exists(csproj)) { - var csprojtxt = File.ReadAllText(csproj); - var csprojsplit = csprojtxt.Split(new[] { "" }, StringSplitOptions.None); - if (csprojsplit != null && csprojsplit.Length > 1) + // Read the file line by line for performance + using (var reader = new StreamReader(csproj)) { - var endrow = csprojsplit[1].IndexOf(":"); - if (endrow > -1) + string line; + while ((line = reader.ReadLine()) != null) { - //Console.WriteLine("build target: " + csprojsplit[1].Substring(0, endrow)); - // 5.6 : win32, win64, osx, linux, linux64, ios, android, web, webstreamed, webgl, xboxone, ps4, psp2, wsaplayer, tizen, samsungtv - // 2017: standalone, Win, Win64, OSXUniversal, Linux, Linux64, LinuxUniversal, iOS, Android, Web, WebStreamed, WebGL, XboxOne, PS4, PSP2, WindowsStoreApps, Switch, WiiU, N3DS, tvOS, PSM - // 2018: standalone, Win, Win64, OSXUniversal, Linux, Linux64, LinuxUniversal, iOS, Android, Web, WebStreamed, WebGL, XboxOne, PS4, WindowsStoreApps, Switch, N3DS, tvOS - // 2019: Standalone, Win, Win64, OSXUniversal, Linux64, iOS, Android, WebGL, XboxOne, PS4, WindowsStoreApps, Switch, tvOS - // 2020: Standalone, Win, Win64, OSXUniversal, Linux64, iOS, Android, WebGL, XboxOne, PS4, WindowsStoreApps, Switch, tvOS - // 2021: Standalone, Win, Win64, OSXUniversal, Linux64, iOS, Android, WebGL, XboxOne, PS4, WindowsStoreApps, Switch, tvOS - results = csprojsplit[1].Substring(0, endrow); - //results = (Platform)Enum.Parse(typeof(Platform), csprojsplit[1].Substring(0, endrow)); + const string tagStart = ""; + const string tagEnd = ""; + + int startIdx = line.IndexOf(tagStart); + if (startIdx >= 0) + { + int endIdx = line.IndexOf(tagEnd, startIdx); + if (endIdx > startIdx) + { + string inner = line.Substring(startIdx + tagStart.Length, endIdx - startIdx - tagStart.Length); + int colonIndex = inner.IndexOf(':'); + if (colonIndex > -1) + { + //Console.WriteLine("build target: " + inner.Substring(0, colonIndex)); + // 5.6 : win32, win64, osx, linux, linux64, ios, android, web, webstreamed, webgl, xboxone, ps4, psp2, wsaplayer, tizen, samsungtv + // 2017: standalone, Win, Win64, OSXUniversal, Linux, Linux64, LinuxUniversal, iOS, Android, Web, WebStreamed, WebGL, XboxOne, PS4, PSP2, WindowsStoreApps, Switch, WiiU, N3DS, tvOS, PSM + // 2018: standalone, Win, Win64, OSXUniversal, Linux, Linux64, LinuxUniversal, iOS, Android, Web, WebStreamed, WebGL, XboxOne, PS4, WindowsStoreApps, Switch, N3DS, tvOS + // 2019: Standalone, Win, Win64, OSXUniversal, Linux64, iOS, Android, WebGL, XboxOne, PS4, WindowsStoreApps, Switch, tvOS + // 2020: Standalone, Win, Win64, OSXUniversal, Linux64, iOS, Android, WebGL, XboxOne, PS4, WindowsStoreApps, Switch, tvOS + // 2021: Standalone, Win, Win64, OSXUniversal, Linux64, iOS, Android, WebGL, XboxOne, PS4, WindowsStoreApps, Switch, tvOS + results = inner.Substring(0, colonIndex); + //results = (Platform)Enum.Parse(typeof(Platform), inner.Substring(0, colonIndex)); + break; // we found it, exit early + } + } + } } } } else { - //Console.WriteLine("Missing csproj, cannot parse target platform: "+ projectPath); + //Console.WriteLine("Missing csproj, cannot parse target platform: " + projectPath); } return results; } + public static string GetTargetPlatform(string projectPath) { var rawPlatformName = GetTargetPlatformRaw(projectPath); From f91906c452757e8b78cc34ece3ff335bbd03bb76 Mon Sep 17 00:00:00 2001 From: unitycoder Date: Fri, 2 May 2025 11:34:28 +0300 Subject: [PATCH 34/67] fix launch new project in Empty folder (dont shutdown if detect duplicate instance already) fixes #189 --- UnityLauncherPro/MainWindow.xaml.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/UnityLauncherPro/MainWindow.xaml.cs b/UnityLauncherPro/MainWindow.xaml.cs index b61c2a1..4fc19ec 100644 --- a/UnityLauncherPro/MainWindow.xaml.cs +++ b/UnityLauncherPro/MainWindow.xaml.cs @@ -133,8 +133,11 @@ void Start() // Send a wake-up message to the running instance ActivateRunningInstance(); - // Exit the current instance - App.Current.Shutdown(); + // Exit the current instance (if not coming from Explorer launch) + if (Directory.GetCurrentDirectory().ToLower() != @"c:\windows\system32") + { + App.Current.Shutdown(); + } } else { From beadc2819b3dc1b6229835295e62f2778e7b6b8e Mon Sep 17 00:00:00 2001 From: unitycoder Date: Fri, 2 May 2025 11:48:48 +0300 Subject: [PATCH 35/67] handle null version for new project folder open fixes #189 --- UnityLauncherPro/MainWindow.xaml.cs | 1 + UnityLauncherPro/UpgradeWindow.xaml.cs | 33 +++++++++++++------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/UnityLauncherPro/MainWindow.xaml.cs b/UnityLauncherPro/MainWindow.xaml.cs index 4fc19ec..fa47cb0 100644 --- a/UnityLauncherPro/MainWindow.xaml.cs +++ b/UnityLauncherPro/MainWindow.xaml.cs @@ -122,6 +122,7 @@ void Start() UpdateUnityInstallationsList(); HandleCommandLineLaunch(); + // check for duplicate instance, and activate that instead if (chkAllowSingleInstanceOnly.IsChecked == true) { diff --git a/UnityLauncherPro/UpgradeWindow.xaml.cs b/UnityLauncherPro/UpgradeWindow.xaml.cs index 128e3f9..d2d7a3d 100644 --- a/UnityLauncherPro/UpgradeWindow.xaml.cs +++ b/UnityLauncherPro/UpgradeWindow.xaml.cs @@ -32,28 +32,29 @@ public UpgradeWindow(string currentVersion, string projectPath, string commandLi btnDownload.IsEnabled = true; // if dont have exact version, show red outline - if (MainWindow.unityInstalledVersions.ContainsKey(currentVersion) == false) + if (currentVersion == null || MainWindow.unityInstalledVersions.ContainsKey(currentVersion) == false) { txtCurrentVersion.BorderBrush = Brushes.Red; txtCurrentVersion.BorderThickness = new Thickness(1); } - - // remove china c1 from version - if (currentVersion.Contains('c')) currentVersion= currentVersion.Replace("c1", ""); - - // find nearest version - string nearestVersion = Tools.FindNearestVersion(currentVersion, MainWindow.unityInstalledVersions.Keys.ToList()); - - if (nearestVersion != null) + else // not null { - // select nearest version - for (int i = 0; i < MainWindow.unityInstallationsSource.Count; i++) + // remove china c1 from version + if (currentVersion.Contains('c')) currentVersion = currentVersion.Replace("c1", ""); + // find nearest version + string nearestVersion = Tools.FindNearestVersion(currentVersion, MainWindow.unityInstalledVersions.Keys.ToList()); + + if (nearestVersion != null) { - if (MainWindow.unityInstallationsSource[i].Version == nearestVersion) + // select nearest version + for (int i = 0; i < MainWindow.unityInstallationsSource.Count; i++) { - gridAvailableVersions.SelectedIndex = i; - gridAvailableVersions.ScrollIntoView(gridAvailableVersions.SelectedItem); - break; + if (MainWindow.unityInstallationsSource[i].Version == nearestVersion) + { + gridAvailableVersions.SelectedIndex = i; + gridAvailableVersions.ScrollIntoView(gridAvailableVersions.SelectedItem); + break; + } } } } @@ -77,7 +78,7 @@ private void BtnOpenReleasePage_Click(object sender, RoutedEventArgs e) Tools.OpenReleaseNotes(txtCurrentVersion.Text); } - + private void BtnDownloadEditor_Click(object sender, RoutedEventArgs e) { Tools.DownloadInBrowser(txtCurrentVersion.Text); From 25f29473abfe9ec8d8135eaeb565904763004dd7 Mon Sep 17 00:00:00 2001 From: unitycoder Date: Sat, 3 May 2025 11:01:02 +0300 Subject: [PATCH 36/67] use init script on new project creation (if asset folder exists, but its empty folder) fixes #190 --- UnityLauncherPro/MainWindow.xaml.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/UnityLauncherPro/MainWindow.xaml.cs b/UnityLauncherPro/MainWindow.xaml.cs index fa47cb0..d0e995d 100644 --- a/UnityLauncherPro/MainWindow.xaml.cs +++ b/UnityLauncherPro/MainWindow.xaml.cs @@ -330,13 +330,15 @@ void HandleCommandLineLaunch() // NOTE if keydown, window doesnt become active and focused if (string.IsNullOrEmpty(version) || (Keyboard.Modifiers & ModifierKeys.Shift) != 0) { - if (Directory.Exists(Path.Combine(proj.Path, "Assets")) == true) + // if Assets folder exists, then its existing project + if (Directory.Exists(Path.Combine(proj.Path, "Assets")) == true && (Directory.GetFiles(Path.Combine(proj.Path, "Assets")).Length > 0)) { - Tools.DisplayUpgradeDialog(proj, null, false); + bool useInitScript = (bool)chkUseInitScript.IsChecked; + + Tools.DisplayUpgradeDialog(proj, null, useInitScript); } - else // no assets folder here, then its new project + else // no Assets folder here OR Assets folder is empty, then its new project { - //Tools.DisplayUpgradeDialog(proj, null); CreateNewEmptyProject(proj.Path); } } @@ -1315,7 +1317,7 @@ private void BtnUpgradeProject_Click(object sender, RoutedEventArgs e) var proj = GetSelectedProject(); if (proj == null) return; - Tools.DisplayUpgradeDialog(proj, this, false); + Tools.DisplayUpgradeDialog(proj: proj, owner: this, useInitScript: false); } private void GridRecent_Loaded(object sender, RoutedEventArgs e) From 26bf0d829cf5bb4a696c5047ac7cf91c833322c5 Mon Sep 17 00:00:00 2001 From: unitycoder Date: Sat, 3 May 2025 11:36:55 +0300 Subject: [PATCH 37/67] add Purge button (for project paths with missing folder, those are hanging in Settings string list), add status messages for new project creation failures --- UnityLauncherPro/MainWindow.xaml | 11 +++++++-- UnityLauncherPro/MainWindow.xaml.cs | 36 +++++++++++++++++++++++++++++ UnityLauncherPro/NewProject.xaml.cs | 7 +++--- UnityLauncherPro/Tools.cs | 9 +++++--- 4 files changed, 54 insertions(+), 9 deletions(-) diff --git a/UnityLauncherPro/MainWindow.xaml b/UnityLauncherPro/MainWindow.xaml index 14449c6..49083d2 100644 --- a/UnityLauncherPro/MainWindow.xaml +++ b/UnityLauncherPro/MainWindow.xaml @@ -238,7 +238,8 @@ - +