From 1cc8b9dfe86685abc55a82804b37354a591df58b Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sat, 23 Mar 2024 18:00:32 -0500 Subject: [PATCH 01/75] first commit --- Flow.Launcher.Core/Flow.Launcher.Core.csproj | 2 +- Flow.Launcher.Core/Updater.cs | 70 +++++------ Flow.Launcher/App.xaml.cs | 3 + Flow.Launcher/Flow.Launcher.csproj | 1 + Flow.Launcher/Helper/SingleInstance.cs | 118 +++++++++++-------- Flow.Launcher/PublicAPIInstance.cs | 7 +- 6 files changed, 104 insertions(+), 97 deletions(-) diff --git a/Flow.Launcher.Core/Flow.Launcher.Core.csproj b/Flow.Launcher.Core/Flow.Launcher.Core.csproj index 18101ccf04e..046c7564513 100644 --- a/Flow.Launcher.Core/Flow.Launcher.Core.csproj +++ b/Flow.Launcher.Core/Flow.Launcher.Core.csproj @@ -57,8 +57,8 @@ - + diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs index 3f64b273e4c..3a8e7ec7f07 100644 --- a/Flow.Launcher.Core/Updater.cs +++ b/Flow.Launcher.Core/Updater.cs @@ -17,6 +17,8 @@ using Flow.Launcher.Plugin; using System.Text.Json.Serialization; using System.Threading; +using Velopack; +using Velopack.Sources; namespace Flow.Launcher.Core { @@ -40,15 +42,23 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true) api.ShowMsg(api.GetTranslation("pleaseWait"), api.GetTranslation("update_flowlauncher_update_check")); - using var updateManager = await GitHubUpdateManagerAsync(GitHubRepository).ConfigureAwait(false); + var updateManager = new UpdateManager(new GithubSource(GitHubRepository, null, false)); // UpdateApp CheckForUpdate will return value only if the app is squirrel installed - var newUpdateInfo = await updateManager.CheckForUpdate().NonNull().ConfigureAwait(false); + var newUpdateInfo = await updateManager.CheckForUpdatesAsync().ConfigureAwait(false); - var newReleaseVersion = Version.Parse(newUpdateInfo.FutureReleaseEntry.Version.ToString()); + if (newUpdateInfo == null) + { + if (!silentUpdate) + api.ShowMsg(api.GetTranslation("update_flowlauncher_fail"), + api.GetTranslation("update_flowlauncher_check_connection")); + return; + } + + var newReleaseVersion = Version.Parse(newUpdateInfo.TargetFullRelease.Version.ToString()); var currentVersion = Version.Parse(Constant.Version); - Log.Info($"|Updater.UpdateApp|Future Release <{newUpdateInfo.FutureReleaseEntry.Formatted()}>"); + Log.Info($"|Updater.UpdateApp|Future Release <{newUpdateInfo.TargetFullRelease.Formatted()}>"); if (newReleaseVersion <= currentVersion) { @@ -61,16 +71,18 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true) api.ShowMsg(api.GetTranslation("update_flowlauncher_update_found"), api.GetTranslation("update_flowlauncher_updating")); - await updateManager.DownloadReleases(newUpdateInfo.ReleasesToApply).ConfigureAwait(false); + await updateManager.DownloadUpdatesAsync(newUpdateInfo).ConfigureAwait(false); await updateManager.ApplyReleases(newUpdateInfo).ConfigureAwait(false); if (DataLocation.PortableDataLocationInUse()) { - var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}"; + var targetDestination = updateManager.RootAppDirectory + + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}"; FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination); if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination)) - MessageBox.Show(string.Format(api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"), + MessageBox.Show(string.Format( + api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"), DataLocation.PortableDataPath, targetDestination)); } @@ -83,18 +95,22 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true) Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}"); - if (MessageBox.Show(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes) + if (MessageBox.Show(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), + MessageBoxButton.YesNo) == MessageBoxResult.Yes) { UpdateManager.RestartApp(Constant.ApplicationFileName); } } catch (Exception e) { - if ((e is HttpRequestException or WebException or SocketException || e.InnerException is TimeoutException)) - Log.Exception($"|Updater.UpdateApp|Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", e); + if ((e is HttpRequestException or WebException or SocketException || + e.InnerException is TimeoutException)) + Log.Exception( + $"|Updater.UpdateApp|Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", + e); else Log.Exception($"|Updater.UpdateApp|Error Occurred", e); - + if (!silentUpdate) api.ShowMsg(api.GetTranslation("update_flowlauncher_fail"), api.GetTranslation("update_flowlauncher_check_connection")); @@ -108,37 +124,11 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true) [UsedImplicitly] private class GithubRelease { - [JsonPropertyName("prerelease")] - public bool Prerelease { get; [UsedImplicitly] set; } - - [JsonPropertyName("published_at")] - public DateTime PublishedAt { get; [UsedImplicitly] set; } - - [JsonPropertyName("html_url")] - public string HtmlUrl { get; [UsedImplicitly] set; } - } - - // https://github.com/Squirrel/Squirrel.Windows/blob/master/src/Squirrel/UpdateManager.Factory.cs - private async Task GitHubUpdateManagerAsync(string repository) - { - var uri = new Uri(repository); - var api = $"https://api.github.com/repos{uri.AbsolutePath}/releases"; - - await using var jsonStream = await Http.GetStreamAsync(api).ConfigureAwait(false); - - var releases = await System.Text.Json.JsonSerializer.DeserializeAsync>(jsonStream).ConfigureAwait(false); - var latest = releases.Where(r => !r.Prerelease).OrderByDescending(r => r.PublishedAt).First(); - var latestUrl = latest.HtmlUrl.Replace("/tag/", "/download/"); - - var client = new WebClient - { - Proxy = Http.WebProxy - }; - var downloader = new FileDownloader(client); + [JsonPropertyName("prerelease")] public bool Prerelease { get; [UsedImplicitly] set; } - var manager = new UpdateManager(latestUrl, urlDownloader: downloader); + [JsonPropertyName("published_at")] public DateTime PublishedAt { get; [UsedImplicitly] set; } - return manager; + [JsonPropertyName("html_url")] public string HtmlUrl { get; [UsedImplicitly] set; } } public string NewVersionTips(string version) diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index f4a17761f00..fbc7e7f31ae 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -16,6 +16,7 @@ using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.ViewModel; +using Velopack; using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch; namespace Flow.Launcher @@ -36,6 +37,8 @@ public partial class App : IDisposable, ISingleInstanceApp [STAThread] public static void Main() { + VelopackApp.Build().Run(); + if (SingleInstance.InitializeAsFirstInstance(Unique)) { using (var application = new App()) diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index 53c1bafc738..893d9515fdf 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -96,6 +96,7 @@ + diff --git a/Flow.Launcher/Helper/SingleInstance.cs b/Flow.Launcher/Helper/SingleInstance.cs index 739fed378e0..b5cd67a0000 100644 --- a/Flow.Launcher/Helper/SingleInstance.cs +++ b/Flow.Launcher/Helper/SingleInstance.cs @@ -119,8 +119,10 @@ internal enum WM DWMWINDOWMAXIMIZEDCHANGE = 0x0321, #region Windows 7 + DWMSENDICONICTHUMBNAIL = 0x0323, DWMSENDICONICLIVEPREVIEWBITMAP = 0x0326, + #endregion USER = 0x0400, @@ -140,7 +142,8 @@ internal static class NativeMethods public delegate IntPtr MessageHandler(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled); [DllImport("shell32.dll", EntryPoint = "CommandLineToArgvW", CharSet = CharSet.Unicode)] - private static extern IntPtr _CommandLineToArgvW([MarshalAs(UnmanagedType.LPWStr)] string cmdLine, out int numArgs); + private static extern IntPtr _CommandLineToArgvW([MarshalAs(UnmanagedType.LPWStr)] string cmdLine, + out int numArgs); [DllImport("kernel32.dll", EntryPoint = "LocalFree", SetLastError = true)] @@ -159,6 +162,7 @@ public static string[] CommandLineToArgvW(string cmdLine) { throw new Win32Exception(); } + var result = new string[numArgs]; for (int i = 0; i < numArgs; i++) @@ -171,19 +175,17 @@ public static string[] CommandLineToArgvW(string cmdLine) } finally { - IntPtr p = _LocalFree(argv); // Otherwise LocalFree failed. // Assert.AreEqual(IntPtr.Zero, p); } } + } - } - - public interface ISingleInstanceApp - { - void OnSecondAppStarted(); - } + public interface ISingleInstanceApp + { + void OnSecondAppStarted(); + } /// /// This class checks to make sure that only one instance of @@ -196,9 +198,9 @@ public interface ISingleInstanceApp /// running as Administrator, can activate it with command line arguments. /// For most apps, this will not be much of an issue. /// - public static class SingleInstance - where TApplication: Application , ISingleInstanceApp - + public static class SingleInstance + where TApplication : Application, ISingleInstanceApp + { #region Private Fields @@ -215,22 +217,40 @@ public static class SingleInstance /// /// Application mutex. /// - internal static Mutex singleInstanceMutex; + private static Mutex singleInstanceMutex; #endregion - #region Public Properties + #region Public Methods - #endregion + public static void Restart() + { + singleInstanceMutex?.ReleaseMutex(); - #region Public Methods + StopRemoteServiceTokenSource?.Cancel(); + + while (RemoteServiceRunning) + { + // busy wait + Thread.Sleep(10); + } + + System.Diagnostics.Process.Start(Application.ResourceAssembly.Location); + Application.Current.Shutdown(); + } + + // this is always going to run only once + private static CancellationTokenSource StopRemoteServiceTokenSource { get; set; } + private static volatile bool RemoteServiceRunning = false; + + /// /// Checks if the instance of the application attempting to start is the first instance. /// If not, activates the first instance. /// /// True if this is the first instance of the application. - public static bool InitializeAsFirstInstance( string uniqueName ) + public static bool InitializeAsFirstInstance(string uniqueName) { // Build unique application Id and the IPC channel name. string applicationIdentifier = uniqueName + Environment.UserName; @@ -238,16 +258,15 @@ public static bool InitializeAsFirstInstance( string uniqueName ) string channelName = String.Concat(applicationIdentifier, Delimiter, ChannelNameSuffix); // Create mutex based on unique application Id to check if this is the first instance of the application. - bool firstInstance; - singleInstanceMutex = new Mutex(true, applicationIdentifier, out firstInstance); + singleInstanceMutex = new Mutex(true, applicationIdentifier, out var firstInstance); if (firstInstance) { - _ = CreateRemoteService(channelName); + _ = StartRemoteServiceAsync(channelName, StopRemoteServiceTokenSource.Token); return true; } else { - _ = SignalFirstInstance(channelName); + _ = SignalFirstInstanceAsync(channelName); return false; } } @@ -258,6 +277,7 @@ public static bool InitializeAsFirstInstance( string uniqueName ) public static void Cleanup() { singleInstanceMutex?.ReleaseMutex(); + StopRemoteServiceTokenSource?.Cancel(); } #endregion @@ -268,7 +288,7 @@ public static void Cleanup() /// Gets command line args - for ClickOnce deployed applications, command line args may not be passed directly, they have to be retrieved. /// /// List of command line arg strings. - private static IList GetCommandLineArgs( string uniqueApplicationName ) + private static IList GetCommandLineArgs(string uniqueApplicationName) { string[] args = null; @@ -279,7 +299,6 @@ private static IList GetCommandLineArgs( string uniqueApplicationName ) } catch (NotSupportedException) { - // The application was clickonce deployed // Clickonce deployed apps cannot recieve traditional commandline arguments // As a workaround commandline arguments can be written to a shared location before @@ -293,10 +312,8 @@ private static IList GetCommandLineArgs( string uniqueApplicationName ) { try { - using (TextReader reader = new StreamReader(cmdLinePath, Encoding.Unicode)) - { - args = NativeMethods.CommandLineToArgvW(reader.ReadToEnd()); - } + using TextReader reader = new StreamReader(cmdLinePath, Encoding.Unicode); + args = NativeMethods.CommandLineToArgvW(reader.ReadToEnd()); File.Delete(cmdLinePath); } @@ -306,10 +323,7 @@ private static IList GetCommandLineArgs( string uniqueApplicationName ) } } - if (args == null) - { - args = new string[] { }; - } + args ??= Array.Empty(); return new List(args); } @@ -319,40 +333,42 @@ private static IList GetCommandLineArgs( string uniqueApplicationName ) /// Once receives signal from client, will activate first instance. /// /// Application's IPC channel name. - private static async Task CreateRemoteService(string channelName) + /// Cancellation token + private static async Task StartRemoteServiceAsync(string channelName, CancellationToken token = default) { - using (NamedPipeServerStream pipeServer = new NamedPipeServerStream(channelName, PipeDirection.In)) + await using NamedPipeServerStream pipeServer = new NamedPipeServerStream(channelName, PipeDirection.In); + while (true) { - while(true) + if (token.IsCancellationRequested) { - // Wait for connection to the pipe - await pipeServer.WaitForConnectionAsync(); - if (Application.Current != null) - { - // Do an asynchronous call to ActivateFirstInstance function - Application.Current.Dispatcher.Invoke(ActivateFirstInstance); - } - // Disconect client - pipeServer.Disconnect(); + break; + } + + // Wait for connection to the pipe + await pipeServer.WaitForConnectionAsync(token); + if (Application.Current != null) + { + // Do an asynchronous call to ActivateFirstInstance function + Application.Current.Dispatcher.Invoke(ActivateFirstInstance); } + + // Disconnect client + pipeServer.Disconnect(); } + + RemoteServiceRunning = true; } /// /// Creates a client pipe and sends a signal to server to launch first instance /// /// Application's IPC channel name. - /// - /// Command line arguments for the second instance, passed to the first instance to take appropriate action. - /// - private static async Task SignalFirstInstance(string channelName) + private static async Task SignalFirstInstanceAsync(string channelName) { // Create a client pipe connected to server - using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", channelName, PipeDirection.Out)) - { - // Connect to the available pipe - await pipeClient.ConnectAsync(0); - } + await using NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", channelName, PipeDirection.Out); + // Connect to the available pipe + await pipeClient.ConnectAsync(0); } /// diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 36309a22a4f..00e7df3d005 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -62,11 +62,8 @@ public void RestartApp() // UpdateManager.RestartApp() will call Environment.Exit(0) // which will cause ungraceful exit SaveAppAllSettings(); - - // Restart requires Squirrel's Update.exe to be present in the parent folder, - // it is only published from the project's release pipeline. When debugging without it, - // the project may not restart or just terminates. This is expected. - UpdateManager.RestartApp(Constant.ApplicationFileName); + + SingleInstance.Restart(); } public void ShowMainWindow() => _mainVM.Show(); From 3d6782ca305d64057fb1bcd91356c0897b7ebc49 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sun, 24 Mar 2024 13:41:07 -0500 Subject: [PATCH 02/75] migrate to velopack --- Flow.Launcher.Core/Configuration/IPortable.cs | 8 +- Flow.Launcher.Core/Configuration/Portable.cs | 112 +++++------------ Flow.Launcher.Core/Updater.cs | 43 ++++--- .../SharedCommands/FilesFolders.cs | 27 ++-- Flow.Launcher/App.xaml.cs | 6 +- Flow.Launcher/Helper/SingleInstance.cs | 63 ++++++---- Flow.Launcher/PublicAPIInstance.cs | 1 - .../Utilities.cs | 28 +---- Scripts/post_build.ps1 | 119 ++++++++++-------- appveyor.yml | 11 +- 10 files changed, 200 insertions(+), 218 deletions(-) diff --git a/Flow.Launcher.Core/Configuration/IPortable.cs b/Flow.Launcher.Core/Configuration/IPortable.cs index e56b0188cfb..a741a0e9d41 100644 --- a/Flow.Launcher.Core/Configuration/IPortable.cs +++ b/Flow.Launcher.Core/Configuration/IPortable.cs @@ -5,12 +5,6 @@ public interface IPortable { void EnablePortableMode(); void DisablePortableMode(); - void RemoveShortcuts(); - void RemoveUninstallerEntry(); - void CreateShortcuts(); - void CreateUninstallerEntry(); - void MoveUserDataFolder(string fromLocation, string toLocation); - void VerifyUserDataAfterMove(string fromLocation, string toLocation); bool CanUpdatePortability(); } -} \ No newline at end of file +} diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs index b58154dcb23..8b860b3a012 100644 --- a/Flow.Launcher.Core/Configuration/Portable.cs +++ b/Flow.Launcher.Core/Configuration/Portable.cs @@ -1,5 +1,4 @@ using Microsoft.Win32; -using Squirrel; using System; using System.IO; using System.Reflection; @@ -9,41 +8,26 @@ using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin.SharedCommands; using System.Linq; +using Flow.Launcher.Core.Plugin; +using Velopack; +using Velopack.Locators; +using Velopack.Windows; namespace Flow.Launcher.Core.Configuration { public class Portable : IPortable { - /// - /// As at Squirrel.Windows version 1.5.2, UpdateManager needs to be disposed after finish - /// - /// - private UpdateManager NewUpdateManager() - { - var applicationFolderName = Constant.ApplicationDirectory - .Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None) - .Last(); - - return new UpdateManager(string.Empty, applicationFolderName, Constant.RootDirectory); - } - public void DisablePortableMode() { try { MoveUserDataFolder(DataLocation.PortableDataPath, DataLocation.RoamingDataPath); -#if !DEBUG - // Create shortcuts and uninstaller are not required in debug mode, - // otherwise will repoint the path of the actual installed production version to the debug version - CreateShortcuts(); - CreateUninstallerEntry(); -#endif IndicateDeletion(DataLocation.PortableDataPath); MessageBox.Show("Flow Launcher needs to restart to finish disabling portable mode, " + - "after the restart your portable data profile will be deleted and roaming data profile kept"); + "after the restart your portable data profile will be deleted and roaming data profile kept"); - UpdateManager.RestartApp(Constant.ApplicationFileName); + PluginManager.API.RestartApp(); } catch (Exception e) { @@ -56,18 +40,12 @@ public void EnablePortableMode() try { MoveUserDataFolder(DataLocation.RoamingDataPath, DataLocation.PortableDataPath); -#if !DEBUG - // Remove shortcuts and uninstaller are not required in debug mode, - // otherwise will delete the actual installed production version - RemoveShortcuts(); - RemoveUninstallerEntry(); -#endif IndicateDeletion(DataLocation.RoamingDataPath); MessageBox.Show("Flow Launcher needs to restart to finish enabling portable mode, " + - "after the restart your roaming data profile will be deleted and portable data profile kept"); + "after the restart your roaming data profile will be deleted and portable data profile kept"); - UpdateManager.RestartApp(Constant.ApplicationFileName); + PluginManager.API.RestartApp(); } catch (Exception e) { @@ -75,23 +53,6 @@ public void EnablePortableMode() } } - public void RemoveShortcuts() - { - using (var portabilityUpdater = NewUpdateManager()) - { - portabilityUpdater.RemoveShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.StartMenu); - portabilityUpdater.RemoveShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.Desktop); - portabilityUpdater.RemoveShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.Startup); - } - } - - public void RemoveUninstallerEntry() - { - using (var portabilityUpdater = NewUpdateManager()) - { - portabilityUpdater.RemoveUninstallerRegistryEntry(); - } - } public void MoveUserDataFolder(string fromLocation, string toLocation) { @@ -104,32 +65,6 @@ public void VerifyUserDataAfterMove(string fromLocation, string toLocation) FilesFolders.VerifyBothFolderFilesEqual(fromLocation, toLocation); } - public void CreateShortcuts() - { - using (var portabilityUpdater = NewUpdateManager()) - { - portabilityUpdater.CreateShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.StartMenu, false); - portabilityUpdater.CreateShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.Desktop, false); - portabilityUpdater.CreateShortcutsForExecutable(Constant.ApplicationFileName, ShortcutLocation.Startup, false); - } - } - - public void CreateUninstallerEntry() - { - var uninstallRegSubKey = @"Software\Microsoft\Windows\CurrentVersion\Uninstall"; - - using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default)) - using (var subKey1 = baseKey.CreateSubKey(uninstallRegSubKey, RegistryKeyPermissionCheck.ReadWriteSubTree)) - using (var subKey2 = subKey1.CreateSubKey(Constant.FlowLauncher, RegistryKeyPermissionCheck.ReadWriteSubTree)) - { - subKey2.SetValue("DisplayIcon", Path.Combine(Constant.ApplicationDirectory, "app.ico"), RegistryValueKind.String); - } - - using (var portabilityUpdater = NewUpdateManager()) - { - _ = portabilityUpdater.CreateUninstallerRegistryEntry(); - } - } internal void IndicateDeletion(string filePathTodelete) { @@ -145,9 +80,28 @@ internal void IndicateDeletion(string filePathTodelete) /// public void PreStartCleanUpAfterPortabilityUpdate() { + var locator = VelopackLocator.GetDefault(null); + + // this would not happen for development environment + if (locator.PackagesDir != null) + { + // check whether the package locate in %localappdata% + // if not create the portable data folder + if (!locator.PackagesDir.IsSubPathOf( + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)) + && !DataLocation.PortableDataPath.LocationExists()) + { + Directory.CreateDirectory(DataLocation.PortableDataPath); + } + } + // Specify here so this method does not rely on other environment variables to initialise - var portableDataDir = Path.Combine(Directory.GetParent(Assembly.GetExecutingAssembly().Location.NonNull()).ToString(), "UserData"); - var roamingDataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FlowLauncher"); + var portableDataDir = + Path.Combine(Directory.GetParent(Assembly.GetExecutingAssembly().Location.NonNull()).ToString(), + "UserData"); + var roamingDataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), + "FlowLauncher"); + // Get full path to the .dead files for each case var portableDataDeleteFilePath = Path.Combine(portableDataDir, DataLocation.DeletionIndicatorFile); @@ -161,7 +115,7 @@ public void PreStartCleanUpAfterPortabilityUpdate() if (MessageBox.Show("Flow Launcher has detected you enabled portable mode, " + "would you like to move it to a different location?", string.Empty, - MessageBoxButton.YesNo) == MessageBoxResult.Yes) + MessageBoxButton.YesNo) == MessageBoxResult.Yes) { FilesFolders.OpenPath(Constant.RootDirectory); @@ -175,7 +129,7 @@ public void PreStartCleanUpAfterPortabilityUpdate() FilesFolders.RemoveFolderIfExists(portableDataDir); MessageBox.Show("Flow Launcher has detected you disabled portable mode, " + - "the relevant shortcuts and uninstaller entry have been created"); + "the relevant shortcuts and uninstaller entry have been created"); } } @@ -187,8 +141,8 @@ public bool CanUpdatePortability() if (roamingLocationExists && portableLocationExists) { MessageBox.Show(string.Format("Flow Launcher detected your user data exists both in {0} and " + - "{1}. {2}{2}Please delete {1} in order to proceed. No changes have occurred.", - DataLocation.PortableDataPath, DataLocation.RoamingDataPath, Environment.NewLine)); + "{1}. {2}{2}Please delete {1} in order to proceed. No changes have occurred.", + DataLocation.PortableDataPath, DataLocation.RoamingDataPath, Environment.NewLine)); return false; } diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs index 3a8e7ec7f07..7fc50a02dbe 100644 --- a/Flow.Launcher.Core/Updater.cs +++ b/Flow.Launcher.Core/Updater.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Net; using System.Net.Http; using System.Net.Sockets; @@ -7,7 +8,6 @@ using System.Threading.Tasks; using System.Windows; using JetBrains.Annotations; -using Squirrel; using Flow.Launcher.Core.Resource; using Flow.Launcher.Plugin.SharedCommands; using Flow.Launcher.Infrastructure; @@ -17,8 +17,11 @@ using Flow.Launcher.Plugin; using System.Text.Json.Serialization; using System.Threading; +using System.Windows.Shapes; using Velopack; +using Velopack.Locators; using Velopack.Sources; +using Path = System.IO.Path; namespace Flow.Launcher.Core { @@ -54,7 +57,7 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true) api.GetTranslation("update_flowlauncher_check_connection")); return; } - + var newReleaseVersion = Version.Parse(newUpdateInfo.TargetFullRelease.Version.ToString()); var currentVersion = Version.Parse(Constant.Version); @@ -73,23 +76,18 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true) await updateManager.DownloadUpdatesAsync(newUpdateInfo).ConfigureAwait(false); - await updateManager.ApplyReleases(newUpdateInfo).ConfigureAwait(false); - if (DataLocation.PortableDataLocationInUse()) { - var targetDestination = updateManager.RootAppDirectory + - $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}"; - FilesFolders.CopyAll(DataLocation.PortableDataPath, targetDestination); - if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination)) + var targetDestination = Path.Combine(VelopackLocator.GetDefault(null).RootAppDir!, + DataLocation.PortableFolderName); + + DataLocation.PortableDataPath.CopyAll(targetDestination); + if (!DataLocation.PortableDataPath.VerifyBothFolderFilesEqual(targetDestination)) MessageBox.Show(string.Format( api.GetTranslation("update_flowlauncher_fail_moving_portable_user_profile_data"), DataLocation.PortableDataPath, targetDestination)); } - else - { - await updateManager.CreateUninstallerRegistryEntry().ConfigureAwait(false); - } var newVersionTips = NewVersionTips(newReleaseVersion.ToString()); @@ -98,7 +96,11 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true) if (MessageBox.Show(newVersionTips, api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes) { - UpdateManager.RestartApp(Constant.ApplicationFileName); + updateManager.ApplyUpdatesAndRestart(newUpdateInfo); + } + else + { + updateManager.WaitExitThenApplyUpdates(newUpdateInfo); } } catch (Exception e) @@ -121,14 +123,19 @@ public async Task UpdateAppAsync(IPublicAPI api, bool silentUpdate = true) } } - [UsedImplicitly] - private class GithubRelease + public static void RecoverPortableData() { - [JsonPropertyName("prerelease")] public bool Prerelease { get; [UsedImplicitly] set; } + var locator = VelopackLocator.GetDefault(null); - [JsonPropertyName("published_at")] public DateTime PublishedAt { get; [UsedImplicitly] set; } + var portableDataLocation = Path.Combine(VelopackLocator.GetDefault(null).RootAppDir!, + DataLocation.PortableFolderName); + + if (Path.Exists(portableDataLocation)) + { + portableDataLocation.CopyAll(Path.Combine(locator.AppContentDir!, DataLocation.PortableFolderName)); + } - [JsonPropertyName("html_url")] public string HtmlUrl { get; [UsedImplicitly] set; } + Directory.Delete(portableDataLocation); } public string NewVersionTips(string version) diff --git a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs index 4137ca8d076..f25f9fe2ae3 100644 --- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs +++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs @@ -3,6 +3,7 @@ using System.IO; #pragma warning disable IDE0005 using System.Windows; + #pragma warning restore IDE0005 namespace Flow.Launcher.Plugin.SharedCommands @@ -14,6 +15,18 @@ public static class FilesFolders { private const string FileExplorerProgramName = "explorer"; + public static bool IsSubPathOf(this string subPath, string basePath) + { + var rel = Path.GetRelativePath( + basePath.Replace('\\', '/'), + subPath.Replace('\\', '/')); + return rel != "." + && rel != ".." + && !rel.StartsWith("../") + && !Path.IsPathRooted(rel); + } + + /// /// Copies the folder and all of its files and folders /// including subfolders to the target location @@ -65,7 +78,6 @@ public static void CopyAll(this string sourcePath, string targetPath) RemoveFolderIfExists(targetPath); #endif } - } /// @@ -82,10 +94,12 @@ public static bool VerifyBothFolderFilesEqual(this string fromPath, string toPat var fromDir = new DirectoryInfo(fromPath); var toDir = new DirectoryInfo(toPath); - if (fromDir.GetFiles("*", SearchOption.AllDirectories).Length != toDir.GetFiles("*", SearchOption.AllDirectories).Length) + if (fromDir.GetFiles("*", SearchOption.AllDirectories).Length != + toDir.GetFiles("*", SearchOption.AllDirectories).Length) return false; - if (fromDir.GetDirectories("*", SearchOption.AllDirectories).Length != toDir.GetDirectories("*", SearchOption.AllDirectories).Length) + if (fromDir.GetDirectories("*", SearchOption.AllDirectories).Length != + toDir.GetDirectories("*", SearchOption.AllDirectories).Length) return false; return true; @@ -99,7 +113,6 @@ public static bool VerifyBothFolderFilesEqual(this string fromPath, string toPat return false; #endif } - } /// @@ -151,9 +164,7 @@ public static void OpenPath(string fileOrFolderPath) { var psi = new ProcessStartInfo { - FileName = FileExplorerProgramName, - UseShellExecute = true, - Arguments = '"' + fileOrFolderPath + '"' + FileName = FileExplorerProgramName, UseShellExecute = true, Arguments = '"' + fileOrFolderPath + '"' }; try { @@ -279,7 +290,7 @@ public static bool PathContains(string parentPath, string subPath, bool allowEqu && !rel.StartsWith(@"..\") && !Path.IsPathRooted(rel); } - + /// /// Returns path ended with "\" /// diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index fbc7e7f31ae..2792fdfffd2 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -37,7 +37,11 @@ public partial class App : IDisposable, ISingleInstanceApp [STAThread] public static void Main() { - VelopackApp.Build().Run(); + VelopackApp.Build() + .WithAfterUpdateFastCallback(x => + { + Updater.RecoverPortableData(); + }).Run(); if (SingleInstance.InitializeAsFirstInstance(Unique)) { diff --git a/Flow.Launcher/Helper/SingleInstance.cs b/Flow.Launcher/Helper/SingleInstance.cs index b5cd67a0000..b0b8e84b227 100644 --- a/Flow.Launcher/Helper/SingleInstance.cs +++ b/Flow.Launcher/Helper/SingleInstance.cs @@ -1,14 +1,17 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.IO.Pipes; +using System.Reflection; using System.Security; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; +using Velopack; // http://blogs.microsoft.co.il/arik/2010/05/28/wpf-single-instance-application/ // modified to allow single instace restart @@ -226,7 +229,6 @@ public static class SingleInstance public static void Restart() { singleInstanceMutex?.ReleaseMutex(); - StopRemoteServiceTokenSource?.Cancel(); while (RemoteServiceRunning) @@ -235,16 +237,23 @@ public static void Restart() Thread.Sleep(10); } - System.Diagnostics.Process.Start(Application.ResourceAssembly.Location); + var info = new ProcessStartInfo + { + Arguments = "/C choice /C Y /N /D Y /T 1 & START \"\" \"" + Environment.ProcessPath + "\"", + WindowStyle = ProcessWindowStyle.Hidden, + CreateNoWindow = true, + FileName = "cmd.exe" + }; + Process.Start(info); Application.Current.Shutdown(); } // this is always going to run only once private static CancellationTokenSource StopRemoteServiceTokenSource { get; set; } - private static volatile bool RemoteServiceRunning = false; + private static volatile bool RemoteServiceRunning = true; + - /// /// Checks if the instance of the application attempting to start is the first instance. /// If not, activates the first instance. @@ -252,6 +261,8 @@ public static void Restart() /// True if this is the first instance of the application. public static bool InitializeAsFirstInstance(string uniqueName) { + StopRemoteServiceTokenSource = new CancellationTokenSource(); + // Build unique application Id and the IPC channel name. string applicationIdentifier = uniqueName + Environment.UserName; @@ -261,12 +272,12 @@ public static bool InitializeAsFirstInstance(string uniqueName) singleInstanceMutex = new Mutex(true, applicationIdentifier, out var firstInstance); if (firstInstance) { - _ = StartRemoteServiceAsync(channelName, StopRemoteServiceTokenSource.Token); + _ = Task.Run(() => StartRemoteServiceAsync(channelName, StopRemoteServiceTokenSource.Token)); return true; } else { - _ = SignalFirstInstanceAsync(channelName); + _ = Task.Run(() => SignalFirstInstanceAsync(channelName)); return false; } } @@ -336,27 +347,32 @@ private static IList GetCommandLineArgs(string uniqueApplicationName) /// Cancellation token private static async Task StartRemoteServiceAsync(string channelName, CancellationToken token = default) { - await using NamedPipeServerStream pipeServer = new NamedPipeServerStream(channelName, PipeDirection.In); - while (true) + try { - if (token.IsCancellationRequested) + await using NamedPipeServerStream pipeServer = new NamedPipeServerStream(channelName, PipeDirection.In); + while (true) { - break; - } + if (token.IsCancellationRequested) + { + break; + } - // Wait for connection to the pipe - await pipeServer.WaitForConnectionAsync(token); - if (Application.Current != null) - { - // Do an asynchronous call to ActivateFirstInstance function - Application.Current.Dispatcher.Invoke(ActivateFirstInstance); - } + // Wait for connection to the pipe + await pipeServer.WaitForConnectionAsync(token); + if (Application.Current != null) + { + // Do an asynchronous call to ActivateFirstInstance function + Application.Current.Dispatcher.Invoke(ActivateFirstInstance); + } - // Disconnect client - pipeServer.Disconnect(); + // Disconnect client + pipeServer.Disconnect(); + } + } + finally + { + RemoteServiceRunning = false; } - - RemoteServiceRunning = true; } /// @@ -366,7 +382,8 @@ private static async Task StartRemoteServiceAsync(string channelName, Cancellati private static async Task SignalFirstInstanceAsync(string channelName) { // Create a client pipe connected to server - await using NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", channelName, PipeDirection.Out); + await using NamedPipeClientStream pipeClient = + new NamedPipeClientStream(".", channelName, PipeDirection.Out); // Connect to the available pipe await pipeClient.ConnectAsync(0); } diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 00e7df3d005..6d5d4e1ba0f 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -4,7 +4,6 @@ using System.Net; using System.Threading.Tasks; using System.Windows; -using Squirrel; using Flow.Launcher.Core.Plugin; using Flow.Launcher.Core.Resource; using Flow.Launcher.Helper; diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs index 792891ad1a5..7a7496ece1a 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs @@ -1,5 +1,5 @@ -using ICSharpCode.SharpZipLib.Zip; -using System.IO; +using System.IO; +using System.IO.Compression; namespace Flow.Launcher.Plugin.PluginsManager { @@ -13,29 +13,7 @@ internal static class Utilities /// overwrite internal static void UnZip(string zipFilePath, string strDirectory, bool overwrite) { - if (strDirectory == "") - strDirectory = Directory.GetCurrentDirectory(); - - using var zipStream = new ZipInputStream(File.OpenRead(zipFilePath)); - - ZipEntry theEntry; - - while ((theEntry = zipStream.GetNextEntry()) != null) - { - var pathToZip = theEntry.Name; - var directoryName = string.IsNullOrEmpty(pathToZip) ? "" : Path.GetDirectoryName(pathToZip); - var fileName = Path.GetFileName(pathToZip); - var destinationDir = Path.Combine(strDirectory, directoryName); - var destinationFile = Path.Combine(destinationDir, fileName); - - Directory.CreateDirectory(destinationDir); - - if (string.IsNullOrEmpty(fileName) || (File.Exists(destinationFile) && !overwrite)) - continue; - - using var streamWriter = File.Create(destinationFile); - zipStream.CopyTo(streamWriter); - } + ZipFile.ExtractToDirectory(zipFilePath, strDirectory, overwrite); } internal static string GetContainingFolderPathAfterUnzip(string unzippedParentFolderPath) diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index 1757ed99e22..b1f566abf3e 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -1,14 +1,19 @@ param( - [string]$config = "Release", - [string]$solution = (Join-Path $PSScriptRoot ".." -Resolve) + [string]$config = "Release", + [string]$solution = (Join-Path $PSScriptRoot ".." -Resolve), + [string]$channel = "prerelease" ) Write-Host "Config: $config" -function Build-Version { - if ([string]::IsNullOrEmpty($env:flowVersion)) { +function Build-Version +{ + if ( [string]::IsNullOrEmpty($env:flowVersion)) + { $targetPath = Join-Path $solution "Output/Release/Flow.Launcher.dll" -Resolve $v = (Get-Command ${targetPath}).FileVersionInfo.FileVersion - } else { + } + else + { $v = $env:flowVersion } @@ -16,12 +21,18 @@ function Build-Version { return $v } -function Build-Path { - if (![string]::IsNullOrEmpty($env:APPVEYOR_BUILD_FOLDER)) { +function Build-Path +{ + if (![string]::IsNullOrEmpty($env:APPVEYOR_BUILD_FOLDER)) + { $p = $env:APPVEYOR_BUILD_FOLDER - } elseif (![string]::IsNullOrEmpty($solution)) { + } + elseif (![string]::IsNullOrEmpty($solution)) + { $p = $solution - } else { + } + else + { $p = Get-Location } @@ -31,23 +42,38 @@ function Build-Path { return $p } -function Copy-Resources ($path) { +function Copy-Resources($path) +{ # making version static as multiple versions can exist in the nuget folder and in the case a breaking change is introduced. Copy-Item -Force $env:USERPROFILE\.nuget\packages\squirrel.windows\1.5.2\tools\Squirrel.exe $path\Output\Update.exe } -function Delete-Unused ($path, $config) { +function Delete-Unused($path, $config) +{ $target = "$path\Output\$config" - $included = Get-ChildItem $target -Filter "*.dll" - foreach ($i in $included){ - $deleteList = Get-ChildItem $target\Plugins -Include $i -Recurse | Where { $_.VersionInfo.FileVersion -eq $i.VersionInfo.FileVersion -And $_.Name -eq "$i" } - $deleteList | ForEach-Object{ Write-Host Deleting duplicated $_.Name with version $_.VersionInfo.FileVersion at location $_.Directory.FullName } - $deleteList | Remove-Item + $included = @{ } + Get-ChildItem $target -Filter "*.dll" | Get-FileHash | ForEach-Object { + $hash = $_.hash + $filename = $_.Path | Split-Path -Leaf + $included.Add([tuple]::Create($filename, $hash), $true) + } + + $deleteList = Get-ChildItem $target\Plugins -Filter "*.dll" -Recurse | + Select-Object Name, VersionInfo, Directory, @{ name = "hash"; expression = { (Get-FileHash $_.FullName) } } | + Where-Object { + $included.Contains([tuple]::Create($_.Name, $_.hash)) + } + + $deleteList | ForEach-Object { + Write-Host Deleting duplicated $_.Name with version $_.VersionInfo.FileVersion at location $_.Directory.FullName } - Remove-Item -Path $target -Include "*.xml" -Recurse + $deleteList | Remove-Item -Path { $_.FullName } + + Remove-Item -Path $target -Include "*.xml" -Recurse } -function Remove-CreateDumpExe ($path, $config) { +function Remove-CreateDumpExe($path, $config) +{ $target = "$path\Output\$config" $depjson = Get-Content $target\Flow.Launcher.deps.json -raw @@ -56,12 +82,14 @@ function Remove-CreateDumpExe ($path, $config) { } -function Validate-Directory ($output) { +function Validate-Directory($output) +{ New-Item $output -ItemType Directory -Force } -function Pack-Squirrel-Installer ($path, $version, $output) { +function Pack-Squirrel-Installer($path, $version, $output) +{ # msbuild based installer generation is not working in appveyor, not sure why Write-Host "Begin pack squirrel installer" @@ -71,34 +99,20 @@ function Pack-Squirrel-Installer ($path, $version, $output) { Write-Host "Packing: $spec" Write-Host "Input path: $input" - # dotnet pack is not used because ran into issues, need to test installation and starting up if to use it. - nuget pack $spec -Version $version -BasePath $input -OutputDirectory $output -Properties Configuration=Release - - $nupkg = "$output\FlowLauncher.$version.nupkg" - Write-Host "nupkg path: $nupkg" - $icon = "$path\Flow.Launcher\Resources\app.ico" - Write-Host "icon: $icon" - # Squirrel.com: https://github.com/Squirrel/Squirrel.Windows/issues/369 - New-Alias Squirrel $env:USERPROFILE\.nuget\packages\squirrel.windows\1.5.2\tools\Squirrel.exe -Force - # why we need Write-Output: https://github.com/Squirrel/Squirrel.Windows/issues/489#issuecomment-156039327 - # directory of releaseDir in squirrel can't be same as directory ($nupkg) in releasify - $temp = "$output\Temp" - - Squirrel --releasify $nupkg --releaseDir $temp --setupIcon $icon --no-msi | Write-Output - Move-Item $temp\* $output -Force - Remove-Item $temp + $repoUrl = "https://github.com/Flow-Launcher/Prereleases" - $file = "$output\Flow-Launcher-Setup.exe" - Write-Host "Filename: $file" - - Move-Item "$output\Setup.exe" $file -Force - - Write-Host "End pack squirrel installer" + if ($channel -eq "stable") + { + $repoUrl = "https://github.com/Flow-Launcher/Flow.Launcher" + } + + vpk pack --packVersion $version --packDir $input --packId FlowLauncher --mainExe Flow.Launcher.exe --channel $channel } -function Publish-Self-Contained ($p) { +function Publish-Self-Contained($p) +{ - $csproj = Join-Path "$p" "Flow.Launcher/Flow.Launcher.csproj" -Resolve + $csproj = Join-Path "$p" "Flow.Launcher/Flow.Launcher.csproj" -Resolve $profile = Join-Path "$p" "Flow.Launcher/Properties/PublishProfiles/Net7.0-SelfContained.pubxml" -Resolve # we call dotnet publish on the main project. @@ -106,31 +120,32 @@ function Publish-Self-Contained ($p) { dotnet publish -c Release $csproj /p:PublishProfile=$profile } -function Publish-Portable ($outputLocation, $version) { - +function Publish-Portable($outputLocation, $version) +{ + & $outputLocation\Flow-Launcher-Setup.exe --silent | Out-Null mkdir "$env:LocalAppData\FlowLauncher\app-$version\UserData" Compress-Archive -Path $env:LocalAppData\FlowLauncher -DestinationPath $outputLocation\Flow-Launcher-Portable.zip } -function Main { +function Main +{ $p = Build-Path $v = Build-Version Copy-Resources $p - if ($config -eq "Release"){ - + if ($config -eq "Release") + { + Delete-Unused $p $config Publish-Self-Contained $p - Remove-CreateDumpExe $p $config - $o = "$p\Output\Packages" Validate-Directory $o Pack-Squirrel-Installer $p $v $o - Publish-Portable $o $v + # Publish-Portable $o $v } } diff --git a/appveyor.yml b/appveyor.yml index b84230c434c..6a96f88d869 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,6 +7,9 @@ init: if ($env:APPVEYOR_REPO_BRANCH -eq "dev") { $env:prereleaseTag = "{0}.{1}.{2}.{3}" -f $version.Major, $version.Minor, $version.Build, $version.Revision + $env:channel = "prerelease" + } else { + $env:channel = "stable" } - sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest - net start WSearch @@ -40,12 +43,12 @@ artifacts: name: Plugin nupkg - path: 'Output\Packages\Flow-Launcher-*.exe' name: Squirrel Installer -- path: Output\Packages\Flow-Launcher-Portable.zip +- path: Release\Flow-Launcher-Portable.zip name: Portable Version -- path: 'Output\Packages\FlowLauncher-*-full.nupkg' +- path: 'Release\FlowLauncher-*-full.nupkg' name: Squirrel nupkg -- path: 'Output\Packages\RELEASES' - name: Squirrel RELEASES +- path: 'Release\RELEASES*' + name: Velopack RELEASES deploy: - provider: NuGet From f5762f6ad11902e70151751d837d34a215383494 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sun, 24 Mar 2024 13:52:05 -0500 Subject: [PATCH 03/75] modify argument for post_build.ps1 --- Scripts/post_build.ps1 | 4 +++- appveyor.yml | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index b1f566abf3e..6486160b8f8 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -1,9 +1,11 @@ param( [string]$config = "Release", [string]$solution = (Join-Path $PSScriptRoot ".." -Resolve), - [string]$channel = "prerelease" + [string]$channel = "win-x64-prerelease" ) Write-Host "Config: $config" +Write-Host "Solution: $solution" +Write-Host "Channel: $channel" function Build-Version { diff --git a/appveyor.yml b/appveyor.yml index 6a96f88d869..2752844d85b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,9 +7,9 @@ init: if ($env:APPVEYOR_REPO_BRANCH -eq "dev") { $env:prereleaseTag = "{0}.{1}.{2}.{3}" -f $version.Major, $version.Minor, $version.Build, $version.Revision - $env:channel = "prerelease" + $env:channel = "win-x64-prerelease" } else { - $env:channel = "stable" + $env:channel = "win-x64-stable" } - sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest - net start WSearch @@ -36,7 +36,7 @@ build: test_script: - dotnet test --no-build -c Release after_test: - - ps: .\Scripts\post_build.ps1 + - ps: .\Scripts\post_build.ps1 -channel $env:channel artifacts: - path: 'Output\Release\Flow.Launcher.Plugin.*.nupkg' From 3a885eada1d87ec34652b98c09202f6dc05cd1ce Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sun, 24 Mar 2024 13:53:03 -0500 Subject: [PATCH 04/75] install required tool --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 2752844d85b..749c5ada28b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,6 +11,8 @@ init: } else { $env:channel = "win-x64-stable" } + dotnet tool update -g vpk + - sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest - net start WSearch From 2f7bd563971ed190d3b15546ad4079edc56b36fe Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sun, 24 Mar 2024 13:54:35 -0500 Subject: [PATCH 05/75] fix upload --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 749c5ada28b..148a12d19d0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -41,9 +41,9 @@ after_test: - ps: .\Scripts\post_build.ps1 -channel $env:channel artifacts: -- path: 'Output\Release\Flow.Launcher.Plugin.*.nupkg' +- path: 'Release\Flow.Launcher.Plugin.*.nupkg' name: Plugin nupkg -- path: 'Output\Packages\Flow-Launcher-*.exe' +- path: 'Release\Flow-Launcher-*.exe' name: Squirrel Installer - path: Release\Flow-Launcher-Portable.zip name: Portable Version From eecd5fee5e30968b42e3779ae2fadcef9832703e Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sun, 24 Mar 2024 14:14:33 -0500 Subject: [PATCH 06/75] fix upload path --- appveyor.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 148a12d19d0..aeb4f53eb90 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -41,15 +41,15 @@ after_test: - ps: .\Scripts\post_build.ps1 -channel $env:channel artifacts: -- path: 'Release\Flow.Launcher.Plugin.*.nupkg' +- path: 'Output\Release\Flow.Launcher.Plugin.*.nupkg' name: Plugin nupkg -- path: 'Release\Flow-Launcher-*.exe' +- path: 'Releases\Flow-Launcher-*.exe' name: Squirrel Installer - path: Release\Flow-Launcher-Portable.zip name: Portable Version -- path: 'Release\FlowLauncher-*-full.nupkg' +- path: 'Releases\FlowLauncher-*-full.nupkg' name: Squirrel nupkg -- path: 'Release\RELEASES*' +- path: 'Releases\RELEASES*' name: Velopack RELEASES deploy: From 559666b4a2b5f9fd9b5a8412e1ebd7faf711b6d4 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 13:14:17 -0500 Subject: [PATCH 07/75] clean up post_build and roll back delete unused --- Scripts/post_build.ps1 | 54 ++++++++++-------------------------------- 1 file changed, 12 insertions(+), 42 deletions(-) diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index 6486160b8f8..50f72578a0a 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -50,39 +50,20 @@ function Copy-Resources($path) Copy-Item -Force $env:USERPROFILE\.nuget\packages\squirrel.windows\1.5.2\tools\Squirrel.exe $path\Output\Update.exe } + function Delete-Unused($path, $config) { $target = "$path\Output\$config" - $included = @{ } - Get-ChildItem $target -Filter "*.dll" | Get-FileHash | ForEach-Object { - $hash = $_.hash - $filename = $_.Path | Split-Path -Leaf - $included.Add([tuple]::Create($filename, $hash), $true) - } - - $deleteList = Get-ChildItem $target\Plugins -Filter "*.dll" -Recurse | - Select-Object Name, VersionInfo, Directory, @{ name = "hash"; expression = { (Get-FileHash $_.FullName) } } | - Where-Object { - $included.Contains([tuple]::Create($_.Name, $_.hash)) - } - - $deleteList | ForEach-Object { - Write-Host Deleting duplicated $_.Name with version $_.VersionInfo.FileVersion at location $_.Directory.FullName + $included = Get-ChildItem $target -Filter "*.dll" + foreach ($i in $included) + { + $deleteList = Get-ChildItem $target\Plugins -Include $i -Recurse | Where { $_.VersionInfo.FileVersion -eq $i.VersionInfo.FileVersion -And $_.Name -eq "$i" } + $deleteList | ForEach-Object{ Write-Host Deleting duplicated $_.Name with version $_.VersionInfo.FileVersion at location $_.Directory.FullName } + $deleteList | Remove-Item } - $deleteList | Remove-Item -Path { $_.FullName } - Remove-Item -Path $target -Include "*.xml" -Recurse } -function Remove-CreateDumpExe($path, $config) -{ - $target = "$path\Output\$config" - - $depjson = Get-Content $target\Flow.Launcher.deps.json -raw - $depjson -replace '(?s)(.createdump.exe": {.*?}.*?\n)\s*', "" | Out-File $target\Flow.Launcher.deps.json -Encoding UTF8 - Remove-Item -Path $target -Include "*createdump.exe" -Recurse -} - function Validate-Directory($output) { @@ -90,7 +71,7 @@ function Validate-Directory($output) } -function Pack-Squirrel-Installer($path, $version, $output) +function Pack-Velopack-Installer($path, $version, $output) { # msbuild based installer generation is not working in appveyor, not sure why Write-Host "Begin pack squirrel installer" @@ -102,32 +83,23 @@ function Pack-Squirrel-Installer($path, $version, $output) Write-Host "Input path: $input" $repoUrl = "https://github.com/Flow-Launcher/Prereleases" - + if ($channel -eq "stable") { $repoUrl = "https://github.com/Flow-Launcher/Flow.Launcher" } - + vpk pack --packVersion $version --packDir $input --packId FlowLauncher --mainExe Flow.Launcher.exe --channel $channel } function Publish-Self-Contained($p) { - $csproj = Join-Path "$p" "Flow.Launcher/Flow.Launcher.csproj" -Resolve $profile = Join-Path "$p" "Flow.Launcher/Properties/PublishProfiles/Net7.0-SelfContained.pubxml" -Resolve # we call dotnet publish on the main project. # The other projects should have been built in Release at this point. - dotnet publish -c Release $csproj /p:PublishProfile=$profile -} - -function Publish-Portable($outputLocation, $version) -{ - - & $outputLocation\Flow-Launcher-Setup.exe --silent | Out-Null - mkdir "$env:LocalAppData\FlowLauncher\app-$version\UserData" - Compress-Archive -Path $env:LocalAppData\FlowLauncher -DestinationPath $outputLocation\Flow-Launcher-Portable.zip + dotnet publish --no-build -c Release $csproj /p:PublishProfile=$profile } function Main @@ -145,9 +117,7 @@ function Main $o = "$p\Output\Packages" Validate-Directory $o - Pack-Squirrel-Installer $p $v $o - - # Publish-Portable $o $v + Pack-Velopack-Installer $p $v $o } } From bd5bed2634683aefe89c8f1ee42260a152144ed0 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 13:26:02 -0500 Subject: [PATCH 08/75] fix up artifact name --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index aeb4f53eb90..eafbd0851d1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -43,9 +43,9 @@ after_test: artifacts: - path: 'Output\Release\Flow.Launcher.Plugin.*.nupkg' name: Plugin nupkg -- path: 'Releases\Flow-Launcher-*.exe' +- path: 'Releases\FlowLauncher-*.exe' name: Squirrel Installer -- path: Release\Flow-Launcher-Portable.zip +- path: 'Release\FlowLauncher-*-Portable.zip' name: Portable Version - path: 'Releases\FlowLauncher-*-full.nupkg' name: Squirrel nupkg From 765c30fbca5c1790074f2cc4ad09218354c81c53 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 13:29:38 -0500 Subject: [PATCH 09/75] remove cache to test and skip pr build --- appveyor.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index eafbd0851d1..a9cadd1bce9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,8 +16,10 @@ init: - sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest - net start WSearch -cache: - - '%USERPROFILE%\.nuget\packages -> **.sln, **.csproj' # preserve nuget folder (packages) unless the solution or projects change +#cache: +# - '%USERPROFILE%\.nuget\packages -> **.sln, **.csproj' # preserve nuget folder (packages) unless the solution or projects change + +skip_branch_with_pr: true assembly_info: From d562441b9247c4ffa058be43bcbc489741037ef9 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 13:37:07 -0500 Subject: [PATCH 10/75] delete no-build --- Scripts/post_build.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index 50f72578a0a..6d278879090 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -99,7 +99,7 @@ function Publish-Self-Contained($p) # we call dotnet publish on the main project. # The other projects should have been built in Release at this point. - dotnet publish --no-build -c Release $csproj /p:PublishProfile=$profile + dotnet publish -c Release $csproj /p:PublishProfile=$profile } function Main From be8612912c90b6aee49a1aad168b0d12df037dce Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 13:37:33 -0500 Subject: [PATCH 11/75] delete unused arg --- Scripts/post_build.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index 6d278879090..0ab3a444ef8 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -99,7 +99,7 @@ function Publish-Self-Contained($p) # we call dotnet publish on the main project. # The other projects should have been built in Release at this point. - dotnet publish -c Release $csproj /p:PublishProfile=$profile + dotnet publish $csproj /p:PublishProfile=$profile } function Main From 0644f320da829997bb6f9f64afb49fc40951bcc3 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 13:42:54 -0500 Subject: [PATCH 12/75] remove squirrel --- Scripts/post_build.ps1 | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index 0ab3a444ef8..a769c8483a6 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -44,12 +44,6 @@ function Build-Path return $p } -function Copy-Resources($path) -{ - # making version static as multiple versions can exist in the nuget folder and in the case a breaking change is introduced. - Copy-Item -Force $env:USERPROFILE\.nuget\packages\squirrel.windows\1.5.2\tools\Squirrel.exe $path\Output\Update.exe -} - function Delete-Unused($path, $config) { @@ -106,7 +100,6 @@ function Main { $p = Build-Path $v = Build-Version - Copy-Resources $p if ($config -eq "Release") { From f7f37592ea7bc6ba01bf8d9619a476445dcf191b Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 13:53:46 -0500 Subject: [PATCH 13/75] test cache again --- Scripts/post_build.ps1 | 1 - appveyor.yml | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index a769c8483a6..836fdfb8917 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -103,7 +103,6 @@ function Main if ($config -eq "Release") { - Delete-Unused $p $config Publish-Self-Contained $p diff --git a/appveyor.yml b/appveyor.yml index a9cadd1bce9..1c27365e4fb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,12 +12,13 @@ init: $env:channel = "win-x64-stable" } dotnet tool update -g vpk + $env:APPVEYOR_CACHE_ENTRY_ZIP_ARGS = "-t7z -m0=lzma -mx=9" - sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest - net start WSearch -#cache: -# - '%USERPROFILE%\.nuget\packages -> **.sln, **.csproj' # preserve nuget folder (packages) unless the solution or projects change +cache: + - '%USERPROFILE%\.nuget\packages -> **.sln, **.csproj' # preserve nuget folder (packages) unless the solution or projects change skip_branch_with_pr: true From 653ee90401c7e44de1380bae2d297759e851ee1f Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 14:08:03 -0500 Subject: [PATCH 14/75] empty From 9785ec8a26fe0d54698ab0aca62cc3680c01ce6e Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 14:28:33 -0500 Subject: [PATCH 15/75] test github action and remove cache as it is so slow --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 1c27365e4fb..f7912095c74 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,8 +17,8 @@ init: - sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest - net start WSearch -cache: - - '%USERPROFILE%\.nuget\packages -> **.sln, **.csproj' # preserve nuget folder (packages) unless the solution or projects change +#cache: +# - '%USERPROFILE%\.nuget\packages -> **.sln, **.csproj' # preserve nuget folder (packages) unless the solution or projects change skip_branch_with_pr: true From 0d316a576624b63b43587199b022a76a76074489 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 14:30:19 -0500 Subject: [PATCH 16/75] test github action --- .github/workflows/dotnet.yml | 88 ++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 .github/workflows/dotnet.yml diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml new file mode 100644 index 00000000000..d6c6f82ffe2 --- /dev/null +++ b/.github/workflows/dotnet.yml @@ -0,0 +1,88 @@ +# This workflow will build a .NET project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net + +name: .NET + +on: + workflow_dispatch: + push: + pull_request: + branches: + - dev + - master + +jobs: + build: + + runs-on: windows-latest + + steps: + - name: Initialize Service + run: | + sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest + net start WSearch + - name: Set version in all AssemblyInfo.cs files + uses: secondbounce/assemblyinfo-update@v2 + with: + version: '1.9.5' + - if: ${{ runner.os == 'Windows' }} + name: Use GNU tar + shell: cmd + run: | + echo "Adding GNU tar to PATH" + echo C:\Program Files\Git\usr\bin>>"%GITHUB_PATH%" + - uses: actions/cache@v4 + with: + path: | + ~/.nuget/packages + !~/.nuget/packages/microsoft.netcore.app.* + key: ${{ runner.os }}-nuget-${{ hashFiles('**/csproj') }} + restore-keys: | + ${{ runner.os }}-nuget- + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 7.0.x + - name: Restore dependencies + run: dotnet restore + - name: Build + run: dotnet build --no-restore -c Release + - name: Test + run: dotnet test --no-build --verbosity normal -c Release + - name: Perform post_build tasks + shell: pwsh + run: .\Scripts\post_build.ps1 + - name: Upload Plugin Nupkg + uses: actions/upload-artifact@v4 + with: + name: Plugin nupkg + path: | + Output\Release\Flow.Launcher.Plugin.*.nupkg + - name: Upload Setup + uses: actions/upload-artifact@v3 + with: + name: Flow Installer + path: | + Releases\Flow-Launcher-*.exe + - name: Upload Portable Version + uses: actions/upload-artifact@v3 + with: + name: Portable Version + path: | + Releases\Flow-Launcher-Portable.zip + - name: Upload Full Nupkg + uses: actions/upload-artifact@v3 + with: + name: Full nupkg + path: | + Releases\FlowLauncher-*-full.nupkg + + - name: Upload Release Information + uses: actions/upload-artifact@v3 + with: + name: RELEASES + path: | + Releases\RELEASES + + From b886408045b42ed173ef32eb994249ae7c316821 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 14:32:52 -0500 Subject: [PATCH 17/75] trigger push only on dev/master --- .github/workflows/dotnet.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d6c6f82ffe2..e5407945a9f 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -6,6 +6,9 @@ name: .NET on: workflow_dispatch: push: + branches: + - dev + - master pull_request: branches: - dev From f5b18803510f6959428034a9a06230beb56b61cb Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 14:37:44 -0500 Subject: [PATCH 18/75] install vpk --- .github/workflows/dotnet.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index e5407945a9f..39e0b09a57b 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -47,6 +47,8 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: 7.0.x + - name: Install vpk + run: dotnet tool update -g vpk - name: Restore dependencies run: dotnet restore - name: Build From 5532efba981dcdf274f8c47678e7683ce0f000e6 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 14:46:02 -0500 Subject: [PATCH 19/75] do not compress for artifacts as either binary or too small --- .github/workflows/dotnet.yml | 144 ++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 70 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 39e0b09a57b..c9afa47c827 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -9,7 +9,7 @@ on: branches: - dev - master - pull_request: + pull_request: branches: - dev - master @@ -20,74 +20,78 @@ jobs: runs-on: windows-latest steps: - - name: Initialize Service - run: | - sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest - net start WSearch - - name: Set version in all AssemblyInfo.cs files - uses: secondbounce/assemblyinfo-update@v2 - with: - version: '1.9.5' - - if: ${{ runner.os == 'Windows' }} - name: Use GNU tar - shell: cmd - run: | - echo "Adding GNU tar to PATH" - echo C:\Program Files\Git\usr\bin>>"%GITHUB_PATH%" - - uses: actions/cache@v4 - with: - path: | - ~/.nuget/packages - !~/.nuget/packages/microsoft.netcore.app.* - key: ${{ runner.os }}-nuget-${{ hashFiles('**/csproj') }} - restore-keys: | - ${{ runner.os }}-nuget- - - uses: actions/checkout@v4 - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 7.0.x - - name: Install vpk - run: dotnet tool update -g vpk - - name: Restore dependencies - run: dotnet restore - - name: Build - run: dotnet build --no-restore -c Release - - name: Test - run: dotnet test --no-build --verbosity normal -c Release - - name: Perform post_build tasks - shell: pwsh - run: .\Scripts\post_build.ps1 - - name: Upload Plugin Nupkg - uses: actions/upload-artifact@v4 - with: - name: Plugin nupkg - path: | - Output\Release\Flow.Launcher.Plugin.*.nupkg - - name: Upload Setup - uses: actions/upload-artifact@v3 - with: - name: Flow Installer - path: | - Releases\Flow-Launcher-*.exe - - name: Upload Portable Version - uses: actions/upload-artifact@v3 - with: - name: Portable Version - path: | - Releases\Flow-Launcher-Portable.zip - - name: Upload Full Nupkg - uses: actions/upload-artifact@v3 - with: - name: Full nupkg - path: | - Releases\FlowLauncher-*-full.nupkg + - name: Initialize Service + run: | + sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest + net start WSearch + - name: Set version in all AssemblyInfo.cs files + uses: secondbounce/assemblyinfo-update@v2 + with: + version: '1.9.5' + - if: ${{ runner.os == 'Windows' }} + name: Use GNU tar + shell: cmd + run: | + echo "Adding GNU tar to PATH" + echo C:\Program Files\Git\usr\bin>>"%GITHUB_PATH%" + - uses: actions/cache@v4 + with: + path: | + ~/.nuget/packages + !~/.nuget/packages/microsoft.netcore.app.* + key: ${{ runner.os }}-nuget-${{ hashFiles('**/csproj') }} + restore-keys: | + ${{ runner.os }}-nuget- + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 7.0.x + - name: Install vpk + run: dotnet tool update -g vpk + - name: Restore dependencies + run: dotnet restore + - name: Build + run: dotnet build --no-restore -c Release + - name: Test + run: dotnet test --no-build --verbosity normal -c Release + - name: Perform post_build tasks + shell: pwsh + run: .\Scripts\post_build.ps1 + - name: Upload Plugin Nupkg + uses: actions/upload-artifact@v4 + with: + name: Plugin nupkg + path: | + Output\Release\Flow.Launcher.Plugin.*.nupkg + compression-level: 0 + - name: Upload Setup + uses: actions/upload-artifact@v3 + with: + name: Flow Installer + path: | + Releases\FlowLauncher-*.exe + compression-level: 0 + - name: Upload Portable Version + uses: actions/upload-artifact@v3 + with: + name: Portable Version + path: | + Releases\FlowLauncher-Portable.zip + compression-level: 0 + - name: Upload Full Nupkg + uses: actions/upload-artifact@v3 + with: + name: Full nupkg + path: | + Releases\FlowLauncher-*-full.nupkg - - name: Upload Release Information - uses: actions/upload-artifact@v3 - with: - name: RELEASES - path: | - Releases\RELEASES - + compression-level: 0 + - name: Upload Release Information + uses: actions/upload-artifact@v3 + with: + name: RELEASES + path: | + Releases\RELEASES + compression-level: 0 From c4e38b1daab1f78427ed24e3e2e03dc4711b0b0f Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 14:52:47 -0500 Subject: [PATCH 20/75] use v4 for upload artifact --- .github/workflows/dotnet.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index c9afa47c827..ef5e0387de6 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -66,21 +66,21 @@ jobs: Output\Release\Flow.Launcher.Plugin.*.nupkg compression-level: 0 - name: Upload Setup - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Flow Installer path: | Releases\FlowLauncher-*.exe compression-level: 0 - name: Upload Portable Version - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Portable Version path: | Releases\FlowLauncher-Portable.zip compression-level: 0 - name: Upload Full Nupkg - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Full nupkg path: | @@ -88,7 +88,7 @@ jobs: compression-level: 0 - name: Upload Release Information - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: RELEASES path: | From a7c22270cb7bbfe269166001a4599934aeada3ce Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 14:58:52 -0500 Subject: [PATCH 21/75] fix cache key --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index ef5e0387de6..d13088bf33a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -39,7 +39,7 @@ jobs: path: | ~/.nuget/packages !~/.nuget/packages/microsoft.netcore.app.* - key: ${{ runner.os }}-nuget-${{ hashFiles('**/csproj') }} + key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }} restore-keys: | ${{ runner.os }}-nuget- - uses: actions/checkout@v4 From 05a5a50f7a5d501da8f0ea7347628d7ab1eae3d0 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 15:15:59 -0500 Subject: [PATCH 22/75] try new nunit --- Flow.Launcher.Test/FilesFoldersTest.cs | 5 +- Flow.Launcher.Test/Flow.Launcher.Test.csproj | 7 +-- Flow.Launcher.Test/FuzzyMatcherTest.cs | 29 +++++----- Flow.Launcher.Test/HttpTest.cs | 13 +++-- Flow.Launcher.Test/PluginLoadTest.cs | 13 +++-- Flow.Launcher.Test/Plugins/ExplorerTest.cs | 41 ++++++------- .../Plugins/JsonRPCPluginTest.cs | 58 +++++++++---------- Flow.Launcher.Test/Plugins/UrlPluginTest.cs | 30 +++++----- Flow.Launcher.Test/QueryBuilderTest.cs | 39 +++++++------ 9 files changed, 119 insertions(+), 116 deletions(-) diff --git a/Flow.Launcher.Test/FilesFoldersTest.cs b/Flow.Launcher.Test/FilesFoldersTest.cs index 3dead99183e..2621fc2da1f 100644 --- a/Flow.Launcher.Test/FilesFoldersTest.cs +++ b/Flow.Launcher.Test/FilesFoldersTest.cs @@ -1,5 +1,6 @@ using Flow.Launcher.Plugin.SharedCommands; using NUnit.Framework; +using NUnit.Framework.Legacy; namespace Flow.Launcher.Test { @@ -35,7 +36,7 @@ public class FilesFoldersTest [TestCase(@"c:\barr", @"c:\foo\..\bar\baz", false)] public void GivenTwoPaths_WhenCheckPathContains_ThenShouldBeExpectedResult(string parentPath, string path, bool expectedResult) { - Assert.AreEqual(expectedResult, FilesFolders.PathContains(parentPath, path)); + ClassicAssert.AreEqual(expectedResult, FilesFolders.PathContains(parentPath, path)); } // Equality @@ -47,7 +48,7 @@ public void GivenTwoPaths_WhenCheckPathContains_ThenShouldBeExpectedResult(strin [TestCase(@"c:\foo", @"c:\foo\", true)] public void GivenTwoPathsAreTheSame_WhenCheckPathContains_ThenShouldBeExpectedResult(string parentPath, string path, bool expectedResult) { - Assert.AreEqual(expectedResult, FilesFolders.PathContains(parentPath, path, allowEqual: expectedResult)); + ClassicAssert.AreEqual(expectedResult, FilesFolders.PathContains(parentPath, path, allowEqual: expectedResult)); } } } diff --git a/Flow.Launcher.Test/Flow.Launcher.Test.csproj b/Flow.Launcher.Test/Flow.Launcher.Test.csproj index 29414baa600..add321b8f98 100644 --- a/Flow.Launcher.Test/Flow.Launcher.Test.csproj +++ b/Flow.Launcher.Test/Flow.Launcher.Test.csproj @@ -49,12 +49,9 @@ - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + + \ No newline at end of file diff --git a/Flow.Launcher.Test/FuzzyMatcherTest.cs b/Flow.Launcher.Test/FuzzyMatcherTest.cs index d7f1432184c..c22e21a81d0 100644 --- a/Flow.Launcher.Test/FuzzyMatcherTest.cs +++ b/Flow.Launcher.Test/FuzzyMatcherTest.cs @@ -6,6 +6,7 @@ using Flow.Launcher.Infrastructure; using Flow.Launcher.Plugin; using Flow.Launcher.Plugin.SharedModels; +using NUnit.Framework.Legacy; namespace Flow.Launcher.Test { @@ -71,10 +72,10 @@ public void MatchTest() results = results.Where(x => x.Score > 0).OrderByDescending(x => x.Score).ToList(); - Assert.IsTrue(results.Count == 3); - Assert.IsTrue(results[0].Title == "Inste"); - Assert.IsTrue(results[1].Title == "Install Package"); - Assert.IsTrue(results[2].Title == "file open in browser-test"); + ClassicAssert.IsTrue(results.Count == 3); + ClassicAssert.IsTrue(results[0].Title == "Inste"); + ClassicAssert.IsTrue(results[1].Title == "Install Package"); + ClassicAssert.IsTrue(results[2].Title == "file open in browser-test"); } [TestCase("Chrome")] @@ -84,7 +85,7 @@ public void WhenNotAllCharactersFoundInSearchString_ThenShouldReturnZeroScore(st var matcher = new StringMatcher(); var scoreResult = matcher.FuzzyMatch(searchString, compareString).RawScore; - Assert.True(scoreResult == 0); + ClassicAssert.True(scoreResult == 0); } [TestCase("chr")] @@ -125,7 +126,7 @@ public void GivenQueryString_WhenAppliedPrecisionFiltering_ThenShouldReturnGreat Debug.WriteLine("###############################################"); Debug.WriteLine(""); - Assert.IsFalse(filteredResult.Any(x => x.Score < precisionScore)); + ClassicAssert.IsFalse(filteredResult.Any(x => x.Score < precisionScore)); } } @@ -151,7 +152,7 @@ public void WhenGivenQueryString_ThenShouldReturn_TheDesiredScoring( var rawScore = matcher.FuzzyMatch(queryString, compareString).RawScore; // Should - Assert.AreEqual(expectedScore, rawScore, + ClassicAssert.AreEqual(expectedScore, rawScore, $"Expected score for compare string '{compareString}': {expectedScore}, Actual: {rawScore}"); } @@ -195,7 +196,7 @@ public void WhenGivenDesiredPrecision_ThenShouldReturn_AllResultsGreaterOrEqual( Debug.WriteLine(""); // Should - Assert.AreEqual(expectedPrecisionResult, matchResult.IsSearchPrecisionScoreMet(), + ClassicAssert.AreEqual(expectedPrecisionResult, matchResult.IsSearchPrecisionScoreMet(), $"Query: {queryString}{Environment.NewLine} " + $"Compare: {compareString}{Environment.NewLine}" + $"Raw Score: {matchResult.RawScore}{Environment.NewLine}" + @@ -246,7 +247,7 @@ public void WhenGivenQuery_ShouldReturnResults_ContainingAllQuerySubstrings( Debug.WriteLine(""); // Should - Assert.AreEqual(expectedPrecisionResult, matchResult.IsSearchPrecisionScoreMet(), + ClassicAssert.AreEqual(expectedPrecisionResult, matchResult.IsSearchPrecisionScoreMet(), $"Query:{queryString}{Environment.NewLine} " + $"Compare:{compareString}{Environment.NewLine}" + $"Raw Score: {matchResult.RawScore}{Environment.NewLine}" + @@ -277,7 +278,7 @@ public void WhenGivenAQuery_Scoring_ShouldGiveMoreWeightToStartOfNewWord( Debug.WriteLine(""); // Should - Assert.True(compareString1Result.Score > compareString2Result.Score, + ClassicAssert.True(compareString1Result.Score > compareString2Result.Score, $"Query: \"{queryString}\"{Environment.NewLine} " + $"CompareString1: \"{compareString1}\", Score: {compareString1Result.Score}{Environment.NewLine}" + $"Should be greater than{Environment.NewLine}" + @@ -310,7 +311,7 @@ public void WhenGivenTwoStrings_Scoring_ShouldGiveMoreWeightToTheStringCloserToI Debug.WriteLine(""); // Should - Assert.True(compareString1Result.Score > compareString2Result.Score, + ClassicAssert.True(compareString1Result.Score > compareString2Result.Score, $"Query: \"{queryString}\"{Environment.NewLine} " + $"CompareString1: \"{compareString1}\", Score: {compareString1Result.Score}{Environment.NewLine}" + $"Should be greater than{Environment.NewLine}" + @@ -335,8 +336,8 @@ public void WhenMultipleResults_ExactMatchingResult_ShouldHaveGreatestScore( var firstScore = new[] {firstNameMatch, firstDescriptionMatch, firstExecutableNameMatch}.Max(); var secondScore = new[] {secondNameMatch, secondDescriptionMatch, secondExecutableNameMatch}.Max(); - // Assert - Assert.IsTrue(firstScore > secondScore, + // ClassicAssert + ClassicAssert.IsTrue(firstScore > secondScore, $"Query: \"{queryString}\"{Environment.NewLine} " + $"Name of first: \"{firstName}\", Final Score: {firstScore}{Environment.NewLine}" + $"Should be greater than{Environment.NewLine}" + @@ -360,7 +361,7 @@ public void WhenGivenAnAcronymQuery_ShouldReturnAcronymScore(string queryString, { var matcher = new StringMatcher(); var score = matcher.FuzzyMatch(queryString, compareString).Score; - Assert.IsTrue(score == desiredScore, + ClassicAssert.IsTrue(score == desiredScore, $@"Query: ""{queryString}"" CompareString: ""{compareString}"" Score: {score} diff --git a/Flow.Launcher.Test/HttpTest.cs b/Flow.Launcher.Test/HttpTest.cs index e72ad7a6761..27c939634bd 100644 --- a/Flow.Launcher.Test/HttpTest.cs +++ b/Flow.Launcher.Test/HttpTest.cs @@ -2,6 +2,7 @@ using System; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Infrastructure.Http; +using NUnit.Framework.Legacy; namespace Flow.Launcher.Test { @@ -16,16 +17,16 @@ public void GivenHttpProxy_WhenUpdated_ThenWebProxyShouldAlsoBeUpdatedToTheSame( proxy.Enabled = true; proxy.Server = "127.0.0.1"; - Assert.AreEqual(Http.WebProxy.Address, new Uri($"http://{proxy.Server}:{proxy.Port}")); - Assert.IsNull(Http.WebProxy.Credentials); + ClassicAssert.AreEqual(Http.WebProxy.Address, new Uri($"http://{proxy.Server}:{proxy.Port}")); + ClassicAssert.IsNull(Http.WebProxy.Credentials); proxy.UserName = "test"; - Assert.NotNull(Http.WebProxy.Credentials); - Assert.AreEqual(Http.WebProxy.Credentials.GetCredential(Http.WebProxy.Address, "Basic").UserName, proxy.UserName); - Assert.AreEqual(Http.WebProxy.Credentials.GetCredential(Http.WebProxy.Address, "Basic").Password, ""); + ClassicAssert.NotNull(Http.WebProxy.Credentials); + ClassicAssert.AreEqual(Http.WebProxy.Credentials.GetCredential(Http.WebProxy.Address, "Basic").UserName, proxy.UserName); + ClassicAssert.AreEqual(Http.WebProxy.Credentials.GetCredential(Http.WebProxy.Address, "Basic").Password, ""); proxy.Password = "test password"; - Assert.AreEqual(Http.WebProxy.Credentials.GetCredential(Http.WebProxy.Address, "Basic").Password, proxy.Password); + ClassicAssert.AreEqual(Http.WebProxy.Credentials.GetCredential(Http.WebProxy.Address, "Basic").Password, proxy.Password); } } } diff --git a/Flow.Launcher.Test/PluginLoadTest.cs b/Flow.Launcher.Test/PluginLoadTest.cs index d6ba48f1905..65700ee362c 100644 --- a/Flow.Launcher.Test/PluginLoadTest.cs +++ b/Flow.Launcher.Test/PluginLoadTest.cs @@ -3,6 +3,7 @@ using Flow.Launcher.Plugin; using System.Collections.Generic; using System.Linq; +using NUnit.Framework.Legacy; namespace Flow.Launcher.Test { @@ -56,11 +57,11 @@ public void GivenDuplicatePluginMetadatasWhenLoadedThenShouldReturnOnlyUniqueLis (var unique, var duplicates) = PluginConfig.GetUniqueLatestPluginMetadata(duplicateList); // Then - Assert.True(unique.FirstOrDefault().ID == "CEA0TYUC6D3B4085823D60DC76F28855" && unique.FirstOrDefault().Version == "1.0.2"); - Assert.True(unique.Count() == 1); + ClassicAssert.True(unique.FirstOrDefault().ID == "CEA0TYUC6D3B4085823D60DC76F28855" && unique.FirstOrDefault().Version == "1.0.2"); + ClassicAssert.True(unique.Count() == 1); - Assert.False(duplicates.Any(x => x.Version == "1.0.2" && x.ID == "CEA0TYUC6D3B4085823D60DC76F28855")); - Assert.True(duplicates.Count() == 6); + ClassicAssert.False(duplicates.Any(x => x.Version == "1.0.2" && x.ID == "CEA0TYUC6D3B4085823D60DC76F28855")); + ClassicAssert.True(duplicates.Count() == 6); } [Test] @@ -85,8 +86,8 @@ public void GivenDuplicatePluginMetadatasWithNoUniquePluginWhenLoadedThenShouldR (var unique, var duplicates) = PluginConfig.GetUniqueLatestPluginMetadata(duplicateList); // Then - Assert.True(unique.Count() == 0); - Assert.True(duplicates.Count() == 2); + ClassicAssert.True(unique.Count() == 0); + ClassicAssert.True(duplicates.Count() == 2); } } } diff --git a/Flow.Launcher.Test/Plugins/ExplorerTest.cs b/Flow.Launcher.Test/Plugins/ExplorerTest.cs index e9d37433f4e..ead4a25cf68 100644 --- a/Flow.Launcher.Test/Plugins/ExplorerTest.cs +++ b/Flow.Launcher.Test/Plugins/ExplorerTest.cs @@ -11,6 +11,7 @@ using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; +using NUnit.Framework.Legacy; using static Flow.Launcher.Plugin.Explorer.Search.SearchManager; namespace Flow.Launcher.Test.Plugins @@ -57,7 +58,7 @@ public void GivenWindowsIndexSearch_WhenProvidedFolderPath_ThenQueryWhereRestric var result = QueryConstructor.TopLevelDirectoryConstraint(folderPath); // Then - Assert.IsTrue(result == expectedString, + ClassicAssert.IsTrue(result == expectedString, $"Expected QueryWhereRestrictions string: {expectedString}{Environment.NewLine} " + $"Actual: {result}{Environment.NewLine}"); } @@ -74,7 +75,7 @@ public void GivenWindowsIndexSearch_WhenSearchTypeIsTopLevelDirectorySearch_Then var queryString = queryConstructor.Directory(folderPath); // Then - Assert.IsTrue(queryString.Replace(" ", " ") == expectedString.Replace(" ", " "), + ClassicAssert.IsTrue(queryString.Replace(" ", " ") == expectedString.Replace(" ", " "), $"Expected string: {expectedString}{Environment.NewLine} " + $"Actual string was: {queryString}{Environment.NewLine}"); } @@ -94,7 +95,7 @@ public void GivenWindowsIndexSearchTopLevelDirectory_WhenSearchingForSpecificIte var queryString = queryConstructor.Directory(folderPath, userSearchString); // Then - Assert.AreEqual(expectedString, queryString); + ClassicAssert.AreEqual(expectedString, queryString); } [SupportedOSPlatform("windows7.0")] @@ -105,7 +106,7 @@ public void GivenWindowsIndexSearch_WhenSearchAllFoldersAndFiles_ThenQueryWhereR const string resultString = QueryConstructor.RestrictionsForAllFilesAndFoldersSearch; // Then - Assert.AreEqual(expectedString, resultString); + ClassicAssert.AreEqual(expectedString, resultString); } [SupportedOSPlatform("windows7.0")] @@ -128,7 +129,7 @@ public void GivenWindowsIndexSearch_WhenSearchAllFoldersAndFiles_ThenQueryShould var resultString = queryConstructor.FilesAndFolders(userSearchString); // Then - Assert.AreEqual(expectedString, resultString); + ClassicAssert.AreEqual(expectedString, resultString); } @@ -144,7 +145,7 @@ public void GivenWindowsIndexSearch_WhenQueryWhereRestrictionsIsForFileContentSe var resultString = QueryConstructor.RestrictionsForFileContentSearch(querySearchString); // Then - Assert.IsTrue(resultString == expectedString, + ClassicAssert.IsTrue(resultString == expectedString, $"Expected QueryWhereRestrictions string: {expectedString}{Environment.NewLine} " + $"Actual string was: {resultString}{Environment.NewLine}"); } @@ -162,7 +163,7 @@ public void GivenWindowsIndexSearch_WhenSearchForFileContent_ThenQueryShouldUseE var resultString = queryConstructor.FileContent(userSearchString); // Then - Assert.IsTrue(resultString == expectedString, + ClassicAssert.IsTrue(resultString == expectedString, $"Expected query string: {expectedString}{Environment.NewLine} " + $"Actual string was: {resultString}{Environment.NewLine}"); } @@ -181,7 +182,7 @@ public void GivenQuery_WhenActionKeywordForFileContentSearchExists_ThenFileConte var result = searchManager.IsFileContentSearch(query.ActionKeyword); // Then - Assert.IsTrue(result, + ClassicAssert.IsTrue(result, $"Expected True for file content search. {Environment.NewLine} " + $"Actual result was: {result}{Environment.NewLine}"); } @@ -202,7 +203,7 @@ public void WhenGivenQuerySearchString_ThenShouldIndicateIfIsLocationPathString( var result = FilesFolders.IsLocationPathString(querySearchString); //Then - Assert.IsTrue(result == expectedResult, + ClassicAssert.IsTrue(result == expectedResult, $"Expected query search string check result is: {expectedResult} {Environment.NewLine} " + $"Actual check result is {result} {Environment.NewLine}"); @@ -229,7 +230,7 @@ public void GivenAPartialPath_WhenPreviousLevelDirectoryExists_ThenShouldReturnT var previousDirectoryPath = FilesFolders.GetPreviousExistingDirectory(previousLocationExists, path); //Then - Assert.IsTrue(previousDirectoryPath == expectedString, + ClassicAssert.IsTrue(previousDirectoryPath == expectedString, $"Expected path string: {expectedString} {Environment.NewLine} " + $"Actual path string is {previousDirectoryPath} {Environment.NewLine}"); } @@ -242,7 +243,7 @@ public void WhenGivenAPath_ThenShouldReturnThePreviousDirectoryPathIfIncompleteO var returnedPath = FilesFolders.ReturnPreviousDirectoryIfIncompleteString(path); //Then - Assert.IsTrue(returnedPath == expectedString, + ClassicAssert.IsTrue(returnedPath == expectedString, $"Expected path string: {expectedString} {Environment.NewLine} " + $"Actual path string is {returnedPath} {Environment.NewLine}"); } @@ -256,7 +257,7 @@ public void GivenFilePath_WhenSearchPatternHotKeyIsSearchAll_ThenQueryWhereRestr var resultString = QueryConstructor.RecursiveDirectoryConstraint(path); // Then - Assert.AreEqual(expectedString, resultString); + ClassicAssert.AreEqual(expectedString, resultString); } [SupportedOSPlatform("windows7.0")] @@ -270,7 +271,7 @@ public void GivenDirectoryInfoSearch_WhenSearchPatternHotKeyIsSearchAll_ThenSear var resultString = DirectoryInfoSearch.ConstructSearchCriteria(path); // Then - Assert.AreEqual(expectedString, resultString); + ClassicAssert.AreEqual(expectedString, resultString); } [TestCase("c:\\somefolder\\someotherfolder", ResultType.Folder, "irrelevant", false, true, "c:\\somefolder\\someotherfolder\\")] @@ -301,7 +302,7 @@ public void GivenFolderResult_WhenGetPath_ThenPathShouldBeExpectedString( var result = ResultManager.GetPathWithActionKeyword(path, type, actionKeyword); // Then - Assert.AreEqual(result, expectedResult); + ClassicAssert.AreEqual(result, expectedResult); } [TestCase("c:\\somefolder\\somefile", ResultType.File, "irrelevant", false, true, "e c:\\somefolder\\somefile")] @@ -330,7 +331,7 @@ public void GivenFileResult_WhenGetPath_ThenPathShouldBeExpectedString( var result = ResultManager.GetPathWithActionKeyword(path, type, actionKeyword); // Then - Assert.AreEqual(result, expectedResult); + ClassicAssert.AreEqual(result, expectedResult); } [TestCase("somefolder", "c:\\somefolder\\", ResultType.Folder, "q", false, false, "q somefolder")] @@ -362,7 +363,7 @@ public void GivenQueryWithFolderTypeResult_WhenGetAutoComplete_ThenResultShouldB var result = ResultManager.GetAutoCompleteText(title, query, path, resultType); // Then - Assert.AreEqual(result, expectedResult); + ClassicAssert.AreEqual(result, expectedResult); } [TestCase("somefile", "c:\\somefolder\\somefile", ResultType.File, "q", false, false, "q somefile")] @@ -394,7 +395,7 @@ public void GivenQueryWithFileTypeResult_WhenGetAutoComplete_ThenResultShouldBeE var result = ResultManager.GetAutoCompleteText(title, query, path, resultType); // Then - Assert.AreEqual(result, expectedResult); + ClassicAssert.AreEqual(result, expectedResult); } [TestCase(@"c:\foo", @"c:\foo", true)] @@ -416,7 +417,7 @@ public void GivenTwoPaths_WhenCompared_ThenShouldBeExpectedSameOrDifferent(strin }; // When, Then - Assert.AreEqual(expectedResult, comparator.Equals(result1, result2)); + ClassicAssert.AreEqual(expectedResult, comparator.Equals(result1, result2)); } [TestCase(@"c:\foo\", @"c:\foo\")] @@ -440,7 +441,7 @@ public void GivenTwoPaths_WhenComparedHasCode_ThenShouldBeSame(string path1, str var hash2 = comparator.GetHashCode(result2); // When, Then - Assert.IsTrue(hash1 == hash2); + ClassicAssert.IsTrue(hash1 == hash2); } [TestCase(@"%appdata%", true)] @@ -457,7 +458,7 @@ public void GivenPath_WhenHavingEnvironmentVariableOrNot_ThenShouldBeExpected(st var result = EnvironmentVariables.HasEnvironmentVar(path); // Then - Assert.AreEqual(result, expectedResult); + ClassicAssert.AreEqual(result, expectedResult); } } } diff --git a/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs b/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs index 3d05e56796f..3a4952d7567 100644 --- a/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs +++ b/Flow.Launcher.Test/Plugins/JsonRPCPluginTest.cs @@ -29,62 +29,62 @@ protected override Task RequestAsync(JsonRPCRequestModel request, Cancel } [TestCase("{\"result\":[],\"DebugMessage\":null}", Description = "Empty Result")] - [TestCase("{\"result\":[{\"JsonRPCAction\":null,\"Title\":\"something\",\"SubTitle\":\"\",\"ActionKeywordAssigned\":null,\"IcoPath\":null}],\"DebugMessage\":null}", Description = "One Result with Pascal Case")] - [TestCase("{\"result\":[{\"jsonRPCAction\":null,\"title\":\"something\",\"subTitle\":\"\",\"actionKeywordAssigned\":null,\"icoPath\":null}],\"debugMessage\":null}", Description = "One Result with camel Case")] - [TestCase("{\"result\":[{\"JsonRPCAction\":null,\"Title\":\"iii\",\"SubTitle\":\"\",\"ActionKeywordAssigned\":null,\"IcoPath\":null},{\"JsonRPCAction\":null,\"Title\":\"iii\",\"SubTitle\":\"\",\"ActionKeywordAssigned\":null,\"IcoPath\":null}],\"DebugMessage\":null}", Description = "Two Result with Pascal Case")] - [TestCase("{\"result\":[{\"jsonrpcAction\":null,\"TItLE\":\"iii\",\"Subtitle\":\"\",\"Actionkeywordassigned\":null,\"icoPath\":null},{\"jsonRPCAction\":null,\"tiTle\":\"iii\",\"subTitle\":\"\",\"ActionKeywordAssigned\":null,\"IcoPath\":null}],\"DebugMessage\":null}", Description = "Two Result with Weird Case")] + [TestCase( + "{\"result\":[{\"JsonRPCAction\":null,\"Title\":\"something\",\"SubTitle\":\"\",\"ActionKeywordAssigned\":null,\"IcoPath\":null}],\"DebugMessage\":null}", + Description = "One Result with Pascal Case")] + [TestCase( + "{\"result\":[{\"jsonRPCAction\":null,\"title\":\"something\",\"subTitle\":\"\",\"actionKeywordAssigned\":null,\"icoPath\":null}],\"debugMessage\":null}", + Description = "One Result with camel Case")] + [TestCase( + "{\"result\":[{\"JsonRPCAction\":null,\"Title\":\"iii\",\"SubTitle\":\"\",\"ActionKeywordAssigned\":null,\"IcoPath\":null},{\"JsonRPCAction\":null,\"Title\":\"iii\",\"SubTitle\":\"\",\"ActionKeywordAssigned\":null,\"IcoPath\":null}],\"DebugMessage\":null}", + Description = "Two Result with Pascal Case")] + [TestCase( + "{\"result\":[{\"jsonrpcAction\":null,\"TItLE\":\"iii\",\"Subtitle\":\"\",\"Actionkeywordassigned\":null,\"icoPath\":null},{\"jsonRPCAction\":null,\"tiTle\":\"iii\",\"subTitle\":\"\",\"ActionKeywordAssigned\":null,\"IcoPath\":null}],\"DebugMessage\":null}", + Description = "Two Result with Weird Case")] public async Task GivenVariousJsonText_WhenVariousNamingCase_ThenExpectNotNullResults_Async(string resultText) { - var results = await QueryAsync(new Query - { - Search = resultText - }, default); + var results = await QueryAsync(new Query { Search = resultText }, default); - Assert.IsNotNull(results); + Assert.That(results, Is.Not.Null); foreach (var result in results) { - Assert.IsNotNull(result); - Assert.IsNotNull(result.AsyncAction); - Assert.IsNotNull(result.Title); + Assert.That(result, Is.Not.Null); + Assert.That(result.AsyncAction, Is.Not.Null); + Assert.That(result.Title, Is.Not.Null); } - } public static List ResponseModelsSource = new() { new JsonRPCQueryResponseModel(0, new List()), - new JsonRPCQueryResponseModel(0, new List - { - new JsonRPCResult - { - Title = "Test1", SubTitle = "Test2" - } - }) + new JsonRPCQueryResponseModel(0, + new List { new JsonRPCResult { Title = "Test1", SubTitle = "Test2" } }) }; [TestCaseSource(typeof(JsonRPCPluginTest), nameof(ResponseModelsSource))] - public async Task GivenModel_WhenSerializeWithDifferentNamingPolicy_ThenExpectSameResult_Async(JsonRPCQueryResponseModel reference) + public async Task GivenModel_WhenSerializeWithDifferentNamingPolicy_ThenExpectSameResult_Async( + JsonRPCQueryResponseModel reference) { - var camelText = JsonSerializer.Serialize(reference, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); + var camelText = JsonSerializer.Serialize(reference, + new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); var pascalText = JsonSerializer.Serialize(reference); var results1 = await QueryAsync(new Query { Search = camelText }, default); var results2 = await QueryAsync(new Query { Search = pascalText }, default); - Assert.IsNotNull(results1); - Assert.IsNotNull(results2); + Assert.That(results1, Is.Not.Null); + Assert.That(results2, Is.Not.Null); foreach (var ((result1, result2), referenceResult) in results1.Zip(results2).Zip(reference.Result)) { - Assert.AreEqual(result1, result2); - Assert.AreEqual(result1, referenceResult); + Assert.That(result1, Is.EqualTo(result2)); + Assert.That(result1, Is.EqualTo(referenceResult)); - Assert.IsNotNull(result1); - Assert.IsNotNull(result1.AsyncAction); + Assert.That(result1, Is.Not.Null); + Assert.That(result1.AsyncAction, Is.Not.Null); } } - } } diff --git a/Flow.Launcher.Test/Plugins/UrlPluginTest.cs b/Flow.Launcher.Test/Plugins/UrlPluginTest.cs index 7ccac5bd59d..5cd75d16044 100644 --- a/Flow.Launcher.Test/Plugins/UrlPluginTest.cs +++ b/Flow.Launcher.Test/Plugins/UrlPluginTest.cs @@ -10,23 +10,23 @@ public class UrlPluginTest public void URLMatchTest() { var plugin = new Main(); - Assert.IsTrue(plugin.IsURL("http://www.google.com")); - Assert.IsTrue(plugin.IsURL("https://www.google.com")); - Assert.IsTrue(plugin.IsURL("http://google.com")); - Assert.IsTrue(plugin.IsURL("www.google.com")); - Assert.IsTrue(plugin.IsURL("google.com")); - Assert.IsTrue(plugin.IsURL("http://localhost")); - Assert.IsTrue(plugin.IsURL("https://localhost")); - Assert.IsTrue(plugin.IsURL("http://localhost:80")); - Assert.IsTrue(plugin.IsURL("https://localhost:80")); - Assert.IsTrue(plugin.IsURL("http://110.10.10.10")); - Assert.IsTrue(plugin.IsURL("110.10.10.10")); - Assert.IsTrue(plugin.IsURL("ftp://110.10.10.10")); + Assert.That(plugin.IsURL("http://www.google.com"), Is.True); + Assert.That(plugin.IsURL("https://www.google.com"), Is.True); + Assert.That(plugin.IsURL("http://google.com"), Is.True); + Assert.That(plugin.IsURL("www.google.com"), Is.True); + Assert.That(plugin.IsURL("google.com"), Is.True); + Assert.That(plugin.IsURL("http://localhost"), Is.True); + Assert.That(plugin.IsURL("https://localhost"), Is.True); + Assert.That(plugin.IsURL("http://localhost:80"), Is.True); + Assert.That(plugin.IsURL("https://localhost:80"), Is.True); + Assert.That(plugin.IsURL("http://110.10.10.10"), Is.True); + Assert.That(plugin.IsURL("110.10.10.10"), Is.True); + Assert.That(plugin.IsURL("ftp://110.10.10.10"), Is.True); - Assert.IsFalse(plugin.IsURL("wwww")); - Assert.IsFalse(plugin.IsURL("wwww.c")); - Assert.IsFalse(plugin.IsURL("wwww.c")); + Assert.That(plugin.IsURL("wwww"), Is.False); + Assert.That(plugin.IsURL("wwww.c"), Is.False); + Assert.That(plugin.IsURL("wwww.c"), Is.False); } } } diff --git a/Flow.Launcher.Test/QueryBuilderTest.cs b/Flow.Launcher.Test/QueryBuilderTest.cs index aa0c8da12b9..d4808a4c5a5 100644 --- a/Flow.Launcher.Test/QueryBuilderTest.cs +++ b/Flow.Launcher.Test/QueryBuilderTest.cs @@ -2,6 +2,7 @@ using NUnit.Framework; using Flow.Launcher.Core.Plugin; using Flow.Launcher.Plugin; +using NUnit.Framework.Legacy; namespace Flow.Launcher.Test { @@ -17,17 +18,17 @@ public void ExclusivePluginQueryTest() Query q = QueryBuilder.Build("> ping google.com -n 20 -6", nonGlobalPlugins); - Assert.AreEqual("> ping google.com -n 20 -6", q.RawQuery); - Assert.AreEqual("ping google.com -n 20 -6", q.Search, "Search should not start with the ActionKeyword."); - Assert.AreEqual(">", q.ActionKeyword); + ClassicAssert.AreEqual("> ping google.com -n 20 -6", q.RawQuery); + ClassicAssert.AreEqual("ping google.com -n 20 -6", q.Search, "Search should not start with the ActionKeyword."); + ClassicAssert.AreEqual(">", q.ActionKeyword); - Assert.AreEqual(5, q.SearchTerms.Length, "The length of SearchTerms should match."); + ClassicAssert.AreEqual(5, q.SearchTerms.Length, "The length of SearchTerms should match."); - Assert.AreEqual("ping", q.FirstSearch); - Assert.AreEqual("google.com", q.SecondSearch); - Assert.AreEqual("-n", q.ThirdSearch); + ClassicAssert.AreEqual("ping", q.FirstSearch); + ClassicAssert.AreEqual("google.com", q.SecondSearch); + ClassicAssert.AreEqual("-n", q.ThirdSearch); - Assert.AreEqual("google.com -n 20 -6", q.SecondToEndSearch, "SecondToEndSearch should be trimmed of multiple whitespace characters"); + ClassicAssert.AreEqual("google.com -n 20 -6", q.SecondToEndSearch, "SecondToEndSearch should be trimmed of multiple whitespace characters"); } [Test] @@ -40,11 +41,11 @@ public void ExclusivePluginQueryIgnoreDisabledTest() Query q = QueryBuilder.Build("> ping google.com -n 20 -6", nonGlobalPlugins); - Assert.AreEqual("> ping google.com -n 20 -6", q.Search); - Assert.AreEqual(q.Search, q.RawQuery, "RawQuery should be equal to Search."); - Assert.AreEqual(6, q.SearchTerms.Length, "The length of SearchTerms should match."); - Assert.AreNotEqual(">", q.ActionKeyword, "ActionKeyword should not match that of a disabled plugin."); - Assert.AreEqual("ping google.com -n 20 -6", q.SecondToEndSearch, "SecondToEndSearch should be trimmed of multiple whitespace characters"); + ClassicAssert.AreEqual("> ping google.com -n 20 -6", q.Search); + ClassicAssert.AreEqual(q.Search, q.RawQuery, "RawQuery should be equal to Search."); + ClassicAssert.AreEqual(6, q.SearchTerms.Length, "The length of SearchTerms should match."); + ClassicAssert.AreNotEqual(">", q.ActionKeyword, "ActionKeyword should not match that of a disabled plugin."); + ClassicAssert.AreEqual("ping google.com -n 20 -6", q.SecondToEndSearch, "SecondToEndSearch should be trimmed of multiple whitespace characters"); } [Test] @@ -52,13 +53,13 @@ public void GenericPluginQueryTest() { Query q = QueryBuilder.Build("file.txt file2 file3", new Dictionary()); - Assert.AreEqual("file.txt file2 file3", q.Search); - Assert.AreEqual("", q.ActionKeyword); + ClassicAssert.AreEqual("file.txt file2 file3", q.Search); + ClassicAssert.AreEqual("", q.ActionKeyword); - Assert.AreEqual("file.txt", q.FirstSearch); - Assert.AreEqual("file2", q.SecondSearch); - Assert.AreEqual("file3", q.ThirdSearch); - Assert.AreEqual("file2 file3", q.SecondToEndSearch); + ClassicAssert.AreEqual("file.txt", q.FirstSearch); + ClassicAssert.AreEqual("file2", q.SecondSearch); + ClassicAssert.AreEqual("file3", q.ThirdSearch); + ClassicAssert.AreEqual("file2 file3", q.SecondToEndSearch); } } } From cffb5bc82dd867f84aaec04fe0757d7eb65a9af1 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 15:17:33 -0500 Subject: [PATCH 23/75] cache after checkout --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d13088bf33a..a1dc21769a1 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -34,6 +34,7 @@ jobs: run: | echo "Adding GNU tar to PATH" echo C:\Program Files\Git\usr\bin>>"%GITHUB_PATH%" + - uses: actions/checkout@v4 - uses: actions/cache@v4 with: path: | @@ -42,7 +43,6 @@ jobs: key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }} restore-keys: | ${{ runner.os }}-nuget- - - uses: actions/checkout@v4 - name: Setup .NET uses: actions/setup-dotnet@v4 with: From b24b035d89561a1d82d534c2e25af82a49f006a6 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 15:28:34 -0500 Subject: [PATCH 24/75] revise cache --- .github/workflows/dotnet.yml | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index a1dc21769a1..9dac8155564 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -27,22 +27,15 @@ jobs: - name: Set version in all AssemblyInfo.cs files uses: secondbounce/assemblyinfo-update@v2 with: - version: '1.9.5' - - if: ${{ runner.os == 'Windows' }} - name: Use GNU tar - shell: cmd - run: | - echo "Adding GNU tar to PATH" - echo C:\Program Files\Git\usr\bin>>"%GITHUB_PATH%" + version: '1.17.2' - uses: actions/checkout@v4 - uses: actions/cache@v4 with: path: | ~/.nuget/packages - !~/.nuget/packages/microsoft.netcore.app.* key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }} restore-keys: | - ${{ runner.os }}-nuget- + ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }} - name: Setup .NET uses: actions/setup-dotnet@v4 with: @@ -77,7 +70,7 @@ jobs: with: name: Portable Version path: | - Releases\FlowLauncher-Portable.zip + Releases\FlowLauncher-*-Portable.zip compression-level: 0 - name: Upload Full Nupkg uses: actions/upload-artifact@v4 @@ -92,6 +85,6 @@ jobs: with: name: RELEASES path: | - Releases\RELEASES + Releases\RELEASES* compression-level: 0 From 943a9fd9822dc37b9bde4eb717fb5b73e3791e3c Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 16:00:41 -0500 Subject: [PATCH 25/75] try to cache vpk --- .github/workflows/dotnet.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 9dac8155564..32cd8e2d8ef 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -30,12 +30,21 @@ jobs: version: '1.17.2' - uses: actions/checkout@v4 - uses: actions/cache@v4 + name: Restore Nuget Cache with: path: | ~/.nuget/packages key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }} restore-keys: | - ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }} + ${{ runner.os }}-nuget + - uses: actions/cache@v4 + name: Restore dotnet tool Cache + with: + path: | + ~/.dotnet/tools + key: ${{ runner.os }}-dotnet-tools-${{ hashFiles('~/.dotnet/tools/**') }} + restore-keys: | + ${{ runner.os }}-dotnet-tools - name: Setup .NET uses: actions/setup-dotnet@v4 with: From bdad186f081c5409d29c95639c78a3c7d69b0105 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 17:30:33 -0500 Subject: [PATCH 26/75] empty From 8c19ed7732e9217b7841081dadfaee91d43a138b Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 17:38:29 -0500 Subject: [PATCH 27/75] revising remove duplicate --- .github/workflows/dotnet.yml | 4 +++- Scripts/post_build.ps1 | 34 +++++++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 32cd8e2d8ef..03597cbeb5c 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -50,7 +50,9 @@ jobs: with: dotnet-version: 7.0.x - name: Install vpk - run: dotnet tool update -g vpk + # Install vpk tool (dotnet tool install will not reinstall if already installed) + # We will update the cli by removing cache + run: dotnet tool install -g vpk - name: Restore dependencies run: dotnet restore - name: Build diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index 836fdfb8917..a3e202ce5e1 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -49,11 +49,39 @@ function Delete-Unused($path, $config) { $target = "$path\Output\$config" $included = Get-ChildItem $target -Filter "*.dll" + + $hashset = @{ } + foreach ($i in $included) { - $deleteList = Get-ChildItem $target\Plugins -Include $i -Recurse | Where { $_.VersionInfo.FileVersion -eq $i.VersionInfo.FileVersion -And $_.Name -eq "$i" } - $deleteList | ForEach-Object{ Write-Host Deleting duplicated $_.Name with version $_.VersionInfo.FileVersion at location $_.Directory.FullName } - $deleteList | Remove-Item + $item = if ($i.VersionInfo.FileVersion -eq $null) + { + [ValueTuple]::Create($i.Name, "") + } + else + { + [ValueTuple]::Create($i.Name, $i.VersionInfo.FileVersion) + } + + $key = $hashset.Add($item, $true) + } + + $deleteList = Get-ChildItem $target\Plugins -Filter *.dll -Recurse | Where { + $item = if ($_.VersionInfo.FileVersion -eq $null) + { + [ValueTuple]::Create($_.Name, "") + } + else + { + [ValueTuple]::Create($_.Name, $_.VersionInfo.FileVersion) + } + $hashset.ContainsKey($item) + } + + foreach ($i in $deleteList) + { + Write-Host "Deleting duplicated $i.Name with version $i.VersionInfo.FileVersion at location $i.Directory.FullName" + Remove-Item $i } Remove-Item -Path $target -Include "*.xml" -Recurse } From 2eb647485368eae4a13502d32792b4352a844e22 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 17:42:20 -0500 Subject: [PATCH 28/75] try not install vpk --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 03597cbeb5c..b5ba119c4e6 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -49,10 +49,10 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: 7.0.x - - name: Install vpk +# - name: Install vpk # Install vpk tool (dotnet tool install will not reinstall if already installed) # We will update the cli by removing cache - run: dotnet tool install -g vpk +# run: dotnet tool install -g vpk - name: Restore dependencies run: dotnet restore - name: Build From 4337c607ee03e1e6811b6dc05aab5b11b37e6f7a Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 17:45:46 -0500 Subject: [PATCH 29/75] install only if cache not exists --- Scripts/post_build.ps1 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index a3e202ce5e1..cdc1b398d24 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -111,6 +111,13 @@ function Pack-Velopack-Installer($path, $version, $output) $repoUrl = "https://github.com/Flow-Launcher/Flow.Launcher" } + Set-Alias vpk "~/.dotnet/tools/vpk.exe" + + if (!(Get-Command vpk -ErrorAction SilentlyContinue)) + { + dotnet tool install --global vpk + } + vpk pack --packVersion $version --packDir $input --packId FlowLauncher --mainExe Flow.Launcher.exe --channel $channel } From 067f69b4945f3abb8e1c15316806b66bb26b0f34 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 17:48:41 -0500 Subject: [PATCH 30/75] set assemblyinfo after checkout --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b5ba119c4e6..44dbb3522ba 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -24,11 +24,11 @@ jobs: run: | sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest net start WSearch + - uses: actions/checkout@v4 - name: Set version in all AssemblyInfo.cs files uses: secondbounce/assemblyinfo-update@v2 with: version: '1.17.2' - - uses: actions/checkout@v4 - uses: actions/cache@v4 name: Restore Nuget Cache with: From 286f49c3a32a152dbe75650801b4cc647c6fcd53 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 17:57:03 -0500 Subject: [PATCH 31/75] fix assembly version --- .github/workflows/dotnet.yml | 9 ++++++--- Scripts/post_build.ps1 | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 44dbb3522ba..38923452c39 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -25,10 +25,13 @@ jobs: sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest net start WSearch - uses: actions/checkout@v4 - - name: Set version in all AssemblyInfo.cs files - uses: secondbounce/assemblyinfo-update@v2 + - name: Set MyProject.csproj version + id: update + uses: vers-one/dotnet-project-version-updater@v1.5 with: - version: '1.17.2' + file: | + "Flow.Launcher/**/*.csproj", "Flow.Launcher/**/*.nuspec", "Flow.Launcher/**/AssemblyInfo.cs" + version: "1.17.2" - uses: actions/cache@v4 name: Restore Nuget Cache with: diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index cdc1b398d24..535560b0127 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -80,7 +80,7 @@ function Delete-Unused($path, $config) foreach ($i in $deleteList) { - Write-Host "Deleting duplicated $i.Name with version $i.VersionInfo.FileVersion at location $i.Directory.FullName" + write Deleting duplicated $i.Name with version $i.VersionInfo.FileVersion at location $i.Directory.FullName Remove-Item $i } Remove-Item -Path $target -Include "*.xml" -Recurse From 7df7ac083fd7ac7315d44340887a511c7fa866a3 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 17:58:48 -0500 Subject: [PATCH 32/75] revise version --- .github/workflows/dotnet.yml | 10 +++++----- Flow.Launcher.Core/Properties/AssemblyInfo.cs | 4 +++- Flow.Launcher/Flow.Launcher.csproj | 1 + 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 38923452c39..4b63102840a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -20,12 +20,8 @@ jobs: runs-on: windows-latest steps: - - name: Initialize Service - run: | - sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest - net start WSearch - uses: actions/checkout@v4 - - name: Set MyProject.csproj version + - name: Set Flow.Launcher.csproj version id: update uses: vers-one/dotnet-project-version-updater@v1.5 with: @@ -60,6 +56,10 @@ jobs: run: dotnet restore - name: Build run: dotnet build --no-restore -c Release + - name: Initialize Service + run: | + sc config WSearch start= auto # Starts Windows Search service- Needed for running ExplorerTest + net start WSearch - name: Test run: dotnet test --no-build --verbosity normal -c Release - name: Perform post_build tasks diff --git a/Flow.Launcher.Core/Properties/AssemblyInfo.cs b/Flow.Launcher.Core/Properties/AssemblyInfo.cs index ad60e2c9f53..4a55f96cdf3 100644 --- a/Flow.Launcher.Core/Properties/AssemblyInfo.cs +++ b/Flow.Launcher.Core/Properties/AssemblyInfo.cs @@ -1,3 +1,5 @@ -using System.Runtime.CompilerServices; +using System.Reflection; +using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Flow.Launcher.Test")] +[assembly: AssemblyVersion("1.0.0")] diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index 893d9515fdf..4049d5bbc52 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -4,6 +4,7 @@ WinExe net7.0-windows10.0.19041.0 true + 1.0.0 true Flow.Launcher.App Resources\app.ico From c6ca273e0ba37dd09401b3a04ad67e350e60439d Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 18:00:12 -0500 Subject: [PATCH 33/75] add version info to the main project --- Flow.Launcher.Core/Properties/AssemblyInfo.cs | 1 - Flow.Launcher/Properties/AssemblyInfo.cs | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Core/Properties/AssemblyInfo.cs b/Flow.Launcher.Core/Properties/AssemblyInfo.cs index 4a55f96cdf3..77c4fb79a46 100644 --- a/Flow.Launcher.Core/Properties/AssemblyInfo.cs +++ b/Flow.Launcher.Core/Properties/AssemblyInfo.cs @@ -2,4 +2,3 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Flow.Launcher.Test")] -[assembly: AssemblyVersion("1.0.0")] diff --git a/Flow.Launcher/Properties/AssemblyInfo.cs b/Flow.Launcher/Properties/AssemblyInfo.cs index 93ce37f2b5c..a2cf9f145e8 100644 --- a/Flow.Launcher/Properties/AssemblyInfo.cs +++ b/Flow.Launcher/Properties/AssemblyInfo.cs @@ -1,6 +1,9 @@ -using System.Windows; +using System.Reflection; +using System.Windows; [assembly: ThemeInfo( ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly )] +[assembly: AssemblyVersion("1.0.0")] +[assembly: AssemblyFileVersion("1.0.0")] From 41ad35ab7db79538eec6b5bb10f5341e0f7c9787 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 18:10:17 -0500 Subject: [PATCH 34/75] revise assembly version --- .github/workflows/dotnet.yml | 2 +- Flow.Launcher/Properties/AssemblyInfo.cs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 4b63102840a..38703791562 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -26,7 +26,7 @@ jobs: uses: vers-one/dotnet-project-version-updater@v1.5 with: file: | - "Flow.Launcher/**/*.csproj", "Flow.Launcher/**/*.nuspec", "Flow.Launcher/**/AssemblyInfo.cs" + "**/SolutionAssemblyInfo.cs" version: "1.17.2" - uses: actions/cache@v4 name: Restore Nuget Cache diff --git a/Flow.Launcher/Properties/AssemblyInfo.cs b/Flow.Launcher/Properties/AssemblyInfo.cs index a2cf9f145e8..c2ee533d1ef 100644 --- a/Flow.Launcher/Properties/AssemblyInfo.cs +++ b/Flow.Launcher/Properties/AssemblyInfo.cs @@ -5,5 +5,3 @@ ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly )] -[assembly: AssemblyVersion("1.0.0")] -[assembly: AssemblyFileVersion("1.0.0")] From d3e91e01bee2690dd213c316203904f2ea7b2498 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 26 Mar 2024 18:15:04 -0500 Subject: [PATCH 35/75] fix log --- Scripts/post_build.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index 535560b0127..ee626a5a403 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -80,7 +80,7 @@ function Delete-Unused($path, $config) foreach ($i in $deleteList) { - write Deleting duplicated $i.Name with version $i.VersionInfo.FileVersion at location $i.Directory.FullName + write "Deleting duplicated $($i.Name) with version $($i.VersionInfo.FileVersion) at location $($i.Directory.FullName)" Remove-Item $i } Remove-Item -Path $target -Include "*.xml" -Recurse From d1f61bd195f0936c19315eab7fcf0ab4db81eb00 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 27 Mar 2024 00:19:16 -0500 Subject: [PATCH 36/75] try github run id --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 38703791562..c38a98fdb0a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -27,7 +27,7 @@ jobs: with: file: | "**/SolutionAssemblyInfo.cs" - version: "1.17.2" + version: 1.17.2.${{ github.run_id }} - uses: actions/cache@v4 name: Restore Nuget Cache with: From cb7fc2be47dfe439851ea7aa2280241246a53fcc Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 27 Mar 2024 00:24:31 -0500 Subject: [PATCH 37/75] use a different build number --- .github/workflows/dotnet.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index c38a98fdb0a..a7c9b8a021d 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -21,13 +21,18 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Generate build number + id: buildnumber + uses: onyxmueller/build-tag-number@v1 + with: + token: ${{secrets.github_token}} - name: Set Flow.Launcher.csproj version id: update uses: vers-one/dotnet-project-version-updater@v1.5 with: file: | "**/SolutionAssemblyInfo.cs" - version: 1.17.2.${{ github.run_id }} + version: 1.17.2.${{ steps.buildnumber.outputs.build_number }} - uses: actions/cache@v4 name: Restore Nuget Cache with: From 42c21a2815c346c70e34c22cb9f4bc44072ddef6 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 27 Mar 2024 00:30:17 -0500 Subject: [PATCH 38/75] use Sem2 versioning --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index a7c9b8a021d..4f32cb1b44d 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -32,7 +32,7 @@ jobs: with: file: | "**/SolutionAssemblyInfo.cs" - version: 1.17.2.${{ steps.buildnumber.outputs.build_number }} + version: 1.17.2-build.${{ steps.buildnumber.outputs.build_number }} - uses: actions/cache@v4 name: Restore Nuget Cache with: From 0c773b0266c7e2057c9e549c7659c7e4ff04dc3a Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 27 Mar 2024 00:46:14 -0500 Subject: [PATCH 39/75] revise versioning --- .github/workflows/dotnet.yml | 7 ++++--- Scripts/post_build.ps1 | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 4f32cb1b44d..0c6b80799e7 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -18,7 +18,8 @@ jobs: build: runs-on: windows-latest - + env: + FlowVersion: 1.17.2 steps: - uses: actions/checkout@v4 - name: Generate build number @@ -32,7 +33,7 @@ jobs: with: file: | "**/SolutionAssemblyInfo.cs" - version: 1.17.2-build.${{ steps.buildnumber.outputs.build_number }} + version: $FlowVersion-build.${{ steps.buildnumber.outputs.build_number }} - uses: actions/cache@v4 name: Restore Nuget Cache with: @@ -69,7 +70,7 @@ jobs: run: dotnet test --no-build --verbosity normal -c Release - name: Perform post_build tasks shell: pwsh - run: .\Scripts\post_build.ps1 + run: .\Scripts\post_build.ps1 -flowversion "$FlowVersion-build.${{ steps.buildnumber.outputs.build_number }}" - name: Upload Plugin Nupkg uses: actions/upload-artifact@v4 with: diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index ee626a5a403..aa3b73daa55 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -1,7 +1,8 @@ param( [string]$config = "Release", [string]$solution = (Join-Path $PSScriptRoot ".." -Resolve), - [string]$channel = "win-x64-prerelease" + [string]$channel = "win-x64-prerelease", + [string]$flowVersion = "" ) Write-Host "Config: $config" Write-Host "Solution: $solution" @@ -9,7 +10,7 @@ Write-Host "Channel: $channel" function Build-Version { - if ( [string]::IsNullOrEmpty($env:flowVersion)) + if ( [string]::IsNullOrEmpty($flowVersion)) { $targetPath = Join-Path $solution "Output/Release/Flow.Launcher.dll" -Resolve $v = (Get-Command ${targetPath}).FileVersionInfo.FileVersion From e31cde4a80537a26a5d87156a6e2ec7e936ea77f Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 27 Mar 2024 00:50:05 -0500 Subject: [PATCH 40/75] fix environmental variable usage --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 0c6b80799e7..c9126ef8e1a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -33,7 +33,7 @@ jobs: with: file: | "**/SolutionAssemblyInfo.cs" - version: $FlowVersion-build.${{ steps.buildnumber.outputs.build_number }} + version: ${env:FlowVersion}-build.${{ steps.buildnumber.outputs.build_number }} - uses: actions/cache@v4 name: Restore Nuget Cache with: @@ -70,7 +70,7 @@ jobs: run: dotnet test --no-build --verbosity normal -c Release - name: Perform post_build tasks shell: pwsh - run: .\Scripts\post_build.ps1 -flowversion "$FlowVersion-build.${{ steps.buildnumber.outputs.build_number }}" + run: .\Scripts\post_build.ps1 -flowversion "${env:FlowVersion}-build.${env:BUILD_NUMBER}" - name: Upload Plugin Nupkg uses: actions/upload-artifact@v4 with: From 5cb72bf2f96d0bf59dfa5128f34c836e55960218 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 27 Mar 2024 00:51:24 -0500 Subject: [PATCH 41/75] fix env variable (again) --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index c9126ef8e1a..60a821ec15c 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -33,7 +33,7 @@ jobs: with: file: | "**/SolutionAssemblyInfo.cs" - version: ${env:FlowVersion}-build.${{ steps.buildnumber.outputs.build_number }} + version: $FlowVersion.$BUILD_NUMBER - uses: actions/cache@v4 name: Restore Nuget Cache with: From 9f5f04ce8c28d21439a4a42cd8914fb19a84e20c Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 27 Mar 2024 00:53:30 -0500 Subject: [PATCH 42/75] fix again --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 60a821ec15c..d20d77a49b5 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -33,7 +33,7 @@ jobs: with: file: | "**/SolutionAssemblyInfo.cs" - version: $FlowVersion.$BUILD_NUMBER + version: ${{ $env.FlowVersion }}.${{ $env.BUILD_NUMBER }} - uses: actions/cache@v4 name: Restore Nuget Cache with: From d01313553108ee15d18b237292e839839eeea34b Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 27 Mar 2024 00:54:14 -0500 Subject: [PATCH 43/75] remove $ before env --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d20d77a49b5..0d0f069edbd 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -33,7 +33,7 @@ jobs: with: file: | "**/SolutionAssemblyInfo.cs" - version: ${{ $env.FlowVersion }}.${{ $env.BUILD_NUMBER }} + version: ${{ env.FlowVersion }}.${{ env.BUILD_NUMBER }} - uses: actions/cache@v4 name: Restore Nuget Cache with: From 742604cb97116b75793a7207efc05eab6517b866 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 27 Mar 2024 01:09:05 -0500 Subject: [PATCH 44/75] fix build script and no need to upload nupkg and release as artifact --- .github/workflows/dotnet.yml | 32 ++++++++++++++++---------------- Scripts/post_build.ps1 | 3 ++- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 0d0f069edbd..b481500c36a 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -92,19 +92,19 @@ jobs: path: | Releases\FlowLauncher-*-Portable.zip compression-level: 0 - - name: Upload Full Nupkg - uses: actions/upload-artifact@v4 - with: - name: Full nupkg - path: | - Releases\FlowLauncher-*-full.nupkg - - compression-level: 0 - - name: Upload Release Information - uses: actions/upload-artifact@v4 - with: - name: RELEASES - path: | - Releases\RELEASES* - compression-level: 0 - +# - name: Upload Full Nupkg +# uses: actions/upload-artifact@v4 +# with: +# name: Full nupkg +# path: | +# Releases\FlowLauncher-*-full.nupkg +# +# compression-level: 0 +# - name: Upload Release Information +# uses: actions/upload-artifact@v4 +# with: +# name: RELEASES +# path: | +# Releases\RELEASES* +# compression-level: 0 +# diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index aa3b73daa55..2633c24c5f9 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -6,6 +6,7 @@ param( ) Write-Host "Config: $config" Write-Host "Solution: $solution" +Write-Host "Flow Version: $flowVersion" Write-Host "Channel: $channel" function Build-Version @@ -17,7 +18,7 @@ function Build-Version } else { - $v = $env:flowVersion + $v = $flowVersion } Write-Host "Build Version: $v" From c563035cce0e46645e266a90bad1833990f9fcf6 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 27 Mar 2024 16:54:35 -0500 Subject: [PATCH 45/75] change the version being used and portable datafolder creation for non-standard installation --- Flow.Launcher.Core/Configuration/Portable.cs | 21 ++++++++++---------- Flow.Launcher.Infrastructure/Constant.cs | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs index 8b860b3a012..2d473c80691 100644 --- a/Flow.Launcher.Core/Configuration/Portable.cs +++ b/Flow.Launcher.Core/Configuration/Portable.cs @@ -81,18 +81,17 @@ internal void IndicateDeletion(string filePathTodelete) public void PreStartCleanUpAfterPortabilityUpdate() { var locator = VelopackLocator.GetDefault(null); - - // this would not happen for development environment - if (locator.PackagesDir != null) + + // check whether the package locate in %localappdata% + // if not create the portable data folder + // Don't create the folder if the version is 1.0.0 (Dev) to allow potential debugging with data in the project folder + // It is still possible to create the UserData folder for dev version manually but we want to keep the current behavior + if (!Constant.ProgramDirectory.IsSubPathOf( + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)) + && !DataLocation.PortableDataPath.LocationExists() + && Constant.Version != "1.0.0") { - // check whether the package locate in %localappdata% - // if not create the portable data folder - if (!locator.PackagesDir.IsSubPathOf( - Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)) - && !DataLocation.PortableDataPath.LocationExists()) - { - Directory.CreateDirectory(DataLocation.PortableDataPath); - } + Directory.CreateDirectory(DataLocation.PortableDataPath); } // Specify here so this method does not rely on other environment variables to initialise diff --git a/Flow.Launcher.Infrastructure/Constant.cs b/Flow.Launcher.Infrastructure/Constant.cs index 7a95b52d5e0..40759a64317 100644 --- a/Flow.Launcher.Infrastructure/Constant.cs +++ b/Flow.Launcher.Infrastructure/Constant.cs @@ -20,7 +20,7 @@ public static class Constant public static readonly string PreinstalledDirectory = Path.Combine(ProgramDirectory, Plugins); public const string IssuesUrl = "https://github.com/Flow-Launcher/Flow.Launcher/issues"; - public static readonly string Version = FileVersionInfo.GetVersionInfo(Assembly.Location.NonNull()).ProductVersion; + public static readonly string Version = FileVersionInfo.GetVersionInfo(Assembly.Location.NonNull()).FileVersion; public static readonly string Dev = "Dev"; public const string Documentation = "https://flowlauncher.com/docs/#/usage-tips"; From fc96eeda120e10692a8434e720292d179c2ab6d6 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 27 Mar 2024 16:58:31 -0500 Subject: [PATCH 46/75] set NUGET_CERT_REVOCATION_MODE to offline to prevent slower restore --- .github/workflows/dotnet.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b481500c36a..d7fc9aed6f6 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -20,6 +20,7 @@ jobs: runs-on: windows-latest env: FlowVersion: 1.17.2 + NUGET_CERT_REVOCATION_MODE: offline steps: - uses: actions/checkout@v4 - name: Generate build number From 8f718fdcf381b833fade54faaf2bcd370ae8d70e Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 27 Mar 2024 17:32:24 -0500 Subject: [PATCH 47/75] try again --- Flow.Launcher.Core/Configuration/Portable.cs | 7 ++----- Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs | 6 ++++++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs index 2d473c80691..fe9ac6a0c0d 100644 --- a/Flow.Launcher.Core/Configuration/Portable.cs +++ b/Flow.Launcher.Core/Configuration/Portable.cs @@ -95,11 +95,8 @@ public void PreStartCleanUpAfterPortabilityUpdate() } // Specify here so this method does not rely on other environment variables to initialise - var portableDataDir = - Path.Combine(Directory.GetParent(Assembly.GetExecutingAssembly().Location.NonNull()).ToString(), - "UserData"); - var roamingDataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), - "FlowLauncher"); + var portableDataDir = DataLocation.PortableDataPath; + var roamingDataDir = DataLocation.RoamingDataPath; // Get full path to the .dead files for each case diff --git a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs index f25f9fe2ae3..1341318e023 100644 --- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs +++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs @@ -15,6 +15,12 @@ public static class FilesFolders { private const string FileExplorerProgramName = "explorer"; + /// + /// Checks if is a subpath of + /// + /// + /// + /// public static bool IsSubPathOf(this string subPath, string basePath) { var rel = Path.GetRelativePath( From 94d912d1162fbd541360911ac11e55e2571dc017 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 27 Mar 2024 17:55:10 -0500 Subject: [PATCH 48/75] do not use tag number to create build which causes appveyor to publish release --- .github/workflows/dotnet.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d7fc9aed6f6..561d0deccdc 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -21,13 +21,9 @@ jobs: env: FlowVersion: 1.17.2 NUGET_CERT_REVOCATION_MODE: offline + BUILD_NUMBER: ${{ github.run_number }} steps: - uses: actions/checkout@v4 - - name: Generate build number - id: buildnumber - uses: onyxmueller/build-tag-number@v1 - with: - token: ${{secrets.github_token}} - name: Set Flow.Launcher.csproj version id: update uses: vers-one/dotnet-project-version-updater@v1.5 From 1ca7ff0c119a7de258d0c65cdef33d291189dfc1 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 27 Mar 2024 18:55:28 -0500 Subject: [PATCH 49/75] try sourcelink --- Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj | 2 +- SolutionAssemblyInfo.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj index cc89afbc2e3..a84a864f691 100644 --- a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj +++ b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj @@ -66,7 +66,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/SolutionAssemblyInfo.cs b/SolutionAssemblyInfo.cs index 2938bcbbedd..8d8007afef7 100644 --- a/SolutionAssemblyInfo.cs +++ b/SolutionAssemblyInfo.cs @@ -18,4 +18,3 @@ [assembly: ComVisible(false)] [assembly: AssemblyVersion("1.0.0")] [assembly: AssemblyFileVersion("1.0.0")] -[assembly: AssemblyInformationalVersion("1.0.0")] From 92839b004e862e6d6465757cd7c971bbc22c39e7 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 27 Mar 2024 19:10:44 -0500 Subject: [PATCH 50/75] don't check whether the location exists and use the productversion since that's inherited from assembly version --- Flow.Launcher.Core/Configuration/Portable.cs | 3 --- Flow.Launcher.Infrastructure/Constant.cs | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs index fe9ac6a0c0d..826e9f8ac42 100644 --- a/Flow.Launcher.Core/Configuration/Portable.cs +++ b/Flow.Launcher.Core/Configuration/Portable.cs @@ -80,15 +80,12 @@ internal void IndicateDeletion(string filePathTodelete) /// public void PreStartCleanUpAfterPortabilityUpdate() { - var locator = VelopackLocator.GetDefault(null); - // check whether the package locate in %localappdata% // if not create the portable data folder // Don't create the folder if the version is 1.0.0 (Dev) to allow potential debugging with data in the project folder // It is still possible to create the UserData folder for dev version manually but we want to keep the current behavior if (!Constant.ProgramDirectory.IsSubPathOf( Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)) - && !DataLocation.PortableDataPath.LocationExists() && Constant.Version != "1.0.0") { Directory.CreateDirectory(DataLocation.PortableDataPath); diff --git a/Flow.Launcher.Infrastructure/Constant.cs b/Flow.Launcher.Infrastructure/Constant.cs index 40759a64317..7a95b52d5e0 100644 --- a/Flow.Launcher.Infrastructure/Constant.cs +++ b/Flow.Launcher.Infrastructure/Constant.cs @@ -20,7 +20,7 @@ public static class Constant public static readonly string PreinstalledDirectory = Path.Combine(ProgramDirectory, Plugins); public const string IssuesUrl = "https://github.com/Flow-Launcher/Flow.Launcher/issues"; - public static readonly string Version = FileVersionInfo.GetVersionInfo(Assembly.Location.NonNull()).FileVersion; + public static readonly string Version = FileVersionInfo.GetVersionInfo(Assembly.Location.NonNull()).ProductVersion; public static readonly string Dev = "Dev"; public const string Documentation = "https://flowlauncher.com/docs/#/usage-tips"; From db4553f1c8e1298e03f8d92d961cd70cba288425 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Fri, 29 Mar 2024 12:18:51 -0500 Subject: [PATCH 51/75] fix a little spell check --- .github/actions/spelling/allow.txt | 4 ++++ .github/actions/spelling/expect.txt | 2 ++ .github/actions/spelling/patterns.txt | 6 ++++++ Flow.Launcher.Core/Configuration/Portable.cs | 6 +++--- Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs | 12 ++++++------ Flow.Launcher.Test/PluginLoadTest.cs | 2 +- Flow.Launcher/App.xaml.cs | 4 ++-- Flow.Launcher/Helper/SingleInstance.cs | 8 ++++---- README.md | 2 +- 9 files changed, 29 insertions(+), 17 deletions(-) diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt index 00cc67ea00f..01994ec7855 100644 --- a/.github/actions/spelling/allow.txt +++ b/.github/actions/spelling/allow.txt @@ -3,3 +3,7 @@ https ssh ubuntu runcount +nunit +velopack +vpk +vsc \ No newline at end of file diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 2d6fdb7f0aa..48ed17983ed 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -106,3 +106,5 @@ alreadyexists JsonRPC JsonRPCV2 Softpedia +ime +LPWStr \ No newline at end of file diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt index f29f57ad50e..52db824891c 100644 --- a/.github/actions/spelling/patterns.txt +++ b/.github/actions/spelling/patterns.txt @@ -29,6 +29,12 @@ # IServiceProvider \bI(?=(?:[A-Z][a-z]{2,})+\b) +# KListener +\bK(?=(?:[A-Z][a-z]{2,})+\b) + +# TApplication +\bT(?=(?:[A-Z][a-z]{2,})+\b) + # hit-count: 297 file-count: 18 # uuid: \b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs index 826e9f8ac42..f46701b75b1 100644 --- a/Flow.Launcher.Core/Configuration/Portable.cs +++ b/Flow.Launcher.Core/Configuration/Portable.cs @@ -66,9 +66,9 @@ public void VerifyUserDataAfterMove(string fromLocation, string toLocation) } - internal void IndicateDeletion(string filePathTodelete) + internal void IndicateDeletion(string filePathToDelete) { - var deleteFilePath = Path.Combine(filePathTodelete, DataLocation.DeletionIndicatorFile); + var deleteFilePath = Path.Combine(filePathToDelete, DataLocation.DeletionIndicatorFile); using (var _ = File.CreateText(deleteFilePath)) { } @@ -80,7 +80,7 @@ internal void IndicateDeletion(string filePathTodelete) /// public void PreStartCleanUpAfterPortabilityUpdate() { - // check whether the package locate in %localappdata% + // check whether the package locate in %LocalAppData% // if not create the portable data folder // Don't create the folder if the version is 1.0.0 (Dev) to allow potential debugging with data in the project folder // It is still possible to create the UserData folder for dev version manually but we want to keep the current behavior diff --git a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs index 1341318e023..2fa0a0975af 100644 --- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs +++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs @@ -35,7 +35,7 @@ public static bool IsSubPathOf(this string subPath, string basePath) /// /// Copies the folder and all of its files and folders - /// including subfolders to the target location + /// including subFolders to the target location /// /// /// @@ -64,15 +64,15 @@ public static void CopyAll(this string sourcePath, string targetPath) FileInfo[] files = dir.GetFiles(); foreach (FileInfo file in files) { - string temppath = Path.Combine(targetPath, file.Name); - file.CopyTo(temppath, false); + string tempPath = Path.Combine(targetPath, file.Name); + file.CopyTo(tempPath, false); } // Recursively copy subdirectories by calling itself on each subdirectory until there are no more to copy - foreach (DirectoryInfo subdir in dirs) + foreach (DirectoryInfo subDir in dirs) { - string temppath = Path.Combine(targetPath, subdir.Name); - CopyAll(subdir.FullName, temppath); + string temppath = Path.Combine(targetPath, subDir.Name); + CopyAll(subDir.FullName, temppath); } } catch (Exception) diff --git a/Flow.Launcher.Test/PluginLoadTest.cs b/Flow.Launcher.Test/PluginLoadTest.cs index 65700ee362c..f41c10c189d 100644 --- a/Flow.Launcher.Test/PluginLoadTest.cs +++ b/Flow.Launcher.Test/PluginLoadTest.cs @@ -65,7 +65,7 @@ public void GivenDuplicatePluginMetadatasWhenLoadedThenShouldReturnOnlyUniqueLis } [Test] - public void GivenDuplicatePluginMetadatasWithNoUniquePluginWhenLoadedThenShouldReturnEmptyList() + public void GivenDuplicatePluginMetaDataWithNoUniquePluginWhenLoadedThenShouldReturnEmptyList() { // Given var duplicateList = new List diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index 2792fdfffd2..99b575d0505 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -65,7 +65,7 @@ await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () => RegisterAppDomainExceptions(); RegisterDispatcherUnhandledException(); - var imageLoadertask = ImageLoader.InitializeAsync(); + var imageLoaderTask = ImageLoader.InitializeAsync(); _settingsVM = new SettingWindowViewModel(_updater, _portable); _settings = _settingsVM.Settings; @@ -86,7 +86,7 @@ await Stopwatch.NormalAsync("|App.OnStartup|Startup cost", async () => Http.Proxy = _settings.Proxy; await PluginManager.InitializePluginsAsync(API); - await imageLoadertask; + await imageLoaderTask; var window = new MainWindow(_settings, _mainVM); diff --git a/Flow.Launcher/Helper/SingleInstance.cs b/Flow.Launcher/Helper/SingleInstance.cs index b0b8e84b227..a516bfee02b 100644 --- a/Flow.Launcher/Helper/SingleInstance.cs +++ b/Flow.Launcher/Helper/SingleInstance.cs @@ -14,7 +14,7 @@ using Velopack; // http://blogs.microsoft.co.il/arik/2010/05/28/wpf-single-instance-application/ -// modified to allow single instace restart +// modified to allow single instance restart namespace Flow.Launcher.Helper { internal enum WM @@ -311,9 +311,9 @@ private static IList GetCommandLineArgs(string uniqueApplicationName) catch (NotSupportedException) { // The application was clickonce deployed - // Clickonce deployed apps cannot recieve traditional commandline arguments - // As a workaround commandline arguments can be written to a shared location before - // the app is launched and the app can obtain its commandline arguments from the + // Clickonce deployed apps cannot recieve traditional command line arguments + // As a workaround command line arguments can be written to a shared location before + // the app is launched and the app can obtain its command line arguments from the // shared location string appFolderPath = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), uniqueApplicationName); diff --git a/README.md b/README.md index 9ebbe246cbe..325dc9e4b7d 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ And you can download [early access version](https://github.com/Flow-Launcher/Pre - Fully portable. - Type `flow user data` to open your saved user settings folder. They are located at: - If using roaming: `%APPDATA%\FlowLauncher` - - If using portable, by default: `%localappdata%\FlowLauncher\app-\UserData` + - If using portable, by default: `%LocalAppData%\FlowLauncher\app-\UserData` - Type `open log location` to open your logs folder, they are saved along with your user settings folder. ### 🎮 Game Mode From 0d0bd5e8478205f75ab1532e1fdf333e08445f9f Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Fri, 29 Mar 2024 12:23:07 -0500 Subject: [PATCH 52/75] do not include some test file --- .github/actions/spelling/excludes.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/actions/spelling/excludes.txt b/.github/actions/spelling/excludes.txt index 224014ebac5..397c0e6d973 100644 --- a/.github/actions/spelling/excludes.txt +++ b/.github/actions/spelling/excludes.txt @@ -71,3 +71,5 @@ ignore$ \.csproj$ \.DotSettings$ \.targets$ +\FuzzyMatcherTest.cs$ +\ExplorerTest.cs \ No newline at end of file From d9c65e27bfaedf6bdd538c7fba57a979b9a15c16 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Fri, 29 Mar 2024 12:26:00 -0500 Subject: [PATCH 53/75] remove all test from spellcheck (should do them manually) --- .github/actions/spelling/excludes.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/actions/spelling/excludes.txt b/.github/actions/spelling/excludes.txt index 397c0e6d973..74ebe82c99a 100644 --- a/.github/actions/spelling/excludes.txt +++ b/.github/actions/spelling/excludes.txt @@ -71,5 +71,4 @@ ignore$ \.csproj$ \.DotSettings$ \.targets$ -\FuzzyMatcherTest.cs$ -\ExplorerTest.cs \ No newline at end of file +.*Test.cs$ \ No newline at end of file From 01bbe8f92ddc6bcf35734654cbe6e8321ec54e04 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Fri, 29 Mar 2024 12:41:35 -0500 Subject: [PATCH 54/75] change a little bit pattern --- .github/actions/spelling/patterns.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt index 52db824891c..fd134d799d6 100644 --- a/.github/actions/spelling/patterns.txt +++ b/.github/actions/spelling/patterns.txt @@ -27,7 +27,8 @@ # Automatically suggested patterns # hit-count: 360 file-count: 108 # IServiceProvider -\bI(?=(?:[A-Z][a-z]{2,})+\b) +# IPublicAPI +\bI(?=(?:[A-Z][a-z]{2,}[A-Z]*)+\b) # KListener \bK(?=(?:[A-Z][a-z]{2,})+\b) From 8ba180b57065eca20b01cb970217cdc2b1b7bacf Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Fri, 29 Mar 2024 12:48:20 -0500 Subject: [PATCH 55/75] fix more spellcheck --- .github/actions/spelling/allow.txt | 15 ++++++++++++++- Flow.Launcher.Core/Configuration/Portable.cs | 2 +- .../SharedCommands/FilesFolders.cs | 4 ++-- Flow.Launcher/App.xaml.cs | 4 ++-- Flow.Launcher/Helper/SingleInstance.cs | 2 +- Flow.Launcher/PublicAPIInstance.cs | 4 ++-- 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt index 01994ec7855..78b16e430b7 100644 --- a/.github/actions/spelling/allow.txt +++ b/.github/actions/spelling/allow.txt @@ -6,4 +6,17 @@ runcount nunit velopack vpk -vsc \ No newline at end of file +vsc +appveyor +appwrite +IME +hotkey +prioritise +runas +softpedia +sourcelink +TRAYMOUSEMESSAGE +uninstaller +vkcode +winget +workaround \ No newline at end of file diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs index f46701b75b1..631e9484595 100644 --- a/Flow.Launcher.Core/Configuration/Portable.cs +++ b/Flow.Launcher.Core/Configuration/Portable.cs @@ -100,7 +100,7 @@ public void PreStartCleanUpAfterPortabilityUpdate() var portableDataDeleteFilePath = Path.Combine(portableDataDir, DataLocation.DeletionIndicatorFile); var roamingDataDeleteFilePath = Path.Combine(roamingDataDir, DataLocation.DeletionIndicatorFile); - // If the data folder in %appdata% is marked for deletion, + // If the data folder in %AppData% is marked for deletion, // delete it and prompt the user to pick the portable data location if (File.Exists(roamingDataDeleteFilePath)) { diff --git a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs index 2fa0a0975af..39ad6304c8c 100644 --- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs +++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs @@ -71,8 +71,8 @@ public static void CopyAll(this string sourcePath, string targetPath) // Recursively copy subdirectories by calling itself on each subdirectory until there are no more to copy foreach (DirectoryInfo subDir in dirs) { - string temppath = Path.Combine(targetPath, subDir.Name); - CopyAll(subDir.FullName, temppath); + string tempPath = Path.Combine(targetPath, subDir.Name); + CopyAll(subDir.FullName, tempPath); } } catch (Exception) diff --git a/Flow.Launcher/App.xaml.cs b/Flow.Launcher/App.xaml.cs index 99b575d0505..d08a4bf2ede 100644 --- a/Flow.Launcher/App.xaml.cs +++ b/Flow.Launcher/App.xaml.cs @@ -184,8 +184,8 @@ private static void RegisterAppDomainExceptions() public void Dispose() { - // if sessionending is called, exit proverbially be called when log off / shutdown - // but if sessionending is not called, exit won't be called when log off / shutdown + // if session-ending is called, exit proverbially be called when log off / shutdown + // but if session-ending is not called, exit won't be called when log off / shutdown if (!_disposed) { API.SaveAppAllSettings(); diff --git a/Flow.Launcher/Helper/SingleInstance.cs b/Flow.Launcher/Helper/SingleInstance.cs index a516bfee02b..9d077fa8268 100644 --- a/Flow.Launcher/Helper/SingleInstance.cs +++ b/Flow.Launcher/Helper/SingleInstance.cs @@ -311,7 +311,7 @@ private static IList GetCommandLineArgs(string uniqueApplicationName) catch (NotSupportedException) { // The application was clickonce deployed - // Clickonce deployed apps cannot recieve traditional command line arguments + // Clickonce deployed apps cannot receive traditional command line arguments // As a workaround command line arguments can be written to a shared location before // the app is launched and the app can obtain its command line arguments from the // shared location diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 6d5d4e1ba0f..6b327b2be63 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -315,12 +315,12 @@ public bool IsGameModeOn() #region Private Methods - private bool KListener_hookedKeyboardCallback(KeyEvent keyevent, int vkcode, SpecialKeyState state) + private bool KListener_hookedKeyboardCallback(KeyEvent keyEvent, int vkCode, SpecialKeyState state) { var continueHook = true; foreach (var x in _globalKeyboardHandlers) { - continueHook &= x((int)keyevent, vkcode, state); + continueHook &= x((int)keyEvent, vkCode, state); } return continueHook; From 6c3bcdc0b38c998b90208902836c978a89f3b1e2 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Fri, 29 Mar 2024 12:53:13 -0500 Subject: [PATCH 56/75] fix remaining spell --- .github/actions/spelling/allow.txt | 3 ++- .github/actions/spelling/excludes.txt | 2 +- .github/actions/spelling/expect.txt | 8 +++++++- Flow.Launcher/Helper/SingleInstance.cs | 6 +++--- Flow.Launcher/PublicAPIInstance.cs | 4 ++-- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt index 78b16e430b7..19f257eada2 100644 --- a/.github/actions/spelling/allow.txt +++ b/.github/actions/spelling/allow.txt @@ -19,4 +19,5 @@ TRAYMOUSEMESSAGE uninstaller vkcode winget -workaround \ No newline at end of file +workaround +nupkg diff --git a/.github/actions/spelling/excludes.txt b/.github/actions/spelling/excludes.txt index 74ebe82c99a..feb6f0ff007 100644 --- a/.github/actions/spelling/excludes.txt +++ b/.github/actions/spelling/excludes.txt @@ -71,4 +71,4 @@ ignore$ \.csproj$ \.DotSettings$ \.targets$ -.*Test.cs$ \ No newline at end of file +.*Test.cs$ diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 06466654294..ca2edec26b3 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -108,4 +108,10 @@ JsonRPCV2 Softpedia img ime -LPWStr \ No newline at end of file +LPWStr +flowlauncher +hotkeys +LPW +productversion +requery +Wnd diff --git a/Flow.Launcher/Helper/SingleInstance.cs b/Flow.Launcher/Helper/SingleInstance.cs index 9d077fa8268..d46051126ec 100644 --- a/Flow.Launcher/Helper/SingleInstance.cs +++ b/Flow.Launcher/Helper/SingleInstance.cs @@ -305,13 +305,13 @@ private static IList GetCommandLineArgs(string uniqueApplicationName) try { - // The application was not clickonce deployed, get args from standard API's + // The application was not ClickOnce deployed, get args from standard API's args = Environment.GetCommandLineArgs(); } catch (NotSupportedException) { - // The application was clickonce deployed - // Clickonce deployed apps cannot receive traditional command line arguments + // The application was ClickOnce deployed + // ClickOnce deployed apps cannot receive traditional command line arguments // As a workaround command line arguments can be written to a shared location before // the app is launched and the app can obtain its command line arguments from the // shared location diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 6b327b2be63..5b149f8bfe5 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -40,7 +40,7 @@ public PublicAPIInstance(SettingWindowViewModel settingsVM, MainViewModel mainVM _settingsVM = settingsVM; _mainVM = mainVM; _alphabet = alphabet; - GlobalHotkey.hookedKeyboardCallback = KListener_hookedKeyboardCallback; + GlobalHotkey.hookedKeyboardCallback = KListenerHookedKeyboardCallback; WebRequest.RegisterPrefix("data", new DataWebRequestFactory()); } @@ -315,7 +315,7 @@ public bool IsGameModeOn() #region Private Methods - private bool KListener_hookedKeyboardCallback(KeyEvent keyEvent, int vkCode, SpecialKeyState state) + private bool KListenerHookedKeyboardCallback(KeyEvent keyEvent, int vkCode, SpecialKeyState state) { var continueHook = true; foreach (var x in _globalKeyboardHandlers) From c058c649c2dc401942ebb598e215146e0fa2ce4a Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Fri, 3 May 2024 18:42:47 +0800 Subject: [PATCH 57/75] Use full path while deleting --- Scripts/post_build.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index 2633c24c5f9..49de9df8cbd 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -83,7 +83,7 @@ function Delete-Unused($path, $config) foreach ($i in $deleteList) { write "Deleting duplicated $($i.Name) with version $($i.VersionInfo.FileVersion) at location $($i.Directory.FullName)" - Remove-Item $i + Remove-Item -Path $i.FullName } Remove-Item -Path $target -Include "*.xml" -Recurse } From 82584c26bba9587a0f9ee9fa8f0c4b48f5397257 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Fri, 3 May 2024 18:54:30 +0800 Subject: [PATCH 58/75] Create UserData folder before Packing --- Scripts/post_build.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index 49de9df8cbd..9bb7ef2dcf8 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -119,7 +119,10 @@ function Pack-Velopack-Installer($path, $version, $output) { dotnet tool install --global vpk } - + + # Create UserData folder before Packing + New-Item -ItemType Directory -Force -Path "$input\UserData" + vpk pack --packVersion $version --packDir $input --packId FlowLauncher --mainExe Flow.Launcher.exe --channel $channel } From 0982e9b5fe47e94b7dce9da2195a16eabd634945 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Fri, 3 May 2024 19:11:25 +0800 Subject: [PATCH 59/75] Use variable for input path --- Scripts/post_build.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index 9bb7ef2dcf8..a03eb8eea56 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -101,7 +101,7 @@ function Pack-Velopack-Installer($path, $version, $output) Write-Host "Begin pack squirrel installer" $spec = "$path\Scripts\flowlauncher.nuspec" - $input = "$path\Output\Release" + $input = "$path\Output\$config" Write-Host "Packing: $spec" Write-Host "Input path: $input" From 40691a644c2a5d6c0321c2d473200c6dd27ae99a Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Fri, 3 May 2024 19:47:16 +0800 Subject: [PATCH 60/75] Add icon for installer --- Scripts/post_build.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index a03eb8eea56..761ad7d7d89 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -123,7 +123,7 @@ function Pack-Velopack-Installer($path, $version, $output) # Create UserData folder before Packing New-Item -ItemType Directory -Force -Path "$input\UserData" - vpk pack --packVersion $version --packDir $input --packId FlowLauncher --mainExe Flow.Launcher.exe --channel $channel + vpk pack --packVersion $version --packDir $input --packId FlowLauncher --mainExe Flow.Launcher.exe --channel $channel --outputDir $output --packTitle "Flow Launcher" --icon "$input\Images\app.ico" } function Publish-Self-Contained($p) From 8fd998c089021913f7e71c7b6c65c9204623d3dd Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Fri, 3 May 2024 22:28:41 -0500 Subject: [PATCH 61/75] add dotnet tool update again --- .github/workflows/dotnet.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 561d0deccdc..331455fc8ef 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -51,10 +51,10 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: 7.0.x -# - name: Install vpk - # Install vpk tool (dotnet tool install will not reinstall if already installed) - # We will update the cli by removing cache -# run: dotnet tool install -g vpk + - name: Install vpk + Install vpk tool (dotnet tool install will not reinstall if already installed) + We will update the cli by removing cache + run: dotnet tool update -g vpk - name: Restore dependencies run: dotnet restore - name: Build From 61238641cbca4be9445ac0bc31c74b7c06b36ad3 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Sat, 4 May 2024 12:02:05 +0800 Subject: [PATCH 62/75] Revert output path --- .github/workflows/dotnet.yml | 2 +- Scripts/post_build.ps1 | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 331455fc8ef..0a4773de437 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -19,7 +19,7 @@ jobs: runs-on: windows-latest env: - FlowVersion: 1.17.2 + FlowVersion: 1.18.0 NUGET_CERT_REVOCATION_MODE: offline BUILD_NUMBER: ${{ github.run_number }} steps: diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index 761ad7d7d89..e8a098696b2 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -105,6 +105,7 @@ function Pack-Velopack-Installer($path, $version, $output) Write-Host "Packing: $spec" Write-Host "Input path: $input" + Write-Host "Output path: $output" $repoUrl = "https://github.com/Flow-Launcher/Prereleases" @@ -121,7 +122,8 @@ function Pack-Velopack-Installer($path, $version, $output) } # Create UserData folder before Packing - New-Item -ItemType Directory -Force -Path "$input\UserData" + # FIXME userdata should not be created in installer version + # New-Item -ItemType Directory -Force -Path "$input\UserData" vpk pack --packVersion $version --packDir $input --packId FlowLauncher --mainExe Flow.Launcher.exe --channel $channel --outputDir $output --packTitle "Flow Launcher" --icon "$input\Images\app.ico" } @@ -147,7 +149,7 @@ function Main Publish-Self-Contained $p - $o = "$p\Output\Packages" + $o = "$p\Releases" Validate-Directory $o Pack-Velopack-Installer $p $v $o } From 75b1c4b15e0f500d9b7278f668703977a6d5d111 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Thu, 23 May 2024 23:02:24 +0800 Subject: [PATCH 63/75] Remove duplicate function --- Flow.Launcher.Core/Configuration/Portable.cs | 11 ++-------- .../SharedCommands/FilesFolders.cs | 20 +------------------ 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs index 631e9484595..21bd04bda86 100644 --- a/Flow.Launcher.Core/Configuration/Portable.cs +++ b/Flow.Launcher.Core/Configuration/Portable.cs @@ -1,17 +1,11 @@ -using Microsoft.Win32; -using System; +using System; using System.IO; -using System.Reflection; using System.Windows; using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin.SharedCommands; -using System.Linq; using Flow.Launcher.Core.Plugin; -using Velopack; -using Velopack.Locators; -using Velopack.Windows; namespace Flow.Launcher.Core.Configuration { @@ -84,8 +78,7 @@ public void PreStartCleanUpAfterPortabilityUpdate() // if not create the portable data folder // Don't create the folder if the version is 1.0.0 (Dev) to allow potential debugging with data in the project folder // It is still possible to create the UserData folder for dev version manually but we want to keep the current behavior - if (!Constant.ProgramDirectory.IsSubPathOf( - Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)) + if (!Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData).PathContains(Constant.ProgramDirectory) && Constant.Version != "1.0.0") { Directory.CreateDirectory(DataLocation.PortableDataPath); diff --git a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs index 39ad6304c8c..a835c5b964e 100644 --- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs +++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs @@ -15,24 +15,6 @@ public static class FilesFolders { private const string FileExplorerProgramName = "explorer"; - /// - /// Checks if is a subpath of - /// - /// - /// - /// - public static bool IsSubPathOf(this string subPath, string basePath) - { - var rel = Path.GetRelativePath( - basePath.Replace('\\', '/'), - subPath.Replace('\\', '/')); - return rel != "." - && rel != ".." - && !rel.StartsWith("../") - && !Path.IsPathRooted(rel); - } - - /// /// Copies the folder and all of its files and folders /// including subFolders to the target location @@ -287,7 +269,7 @@ public static string ReturnPreviousDirectoryIfIncompleteString(string path) /// Sub path /// If , when and are equal, returns /// - public static bool PathContains(string parentPath, string subPath, bool allowEqual = false) + public static bool PathContains(this string parentPath, string subPath, bool allowEqual = false) { var rel = Path.GetRelativePath(parentPath.EnsureTrailingSlash(), subPath); return (rel != "." || allowEqual) From ac498885ce23aaca4245a9657effd6c7ce67e359 Mon Sep 17 00:00:00 2001 From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com> Date: Thu, 23 May 2024 23:10:53 +0800 Subject: [PATCH 64/75] Fix build error --- Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs index 691f9c26cc8..94f808ec9ff 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs @@ -1,6 +1,4 @@ using Flow.Launcher.Core.ExternalPlugins; -using Flow.Launcher.Infrastructure.UserSettings; -using ICSharpCode.SharpZipLib.Zip; using Newtonsoft.Json; using System.IO; using System.IO.Compression; From d0e092942b507536f40e3b25aedd4ef222864dff Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sat, 25 May 2024 19:30:40 -0500 Subject: [PATCH 65/75] fix a typo for portable build --- Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs | 2 +- Plugins/Flow.Launcher.Plugin.Calculator/Main.cs | 2 +- appveyor.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs index a48d70f2d46..bb8cec137e0 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs @@ -15,7 +15,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark; public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContextMenu, IDisposable { - private static PluginInitContext _context; + internal static PluginInitContext _context { get; private set; } = null!; private static List _cachedBookmarks = new List(); diff --git a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs index 338b5bcbe43..9f7721b8acd 100644 --- a/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Calculator/Main.cs @@ -28,7 +28,7 @@ public class Main : IPlugin, IPluginI18n, ISettingProvider private const string comma = ","; private const string dot = "."; - private PluginInitContext Context { get; set; } + internal static PluginInitContext Context { get; set; } private static Settings _settings; private static SettingsViewModel _viewModel; diff --git a/appveyor.yml b/appveyor.yml index c9ba17077dd..412a26cba2a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -48,7 +48,7 @@ artifacts: name: Plugin nupkg - path: 'Releases\FlowLauncher-*.exe' name: Squirrel Installer -- path: 'Release\FlowLauncher-*-Portable.zip' +- path: 'Releases\FlowLauncher-*-Portable.zip' name: Portable Version - path: 'Releases\FlowLauncher-*-full.nupkg' name: Squirrel nupkg From c3c21225e62f9c330a5154051e27ada3f7d3fda3 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Mon, 27 May 2024 11:56:27 -0500 Subject: [PATCH 66/75] put the portable data path creation into the static constructor of DataLocation.cs --- Flow.Launcher.Core/Configuration/Portable.cs | 10 -------- .../UserSettings/DataLocation.cs | 24 +++++++++++++++++-- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs index 21bd04bda86..fae78b70573 100644 --- a/Flow.Launcher.Core/Configuration/Portable.cs +++ b/Flow.Launcher.Core/Configuration/Portable.cs @@ -74,16 +74,6 @@ internal void IndicateDeletion(string filePathToDelete) /// public void PreStartCleanUpAfterPortabilityUpdate() { - // check whether the package locate in %LocalAppData% - // if not create the portable data folder - // Don't create the folder if the version is 1.0.0 (Dev) to allow potential debugging with data in the project folder - // It is still possible to create the UserData folder for dev version manually but we want to keep the current behavior - if (!Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData).PathContains(Constant.ProgramDirectory) - && Constant.Version != "1.0.0") - { - Directory.CreateDirectory(DataLocation.PortableDataPath); - } - // Specify here so this method does not rely on other environment variables to initialise var portableDataDir = DataLocation.PortableDataPath; var roamingDataDir = DataLocation.RoamingDataPath; diff --git a/Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs b/Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs index e294f52b8c5..51ff5157dc3 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs @@ -1,14 +1,32 @@ using System; using System.IO; +using Flow.Launcher.Plugin.SharedCommands; namespace Flow.Launcher.Infrastructure.UserSettings { public static class DataLocation { + static DataLocation() + { + // check whether the package locate in %LocalAppData% + // if not create the portable data folder + // Don't create the folder if the version is 1.0.0 (Dev) to allow potential debugging with data in the project folder + // It is still possible to create the UserData folder for dev version manually but we want to keep the current behavior + if (!Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + .PathContains(Constant.ProgramDirectory) + && Constant.Version != "1.0.0") + { + Directory.CreateDirectory(PortableDataPath); + } + } + public const string PortableFolderName = "UserData"; public const string DeletionIndicatorFile = ".dead"; public static string PortableDataPath = Path.Combine(Constant.ProgramDirectory, PortableFolderName); - public static string RoamingDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FlowLauncher"); + + public static string RoamingDataPath = + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FlowLauncher"); + public static string DataDirectory() { if (PortableDataLocationInUse()) @@ -26,7 +44,9 @@ public static bool PortableDataLocationInUse() } public static readonly string PluginsDirectory = Path.Combine(DataDirectory(), Constant.Plugins); - public static readonly string PluginSettingsDirectory = Path.Combine(DataDirectory(), "Settings", Constant.Plugins); + + public static readonly string PluginSettingsDirectory = + Path.Combine(DataDirectory(), "Settings", Constant.Plugins); public const string PythonEnvironmentName = "Python"; public const string NodeEnvironmentName = "Node.js"; From 6db965148c7fd3b0cc0fbc1994b7c75f8957061d Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 28 May 2024 15:10:31 -0500 Subject: [PATCH 67/75] delay initialize datafolder to static constructor --- .../UserSettings/DataLocation.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs b/Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs index 51ff5157dc3..74b18957364 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs @@ -18,6 +18,9 @@ static DataLocation() { Directory.CreateDirectory(PortableDataPath); } + + PluginsDirectory = Path.Combine(DataDirectory(), Constant.Plugins); + PluginEnvironmentsPath = Path.Combine(DataDirectory(), PluginEnvironments); } public const string PortableFolderName = "UserData"; @@ -25,7 +28,7 @@ static DataLocation() public static string PortableDataPath = Path.Combine(Constant.ProgramDirectory, PortableFolderName); public static string RoamingDataPath = - Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FlowLauncher"); + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FlowLauncher") public static string DataDirectory() { @@ -43,7 +46,7 @@ public static bool PortableDataLocationInUse() return false; } - public static readonly string PluginsDirectory = Path.Combine(DataDirectory(), Constant.Plugins); + public static readonly string PluginsDirectory; public static readonly string PluginSettingsDirectory = Path.Combine(DataDirectory(), "Settings", Constant.Plugins); @@ -51,6 +54,6 @@ public static bool PortableDataLocationInUse() public const string PythonEnvironmentName = "Python"; public const string NodeEnvironmentName = "Node.js"; public const string PluginEnvironments = "Environments"; - public static readonly string PluginEnvironmentsPath = Path.Combine(DataDirectory(), PluginEnvironments); + public static readonly string PluginEnvironmentsPath; } } From 6c33308653da71d9ed6ecb03e6c1e5e89495fbc1 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Tue, 28 May 2024 15:14:18 -0500 Subject: [PATCH 68/75] fix typo --- Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs b/Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs index 74b18957364..4cab11ba234 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs @@ -28,7 +28,7 @@ static DataLocation() public static string PortableDataPath = Path.Combine(Constant.ProgramDirectory, PortableFolderName); public static string RoamingDataPath = - Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FlowLauncher") + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FlowLauncher"); public static string DataDirectory() { From 4945ca19297f5675b2860a6505c90343c07a7282 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sun, 2 Jun 2024 13:46:23 -0500 Subject: [PATCH 69/75] restore shortcut behavior --- Flow.Launcher.Core/Configuration/Portable.cs | 45 ++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs index fae78b70573..0353c232e4e 100644 --- a/Flow.Launcher.Core/Configuration/Portable.cs +++ b/Flow.Launcher.Core/Configuration/Portable.cs @@ -6,6 +6,8 @@ using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin.SharedCommands; using Flow.Launcher.Core.Plugin; +using Microsoft.Win32; +using Velopack.Windows; namespace Flow.Launcher.Core.Configuration { @@ -16,6 +18,13 @@ public void DisablePortableMode() try { MoveUserDataFolder(DataLocation.PortableDataPath, DataLocation.RoamingDataPath); +#if !DEBUG + // Create shortcuts and uninstaller are not required in debug mode, + // otherwise will repoint the path of the actual installed production version to the debug version + CreateShortcuts(); + // CreateUninstallerEntry(); +#endif + IndicateDeletion(DataLocation.PortableDataPath); MessageBox.Show("Flow Launcher needs to restart to finish disabling portable mode, " + @@ -29,11 +38,47 @@ public void DisablePortableMode() } } + public void CreateShortcuts() + { + var shortcuts = new Shortcuts(); + + shortcuts.CreateShortcutForThisExe(); + } + + public void RemoveShortcuts() + { + var shortcuts = new Shortcuts(); + + shortcuts.DeleteShortcuts(Velopack.Locators.VelopackLocator.GetDefault(null).ThisExeRelativePath, + ShortcutLocation.Desktop | ShortcutLocation.StartMenu); + } + + public void CreateUninstallerEntry() + { + var uninstallRegSubKey = @"Software\Microsoft\Windows\CurrentVersion\Uninstall"; + + using var baseKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default); + using var subKey1 = baseKey.CreateSubKey(uninstallRegSubKey, RegistryKeyPermissionCheck.ReadWriteSubTree); + using var subKey2 = + subKey1.CreateSubKey(Constant.FlowLauncher, RegistryKeyPermissionCheck.ReadWriteSubTree); + subKey2?.SetValue("DisplayIcon", Path.Combine(Constant.ApplicationDirectory, "app.ico"), + RegistryValueKind.String); + } + + public void EnablePortableMode() { try { MoveUserDataFolder(DataLocation.RoamingDataPath, DataLocation.PortableDataPath); + +#if !DEBUG + // Remove shortcuts and uninstaller are not required in debug mode, + // otherwise will delete the actual installed production version + RemoveShortcuts(); + // RemoveUninstallerEntry(); +#endif + IndicateDeletion(DataLocation.RoamingDataPath); MessageBox.Show("Flow Launcher needs to restart to finish enabling portable mode, " + From 239b97b34b4ecec63dd0a6717de2e9dd046ecc31 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sun, 16 Jun 2024 17:11:59 -0500 Subject: [PATCH 70/75] fix some merge issue --- Flow.Launcher/Flow.Launcher.csproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index 59c0f9749ee..b6aa897d21c 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -116,10 +116,6 @@ PreserveNewest - 1.0.0 - true - false - From ffe8352935b8b47ea61a0a9cd737d846d7fa4f67 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sun, 16 Jun 2024 17:18:57 -0500 Subject: [PATCH 71/75] try to not execute the command if vpk avaliable in the system. --- .github/workflows/dotnet.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 0a4773de437..9ba4f20ac78 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -54,7 +54,10 @@ jobs: - name: Install vpk Install vpk tool (dotnet tool install will not reinstall if already installed) We will update the cli by removing cache - run: dotnet tool update -g vpk + run: | + if (!(Get-Command vpk -ErrorAction SilentlyContinue)) { + dotnet tool install -g vpk + } - name: Restore dependencies run: dotnet restore - name: Build From dcd741afd8abf4c4d4b855974728ce255fb473f4 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sun, 16 Jun 2024 17:37:15 -0500 Subject: [PATCH 72/75] remote duplicate entry --- Flow.Launcher/Flow.Launcher.csproj | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj index b6aa897d21c..bba7594805a 100644 --- a/Flow.Launcher/Flow.Launcher.csproj +++ b/Flow.Launcher/Flow.Launcher.csproj @@ -118,12 +118,6 @@ - - - PreserveNewest - - - From 025c5039639d34d1b18aeb5a33a6964269fe6403 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sun, 16 Jun 2024 17:45:39 -0500 Subject: [PATCH 73/75] add authors and slight refactor to make code cleaner --- Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs | 4 +++- Scripts/post_build.ps1 | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs b/Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs index 4cab11ba234..2631dc0852e 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/DataLocation.cs @@ -14,7 +14,7 @@ static DataLocation() // It is still possible to create the UserData folder for dev version manually but we want to keep the current behavior if (!Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) .PathContains(Constant.ProgramDirectory) - && Constant.Version != "1.0.0") + && !IsDevVersion) { Directory.CreateDirectory(PortableDataPath); } @@ -30,6 +30,8 @@ static DataLocation() public static string RoamingDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FlowLauncher"); + public static bool IsDevVersion => Constant.Version == "1.0.0"; + public static string DataDirectory() { if (PortableDataLocationInUse()) diff --git a/Scripts/post_build.ps1 b/Scripts/post_build.ps1 index e8a098696b2..a6c31949404 100644 --- a/Scripts/post_build.ps1 +++ b/Scripts/post_build.ps1 @@ -125,7 +125,7 @@ function Pack-Velopack-Installer($path, $version, $output) # FIXME userdata should not be created in installer version # New-Item -ItemType Directory -Force -Path "$input\UserData" - vpk pack --packVersion $version --packDir $input --packId FlowLauncher --mainExe Flow.Launcher.exe --channel $channel --outputDir $output --packTitle "Flow Launcher" --icon "$input\Images\app.ico" + vpk pack --packVersion $version --packDir $input --packId FlowLauncher --mainExe Flow.Launcher.exe --channel $channel --outputDir $output --packTitle "Flow Launcher" --icon "$input\Images\app.ico" --packAuthors "Flow-Launcher Team" } function Publish-Self-Contained($p) From 11340d90d7b59283a0c11219c640a6c71a528ca6 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sun, 16 Jun 2024 17:48:07 -0500 Subject: [PATCH 74/75] change readme according to coderabbit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4c8d99ec8a9..f163f464ea3 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ scoop install Flow-Launcher choco install Flow-Launcher ``` -> When installing for the first time Windows may raise an issue about security due to code not being signed, if you downloaded from this repo then you are good to continue the set up. +> When installing for the first time Windows may raise an issue about security due to code not being signed, if you downloaded from this repo, then you are good to continue the set up. Or download the [early access version](https://github.com/Flow-Launcher/Prereleases/releases). @@ -122,7 +122,7 @@ Or download the [early access version](https://github.com/Flow-Launcher/Prerelea - Drag a file/folder to File Explorer, or even Discord. -- Copy/move behavior can be change via Ctrl or Shift, and the operation is displayed on the mouse cursor. +- Copy/move behavior can be changed via Ctrl or Shift, and the operation is displayed on the mouse cursor. ### Windows & Control Panel Settings @@ -378,7 +378,7 @@ Each of the pull requests will be marked with a milestone indicating the planned ### Contributing -Contributions are very welcome, in addition to the main project(C#) there are also [documentation](https://github.com/Flow-Launcher/docs)(md), [website](https://github.com/Flow-Launcher/flow-launcher.github.io)(html/css) and [others](https://github.com/Flow-Launcher) that can be contributed to. If you are unsure of a change you want to make, let us know in the [Discussions](https://github.com/Flow-Launcher/Flow.Launcher/discussions/categories/ideas), otherwise feel free to put in a pull request. +Contributions are very welcome, in addition to the main project(C#) there are also [documentation](https://github.com/Flow-Launcher/docs)(md), [website](https://github.com/Flow-Launcher/flow-launcher.github.io)(html/css) and [others](https://github.com/Flow-Launcher) that can be contributed to. If you are unsure of a change you want to make, let us know in the [Discussions](https://github.com/Flow-Launcher/Flow.Launcher/discussions/categories/ideas), otherwise, please consider submitting a pull request. You will find the main goals of flow placed under the [Projects board](https://github.com/Flow-Launcher/Flow.Launcher/projects), so feel free to contribute on that. If you would like to make small incremental changes, feel free to do so as well. From 0c46da1850d95024e3b56d7a3eba3eeae79cfc24 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 19 Jun 2024 12:41:51 -0500 Subject: [PATCH 75/75] disable the portable button --- Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml index 30e065b1601..8c072f9aedd 100644 --- a/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml +++ b/Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml @@ -161,6 +161,7 @@ Sub="{DynamicResource portableModeToolTIp}">