From 73056534bb413516740982dca7327234edc8436b Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sat, 8 Jan 2022 15:50:27 -0600 Subject: [PATCH 01/13] Reindex when app install or deleted (and uwp update). --- Plugins/Flow.Launcher.Plugin.Program/Main.cs | 16 +- .../Programs/UWP.cs | 151 +++++++++++++----- .../Programs/Win32.cs | 83 +++++++++- 3 files changed, 198 insertions(+), 52 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs index 634382109..cb0a2a4f3 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs @@ -18,7 +18,7 @@ using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch; namespace Flow.Launcher.Plugin.Program { - public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, ISavable, IAsyncReloadable + public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, ISavable, IAsyncReloadable, IDisposable { internal static Win32[] _win32s { get; set; } internal static UWP.Application[] _uwps { get; set; } @@ -126,6 +126,9 @@ namespace Flow.Launcher.Plugin.Program if (!(_win32s.Any() && _uwps.Any())) await indexTask; + + Win32.WatchProgramUpdate(_settings); + UWP.WatchUWPInstallation(); } public static void IndexWin32Programs() @@ -209,13 +212,11 @@ namespace Flow.Launcher.Plugin.Program return; if (_uwps.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier)) - _uwps.Where(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier) - .FirstOrDefault() + _uwps.FirstOrDefault(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier)! .Enabled = false; if (_win32s.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier)) - _win32s.Where(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier) - .FirstOrDefault() + _win32s.FirstOrDefault(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier)! .Enabled = false; _settings.DisabledProgramSources @@ -248,5 +249,10 @@ namespace Flow.Launcher.Plugin.Program { await IndexPrograms(); } + public void Dispose() + { + Win32.Dispose(); + UWP.Dispose(); + } } } \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs index 2a04b2b2e..b3d39bdbc 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs @@ -78,7 +78,7 @@ namespace Flow.Launcher.Plugin.Program.Programs { var e = Marshal.GetExceptionForHR((int)hResult); ProgramLogger.LogException($"|UWP|InitializeAppInfo|{path}" + - "|Error caused while trying to get the details of the UWP program", e); + "|Error caused while trying to get the details of the UWP program", e); Apps = new List().ToArray(); } @@ -91,28 +91,29 @@ namespace Flow.Launcher.Plugin.Program.Programs + /// http://www.hanselman.com/blog/GetNamespacesFromAnXMLDocumentWithXPathDocumentAndLINQToXML.aspx private string[] XmlNamespaces(string path) { XDocument z = XDocument.Load(path); if (z.Root != null) { - var namespaces = z.Root.Attributes(). - Where(a => a.IsNamespaceDeclaration). - GroupBy( - a => a.Name.Namespace == XNamespace.None ? string.Empty : a.Name.LocalName, - a => XNamespace.Get(a.Value) - ).Select( - g => g.First().ToString() - ).ToArray(); + var namespaces = z.Root.Attributes().Where(a => a.IsNamespaceDeclaration).GroupBy( + a => a.Name.Namespace == XNamespace.None ? string.Empty : a.Name.LocalName, + a => XNamespace.Get(a.Value) + ).Select( + g => g.First().ToString() + ).ToArray(); return namespaces; } else { ProgramLogger.LogException($"|UWP|XmlNamespaces|{path}" + - $"|Error occured while trying to get the XML from {path}", new ArgumentNullException()); + $"|Error occured while trying to get the XML from {path}", new ArgumentNullException()); - return new string[] { }; + return new string[] + { + }; } } @@ -120,9 +121,15 @@ namespace Flow.Launcher.Plugin.Program.Programs { var versionFromNamespace = new Dictionary { - {"http://schemas.microsoft.com/appx/manifest/foundation/windows10", PackageVersion.Windows10}, - {"http://schemas.microsoft.com/appx/2013/manifest", PackageVersion.Windows81}, - {"http://schemas.microsoft.com/appx/2010/manifest", PackageVersion.Windows8}, + { + "http://schemas.microsoft.com/appx/manifest/foundation/windows10", PackageVersion.Windows10 + }, + { + "http://schemas.microsoft.com/appx/2013/manifest", PackageVersion.Windows81 + }, + { + "http://schemas.microsoft.com/appx/2010/manifest", PackageVersion.Windows8 + }, }; foreach (var n in versionFromNamespace.Keys) @@ -135,8 +142,8 @@ namespace Flow.Launcher.Plugin.Program.Programs } ProgramLogger.LogException($"|UWP|XmlNamespaces|{Location}" + - "|Trying to get the package version of the UWP program, but a unknown UWP appmanifest version " - + $"{FullName} from location {Location} is returned.", new FormatException()); + "|Trying to get the package version of the UWP program, but a unknown UWP appmanifest version " + + $"{FullName} from location {Location} is returned.", new FormatException()); Version = PackageVersion.Unknown; } @@ -172,15 +179,17 @@ namespace Flow.Launcher.Plugin.Program.Programs }).ToArray(); var updatedListWithoutDisabledApps = applications - .Where(t1 => !Main._settings.DisabledProgramSources - .Any(x => x.UniqueIdentifier == t1.UniqueIdentifier)) - .Select(x => x); + .Where(t1 => !Main._settings.DisabledProgramSources + .Any(x => x.UniqueIdentifier == t1.UniqueIdentifier)) + .Select(x => x); return updatedListWithoutDisabledApps.ToArray(); } else { - return new Application[] { }; + return new Application[] + { + }; } } @@ -216,7 +225,7 @@ namespace Flow.Launcher.Plugin.Program.Programs catch (Exception e) { ProgramLogger.LogException("UWP", "CurrentUserPackages", $"id", "An unexpected error occured and " - + $"unable to verify if package is valid", e); + + $"unable to verify if package is valid", e); return false; } @@ -226,10 +235,30 @@ namespace Flow.Launcher.Plugin.Program.Programs } else { - return new Package[] { }; + return new Package[] + { + }; } } + private static List _watchers = new(); + + private static void GenerateWatcher(string path) + { + var watcher = new FileSystemWatcher(path); + watcher.Created += static (_, _) => Task.Run(Main.IndexUwpPrograms); + watcher.Deleted += static (_, _) => Task.Run(Main.IndexUwpPrograms); + watcher.EnableRaisingEvents = true; + } + + public static void WatchUWPInstallation() + { + PackageCatalog.OpenForCurrentUser().PackageStatusChanged += (_, _) => + { + Task.Delay(10000).ContinueWith(t => Main.IndexUwpPrograms()); + }; + } + public override string ToString() { return FamilyName; @@ -326,7 +355,7 @@ namespace Flow.Launcher.Plugin.Program.Programs e.SpecialKeyState.ShiftPressed && !e.SpecialKeyState.AltPressed && !e.SpecialKeyState.WinPressed - ); + ); if (elevated && CanRunElevated) { @@ -359,14 +388,12 @@ namespace Flow.Launcher.Plugin.Program.Programs new Result { Title = api.GetTranslation("flowlauncher_plugin_program_open_containing_folder"), - Action = _ => { Main.Context.API.OpenDirectory(Package.Location); return true; }, - IcoPath = "Images/folder.png" } }; @@ -415,8 +442,7 @@ namespace Flow.Launcher.Plugin.Program.Programs var info = new ProcessStartInfo(command) { - UseShellExecute = true, - Verb = "runas", + UseShellExecute = true, Verb = "runas", }; Main.StartProcess(Process.Start, info); @@ -493,7 +519,7 @@ namespace Flow.Launcher.Plugin.Program.Programs else { ProgramLogger.LogException($"|UWP|ResourceFromPri|{Package.Location}|Can't load null or empty result " - + $"pri {source} in uwp location {Package.Location}", new NullReferenceException()); + + $"pri {source} in uwp location {Package.Location}", new NullReferenceException()); return string.Empty; } } @@ -533,9 +559,15 @@ namespace Flow.Launcher.Plugin.Program.Programs { var logoKeyFromVersion = new Dictionary { - { PackageVersion.Windows10, "Square44x44Logo" }, - { PackageVersion.Windows81, "Square30x30Logo" }, - { PackageVersion.Windows8, "SmallLogo" }, + { + PackageVersion.Windows10, "Square44x44Logo" + }, + { + PackageVersion.Windows81, "Square30x30Logo" + }, + { + PackageVersion.Windows8, "SmallLogo" + }, }; if (logoKeyFromVersion.ContainsKey(Package.Version)) { @@ -572,14 +604,40 @@ namespace Flow.Launcher.Plugin.Program.Programs { var end = path.Length - extension.Length; var prefix = path.Substring(0, end); - var paths = new List { path }; + var paths = new List + { + path + }; var scaleFactors = new Dictionary> { // scale factors on win10: https://docs.microsoft.com/en-us/windows/uwp/controls-and-patterns/tiles-and-notifications-app-assets#asset-size-tables, - { PackageVersion.Windows10, new List { 100, 125, 150, 200, 400 } }, - { PackageVersion.Windows81, new List { 100, 120, 140, 160, 180 } }, - { PackageVersion.Windows8, new List { 100 } } + { + PackageVersion.Windows10, new List + { + 100, + 125, + 150, + 200, + 400 + } + }, + { + PackageVersion.Windows81, new List + { + 100, + 120, + 140, + 160, + 180 + } + }, + { + PackageVersion.Windows8, new List + { + 100 + } + } }; if (scaleFactors.ContainsKey(Package.Version)) @@ -598,15 +656,15 @@ namespace Flow.Launcher.Plugin.Program.Programs else { ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" + - $"|{UserModelId} can't find logo uri for {uri} in package location: {Package.Location}", new FileNotFoundException()); + $"|{UserModelId} can't find logo uri for {uri} in package location: {Package.Location}", new FileNotFoundException()); return string.Empty; } } else { ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" + - $"|Unable to find extension from {uri} for {UserModelId} " + - $"in package location {Package.Location}", new FileNotFoundException()); + $"|Unable to find extension from {uri} for {UserModelId} " + + $"in package location {Package.Location}", new FileNotFoundException()); return string.Empty; } } @@ -633,8 +691,8 @@ namespace Flow.Launcher.Plugin.Program.Programs else { ProgramLogger.LogException($"|UWP|ImageFromPath|{(string.IsNullOrEmpty(path) ? "Not Avaliable" : path)}" + - $"|Unable to get logo for {UserModelId} from {path} and" + - $" located in {Package.Location}", new FileNotFoundException()); + $"|Unable to get logo for {UserModelId} from {path} and" + + $" located in {Package.Location}", new FileNotFoundException()); return new BitmapImage(new Uri(Constant.MissingImgIcon)); } } @@ -682,8 +740,8 @@ namespace Flow.Launcher.Plugin.Program.Programs else { ProgramLogger.LogException($"|UWP|PlatedImage|{Package.Location}" + - $"|Unable to convert background string {BackgroundColor} " + - $"to color for {Package.Location}", new InvalidOperationException()); + $"|Unable to convert background string {BackgroundColor} " + + $"to color for {Package.Location}", new InvalidOperationException()); return new BitmapImage(new Uri(Constant.MissingImgIcon)); } @@ -701,6 +759,14 @@ namespace Flow.Launcher.Plugin.Program.Programs } } + public static void Dispose() + { + foreach (var fileSystemWatcher in _watchers) + { + fileSystemWatcher.Dispose(); + } + } + public enum PackageVersion { Windows10, @@ -728,5 +794,6 @@ namespace Flow.Launcher.Plugin.Program.Programs [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)] private static extern Hresult SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, uint cchOutBuf, IntPtr ppvReserved); + } } \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs index 1464bd785..3e568fa19 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs @@ -12,9 +12,11 @@ using Flow.Launcher.Plugin.Program.Logger; using Flow.Launcher.Plugin.SharedCommands; using Flow.Launcher.Plugin.SharedModels; using Flow.Launcher.Infrastructure.Logger; +using System.Collections; using System.Diagnostics; using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch; using System.Diagnostics.CodeAnalysis; +using System.Threading.Channels; namespace Flow.Launcher.Plugin.Program.Programs { @@ -109,7 +111,7 @@ namespace Flow.Launcher.Plugin.Program.Programs c.SpecialKeyState.ShiftPressed && !c.SpecialKeyState.AltPressed && !c.SpecialKeyState.WinPressed - ); + ); var info = new ProcessStartInfo { @@ -194,6 +196,9 @@ namespace Flow.Launcher.Plugin.Program.Programs return Name; } + public static List Watchers = new List(); + + private static Win32 Win32Program(string path) { try @@ -216,7 +221,10 @@ namespace Flow.Launcher.Plugin.Program.Programs ProgramLogger.LogException($"|Win32|Win32Program|{path}" + $"|Permission denied when trying to load the program from {path}", e); - return new Win32() { Valid = false, Enabled = false }; + return new Win32() + { + Valid = false, Enabled = false + }; } } @@ -294,7 +302,10 @@ namespace Flow.Launcher.Plugin.Program.Programs ProgramLogger.LogException($"|Win32|ExeProgram|{path}" + $"|Permission denied when trying to load the program from {path}", e); - return new Win32() { Valid = false, Enabled = false }; + return new Win32() + { + Valid = false, Enabled = false + }; } } @@ -305,8 +316,7 @@ namespace Flow.Launcher.Plugin.Program.Programs return Directory.EnumerateFiles(directory, "*", new EnumerationOptions { - IgnoreInaccessible = true, - RecurseSubdirectories = true + IgnoreInaccessible = true, RecurseSubdirectories = true }).Where(x => suffixes.Contains(Extension(x))); } @@ -545,5 +555,68 @@ namespace Flow.Launcher.Plugin.Program.Programs return UniqueIdentifier == other.UniqueIdentifier; } + + private static IEnumerable GetStartMenuPaths() + { + var directory1 = Environment.GetFolderPath(Environment.SpecialFolder.Programs); + var directory2 = Environment.GetFolderPath(Environment.SpecialFolder.CommonPrograms); + return new[] + { + directory1, directory2 + }; + } + + public static void WatchProgramUpdate(Settings settings) + { + var paths = new List(); + if (settings.EnableStartMenuSource) + paths.AddRange(GetStartMenuPaths()); + + paths.AddRange(from source in settings.ProgramSources where source.Enabled select source.Location); + + foreach (var directory in from path in paths where Directory.Exists(path) select path) + { + WatchDirectory(directory); + } + + _ = Task.Run(MonitorDirectoryChangeAsync); + } + + private static Channel indexQueue = Channel.CreateBounded(1); + + public static async Task MonitorDirectoryChangeAsync() + { + var reader = indexQueue.Reader; + while (await reader.WaitToReadAsync()) + { + await Task.Delay(500); + while (reader.TryRead(out _)) + { + } + Main.IndexWin32Programs(); + } + } + + public static void WatchDirectory(string directory) + { + if (!Directory.Exists(directory)) + { + throw new ArgumentException("Path Not Exist"); + } + var watcher = new FileSystemWatcher(directory); + + watcher.Created += static (_, _) => indexQueue.Writer.TryWrite(default); + watcher.Deleted += static (_, _) => indexQueue.Writer.TryWrite(default); + watcher.EnableRaisingEvents = true; + watcher.IncludeSubdirectories = true; + } + + public static void Dispose() + { + foreach (var fileSystemWatcher in Watchers) + { + fileSystemWatcher.Dispose(); + } + } } } \ No newline at end of file From 9fc0e03b3dd010bf324009f42646438fb9149978 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sat, 8 Jan 2022 16:03:53 -0600 Subject: [PATCH 02/13] detect windows version --- Plugins/Flow.Launcher.Plugin.Program/Main.cs | 2 +- Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs index cb0a2a4f3..3f89d63d3 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs @@ -128,7 +128,7 @@ namespace Flow.Launcher.Plugin.Program await indexTask; Win32.WatchProgramUpdate(_settings); - UWP.WatchUWPInstallation(); + UWP.WatchPackageChange(); } public static void IndexWin32Programs() diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs index b3d39bdbc..86f5f38c4 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs @@ -18,6 +18,7 @@ using Flow.Launcher.Plugin.Program.Logger; using Rect = System.Windows.Rect; using Flow.Launcher.Plugin.SharedModels; using Flow.Launcher.Infrastructure.Logger; +using System.Runtime.Versioning; namespace Flow.Launcher.Plugin.Program.Programs { @@ -251,12 +252,13 @@ namespace Flow.Launcher.Plugin.Program.Programs watcher.EnableRaisingEvents = true; } - public static void WatchUWPInstallation() + public static void WatchPackageChange() { - PackageCatalog.OpenForCurrentUser().PackageStatusChanged += (_, _) => - { - Task.Delay(10000).ContinueWith(t => Main.IndexUwpPrograms()); - }; + if (Environment.OSVersion.Version.Build >= 19041) + PackageCatalog.OpenForCurrentUser().PackageStatusChanged += (_, _) => + { + Task.Delay(10000).ContinueWith(t => Main.IndexUwpPrograms()); + }; } public override string ToString() From 50144ea8f45133d40d3eacb0fd4baf9f19309867 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sat, 8 Jan 2022 16:31:28 -0600 Subject: [PATCH 03/13] Remove firefox bookmark with no title --- .../FirefoxBookmarkLoader.cs | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs index 3df034781..4d5135b30 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs @@ -9,10 +9,10 @@ namespace Flow.Launcher.Plugin.BrowserBookmark { public class FirefoxBookmarkLoader : IBookmarkLoader { - private const string queryAllBookmarks = @"SELECT moz_places.url, moz_bookmarks.title + private const string QueryAllBookmarks = @"SELECT moz_places.url, moz_bookmarks.title FROM moz_places INNER JOIN moz_bookmarks ON ( - moz_bookmarks.fk NOT NULL AND moz_bookmarks.fk = moz_places.id + moz_bookmarks.fk NOT NULL AND moz_bookmarks.title NOT NULL AND moz_bookmarks.fk = moz_places.id ) ORDER BY moz_places.visit_count DESC "; @@ -32,18 +32,16 @@ namespace Flow.Launcher.Plugin.BrowserBookmark // create the connection string and init the connection string dbPath = string.Format(dbPathFormat, PlacesPath); - using (var dbConnection = new SQLiteConnection(dbPath)) - { - // Open connection to the database file and execute the query - dbConnection.Open(); - var reader = new SQLiteCommand(queryAllBookmarks, dbConnection).ExecuteReader(); + using var dbConnection = new SQLiteConnection(dbPath); + // Open connection to the database file and execute the query + dbConnection.Open(); + var reader = new SQLiteCommand(QueryAllBookmarks, dbConnection).ExecuteReader(); - // return results in List format - bookmarkList = reader.Select( - x => new Bookmark(x["title"] is DBNull ? string.Empty : x["title"].ToString(), - x["url"].ToString()) - ).ToList(); - } + // return results in List format + bookmarkList = reader.Select( + x => new Bookmark(x["title"] is DBNull ? string.Empty : x["title"].ToString(), + x["url"].ToString()) + ).ToList(); return bookmarkList; } From af68cb5093b38c15b39e69cc1cdeebaa4173cd04 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sat, 8 Jan 2022 16:58:12 -0600 Subject: [PATCH 04/13] detect browserbookmark file change --- .../ChromiumBookmarkLoader.cs | 5 ++ .../Commands/BookmarkLoader.cs | 5 ++ .../FirefoxBookmarkLoader.cs | 2 + .../Main.cs | 88 +++++++++++++++++-- 4 files changed, 91 insertions(+), 9 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs index d7b412392..c32f60af3 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs @@ -20,6 +20,8 @@ namespace Flow.Launcher.Plugin.BrowserBookmark var bookmarkPath = Path.Combine(profile, "Bookmarks"); if (!File.Exists(bookmarkPath)) continue; + + Main.RegisterBookmarkFile(bookmarkPath); var source = name + (Path.GetFileName(profile) == "Default" ? "" : $" ({Path.GetFileName(profile)})"); bookmarks.AddRange(LoadBookmarksFromFile(bookmarkPath, source)); @@ -31,6 +33,9 @@ namespace Flow.Launcher.Plugin.BrowserBookmark { if (!File.Exists(path)) return new(); + + Main.RegisterBookmarkFile(path); + var bookmarks = new List(); using var jsonDocument = JsonDocument.Parse(File.ReadAllText(path)); if (!jsonDocument.RootElement.TryGetProperty("roots", out var rootElement)) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs index 40d10b26f..491c5c915 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs @@ -3,6 +3,10 @@ using System.Linq; using Flow.Launcher.Infrastructure; using Flow.Launcher.Plugin.BrowserBookmark.Models; using Flow.Launcher.Plugin.SharedModels; +using Microsoft.AspNetCore.Authentication; +using System.IO; +using System.Threading.Channels; +using System.Threading.Tasks; namespace Flow.Launcher.Plugin.BrowserBookmark.Commands { @@ -17,6 +21,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Commands return StringMatcher.FuzzySearch(queryString, bookmark.Url); } + internal static List LoadAllBookmarks(Settings setting) { diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs index 4d5135b30..9d29b9c41 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs @@ -29,6 +29,8 @@ namespace Flow.Launcher.Plugin.BrowserBookmark return new List(); var bookmarkList = new List(); + + Main.RegisterBookmarkFile(PlacesPath); // create the connection string and init the connection string dbPath = string.Format(dbPathFormat, PlacesPath); diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs index 1d58f84d8..f9127cd3c 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Main.cs @@ -9,24 +9,29 @@ using Flow.Launcher.Plugin.BrowserBookmark.Commands; using Flow.Launcher.Plugin.BrowserBookmark.Models; using Flow.Launcher.Plugin.BrowserBookmark.Views; using Flow.Launcher.Plugin.SharedCommands; +using System.IO; +using System.Threading.Channels; +using System.Threading.Tasks; namespace Flow.Launcher.Plugin.BrowserBookmark { - public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContextMenu + public class Main : ISettingProvider, IPlugin, IReloadable, IPluginI18n, IContextMenu, IDisposable { private PluginInitContext context; private List cachedBookmarks = new List(); - private Settings _settings { get; set;} + private Settings _settings { get; set; } public void Init(PluginInitContext context) { this.context = context; - + _settings = context.API.LoadSettingJsonStorage(); cachedBookmarks = BookmarkLoader.LoadAllBookmarks(_settings); + + _ = MonitorRefreshQueue(); } public List Query(Query query) @@ -52,7 +57,10 @@ namespace Flow.Launcher.Plugin.BrowserBookmark return true; }, - ContextData = new BookmarkAttributes { Url = c.Url } + ContextData = new BookmarkAttributes + { + Url = c.Url + } }).Where(r => r.Score > 0); return returnList.ToList(); } @@ -69,11 +77,64 @@ namespace Flow.Launcher.Plugin.BrowserBookmark context.API.OpenUrl(c.Url); return true; }, - ContextData = new BookmarkAttributes { Url = c.Url } + ContextData = new BookmarkAttributes + { + Url = c.Url + } }).ToList(); } } + + private static Channel refreshQueue = Channel.CreateBounded(1); + + private async Task MonitorRefreshQueue() + { + var reader = refreshQueue.Reader; + while (await reader.WaitToReadAsync()) + { + await Task.Delay(2000); + if (reader.TryRead(out _)) + { + ReloadData(); + } + } + } + + private static readonly List Watchers = new(); + + internal static void RegisterBookmarkFile(string path) + { + var directory = Path.GetDirectoryName(path); + if (!Directory.Exists(directory)) + return; + var watcher = new FileSystemWatcher(directory!); + if (File.Exists(path)) + { + var fileName = Path.GetFileName(path); + watcher.Filter = fileName; + } + + watcher.NotifyFilter = NotifyFilters.FileName | + NotifyFilters.LastAccess | + NotifyFilters.LastWrite | + NotifyFilters.Size; + + watcher.Changed += static (_, _) => + { + refreshQueue.Writer.TryWrite(default); + }; + + watcher.Renamed += static (_, _) => + { + refreshQueue.Writer.TryWrite(default); + }; + + watcher.EnableRaisingEvents = true; + + Watchers.Add(watcher); + } + public void ReloadData() { cachedBookmarks.Clear(); @@ -98,7 +159,8 @@ namespace Flow.Launcher.Plugin.BrowserBookmark public List LoadContextMenus(Result selectedResult) { - return new List() { + return new List() + { new Result { Title = context.API.GetTranslation("flowlauncher_plugin_browserbookmark_copyurl_title"), @@ -114,7 +176,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark catch (Exception e) { var message = "Failed to set url in clipboard"; - Log.Exception("Main",message, e, "LoadContextMenus"); + Log.Exception("Main", message, e, "LoadContextMenus"); context.API.ShowMsg(message); @@ -122,12 +184,20 @@ namespace Flow.Launcher.Plugin.BrowserBookmark } }, IcoPath = "Images\\copylink.png" - }}; + } + }; } internal class BookmarkAttributes { internal string Url { get; set; } } + public void Dispose() + { + foreach (var watcher in Watchers) + { + watcher.Dispose(); + } + } } -} +} \ No newline at end of file From f42fd29224623a187476a8e59c42e71602ea16f7 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Thu, 27 Jan 2022 20:14:42 +1100 Subject: [PATCH 05/13] formatting --- .../Commands/BookmarkLoader.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs index 491c5c915..284255498 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs @@ -21,7 +21,6 @@ namespace Flow.Launcher.Plugin.BrowserBookmark.Commands return StringMatcher.FuzzySearch(queryString, bookmark.Url); } - internal static List LoadAllBookmarks(Settings setting) { From 0842091f266664854f2f7ce5c84b286307873de6 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Thu, 27 Jan 2022 20:22:01 +1100 Subject: [PATCH 06/13] formatting --- Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs index 86f5f38c4..4094d8589 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs @@ -90,9 +90,6 @@ namespace Flow.Launcher.Plugin.Program.Programs } } - - - /// http://www.hanselman.com/blog/GetNamespacesFromAnXMLDocumentWithXPathDocumentAndLINQToXML.aspx private string[] XmlNamespaces(string path) { From 25cc50b9ac29f475ba56cb5205d518845b18432d Mon Sep 17 00:00:00 2001 From: Jeremy Date: Thu, 27 Jan 2022 20:52:47 +1100 Subject: [PATCH 07/13] version bump Program & BrowserBookmark plugins --- Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json | 2 +- Plugins/Flow.Launcher.Plugin.Program/plugin.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json index afc4f9855..b93630c31 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/plugin.json @@ -4,7 +4,7 @@ "Name": "Browser Bookmarks", "Description": "Search your browser bookmarks", "Author": "qianlifeng, Ioannis G.", - "Version": "1.6.3", + "Version": "1.7.0", "Language": "csharp", "Website": "https://github.com/Flow-Launcher/Flow.Launcher", "ExecuteFileName": "Flow.Launcher.Plugin.BrowserBookmark.dll", diff --git a/Plugins/Flow.Launcher.Plugin.Program/plugin.json b/Plugins/Flow.Launcher.Plugin.Program/plugin.json index 993b2adba..a297cb410 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/plugin.json +++ b/Plugins/Flow.Launcher.Plugin.Program/plugin.json @@ -4,7 +4,7 @@ "Name": "Program", "Description": "Search programs in Flow.Launcher", "Author": "qianlifeng", - "Version": "1.8.2", + "Version": "1.9.0", "Language": "csharp", "Website": "https://github.com/Flow-Launcher/Flow.Launcher", "ExecuteFileName": "Flow.Launcher.Plugin.Program.dll", From 18acea332159e95859868badd555c3fcac430166 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Mon, 7 Feb 2022 08:47:28 +1100 Subject: [PATCH 08/13] remove dup RegisterBookmarkFile & update condition --- .../ChromiumBookmarkLoader.cs | 2 -- .../Commands/BookmarkLoader.cs | 4 ---- .../FirefoxBookmarkLoader.cs | 4 ++-- Plugins/Flow.Launcher.Plugin.Program/Main.cs | 4 ++-- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs index c32f60af3..a49f8cb94 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs @@ -34,8 +34,6 @@ namespace Flow.Launcher.Plugin.BrowserBookmark if (!File.Exists(path)) return new(); - Main.RegisterBookmarkFile(path); - var bookmarks = new List(); using var jsonDocument = JsonDocument.Parse(File.ReadAllText(path)); if (!jsonDocument.RootElement.TryGetProperty("roots", out var rootElement)) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs index 284255498..40d10b26f 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/BookmarkLoader.cs @@ -3,10 +3,6 @@ using System.Linq; using Flow.Launcher.Infrastructure; using Flow.Launcher.Plugin.BrowserBookmark.Models; using Flow.Launcher.Plugin.SharedModels; -using Microsoft.AspNetCore.Authentication; -using System.IO; -using System.Threading.Channels; -using System.Threading.Tasks; namespace Flow.Launcher.Plugin.BrowserBookmark.Commands { diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs index 9d29b9c41..892e18ddd 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/FirefoxBookmarkLoader.cs @@ -9,7 +9,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark { public class FirefoxBookmarkLoader : IBookmarkLoader { - private const string QueryAllBookmarks = @"SELECT moz_places.url, moz_bookmarks.title + private const string queryAllBookmarks = @"SELECT moz_places.url, moz_bookmarks.title FROM moz_places INNER JOIN moz_bookmarks ON ( moz_bookmarks.fk NOT NULL AND moz_bookmarks.title NOT NULL AND moz_bookmarks.fk = moz_places.id @@ -37,7 +37,7 @@ namespace Flow.Launcher.Plugin.BrowserBookmark using var dbConnection = new SQLiteConnection(dbPath); // Open connection to the database file and execute the query dbConnection.Open(); - var reader = new SQLiteCommand(QueryAllBookmarks, dbConnection).ExecuteReader(); + var reader = new SQLiteCommand(queryAllBookmarks, dbConnection).ExecuteReader(); // return results in List format bookmarkList = reader.Select( diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs index 3f89d63d3..cf5d68a18 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs @@ -212,11 +212,11 @@ namespace Flow.Launcher.Plugin.Program return; if (_uwps.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier)) - _uwps.FirstOrDefault(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier)! + _uwps.FirstOrDefault(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier) .Enabled = false; if (_win32s.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier)) - _win32s.FirstOrDefault(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier)! + _win32s.FirstOrDefault(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier) .Enabled = false; _settings.DisabledProgramSources From 823fa38dcdcc273390162eb051c559e06918dc78 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sun, 6 Feb 2022 17:27:12 -0600 Subject: [PATCH 09/13] Remove unused method --- Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs index 4094d8589..e4ce7ddb4 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs @@ -241,14 +241,6 @@ namespace Flow.Launcher.Plugin.Program.Programs private static List _watchers = new(); - private static void GenerateWatcher(string path) - { - var watcher = new FileSystemWatcher(path); - watcher.Created += static (_, _) => Task.Run(Main.IndexUwpPrograms); - watcher.Deleted += static (_, _) => Task.Run(Main.IndexUwpPrograms); - watcher.EnableRaisingEvents = true; - } - public static void WatchPackageChange() { if (Environment.OSVersion.Version.Build >= 19041) From 87e7ff5b5386c3183bee169f21f0c99d661b1e6c Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Sun, 6 Feb 2022 17:34:50 -0600 Subject: [PATCH 10/13] Remove unneeded logic and add a background reindex at startup --- Plugins/Flow.Launcher.Plugin.Program/Main.cs | 75 ++++++++------------ 1 file changed, 29 insertions(+), 46 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs index cf5d68a18..5975b989a 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs @@ -24,7 +24,6 @@ namespace Flow.Launcher.Plugin.Program internal static UWP.Application[] _uwps { get; set; } internal static Settings _settings { get; set; } - private static bool IsStartupIndexProgramsRequired => _settings.LastIndexTime.AddDays(3) < DateTime.Today; internal static PluginInitContext Context { get; private set; } @@ -51,29 +50,25 @@ namespace Flow.Launcher.Plugin.Program public async Task> QueryAsync(Query query, CancellationToken token) { - - if (IsStartupIndexProgramsRequired) - _ = IndexPrograms(); - var result = await cache.GetOrCreateAsync(query.Search, async entry => - { - var resultList = await Task.Run(() => - _win32s.Cast() - .Concat(_uwps) - .AsParallel() - .WithCancellation(token) - .Where(p => p.Enabled) - .Select(p => p.Result(query.Search, Context.API)) - .Where(r => r?.Score > 0) - .ToList()); + { + var resultList = await Task.Run(() => + _win32s.Cast() + .Concat(_uwps) + .AsParallel() + .WithCancellation(token) + .Where(p => p.Enabled) + .Select(p => p.Result(query.Search, Context.API)) + .Where(r => r?.Score > 0) + .ToList()); - resultList = resultList.Any() ? resultList : emptyResults; + resultList = resultList.Any() ? resultList : emptyResults; - entry.SetSize(resultList.Count); - entry.SetSlidingExpiration(TimeSpan.FromHours(8)); + entry.SetSize(resultList.Count); + entry.SetSlidingExpiration(TimeSpan.FromHours(8)); - return resultList; - }); + return resultList; + }); return result; } @@ -84,49 +79,35 @@ namespace Flow.Launcher.Plugin.Program _settings = context.API.LoadSettingJsonStorage(); - await Task.Yield(); - Stopwatch.Normal("|Flow.Launcher.Plugin.Program.Main|Preload programs cost", () => { _win32Storage = new BinaryStorage("Win32"); - _win32s = _win32Storage.TryLoad(new Win32[] { }); + _win32s = _win32Storage.TryLoad(new Win32[] + { + }); _uwpStorage = new BinaryStorage("UWP"); - _uwps = _uwpStorage.TryLoad(new UWP.Application[] { }); + _uwps = _uwpStorage.TryLoad(new UWP.Application[] + { + }); }); Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload win32 programs <{_win32s.Length}>"); Log.Info($"|Flow.Launcher.Plugin.Program.Main|Number of preload uwps <{_uwps.Length}>"); - - bool indexedWinApps = false; - bool indexedUWPApps = false; + bool cacheEmpty = !_win32s.Any() && !_uwps.Any(); var a = Task.Run(() => { - if (IsStartupIndexProgramsRequired || !_win32s.Any()) - { - Stopwatch.Normal("|Flow.Launcher.Plugin.Program.Main|Win32Program index cost", IndexWin32Programs); - indexedWinApps = true; - } + Stopwatch.Normal("|Flow.Launcher.Plugin.Program.Main|Win32Program index cost", IndexWin32Programs); }); var b = Task.Run(() => { - if (IsStartupIndexProgramsRequired || !_uwps.Any()) - { - Stopwatch.Normal("|Flow.Launcher.Plugin.Program.Main|Win32Program index cost", IndexUwpPrograms); - indexedUWPApps = true; - } + Stopwatch.Normal("|Flow.Launcher.Plugin.Program.Main|Win32Program index cost", IndexUwpPrograms); }); - var indexTask = Task.WhenAll(a, b).ContinueWith(t => - { - if (indexedWinApps && indexedUWPApps) - _settings.LastIndexTime = DateTime.Today; - }); + if (cacheEmpty) + await Task.WhenAll(a, b); - if (!(_win32s.Any() && _uwps.Any())) - await indexTask; - Win32.WatchProgramUpdate(_settings); UWP.WatchPackageChange(); } @@ -141,7 +122,9 @@ namespace Flow.Launcher.Plugin.Program { var windows10 = new Version(10, 0); var support = Environment.OSVersion.Version.Major >= windows10.Major; - var applications = support ? UWP.All() : new UWP.Application[] { }; + var applications = support ? UWP.All() : new UWP.Application[] + { + }; _uwps = applications; } From 80eb0e494320f4a73dc7bc37dc050024d9a40721 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Mon, 21 Feb 2022 15:54:46 -0600 Subject: [PATCH 11/13] Reset Cache and rewrite uwp detection logic --- Plugins/Flow.Launcher.Plugin.Program/Main.cs | 4 +- .../Programs/UWP.cs | 47 +++++++++++++------ 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs index 5975b989a..e634f5fe7 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs @@ -116,6 +116,7 @@ namespace Flow.Launcher.Plugin.Program { var win32S = Win32.All(_settings); _win32s = win32S; + ResetCache(); } public static void IndexUwpPrograms() @@ -126,6 +127,7 @@ namespace Flow.Launcher.Plugin.Program { }; _uwps = applications; + ResetCache(); } public static async Task IndexPrograms() @@ -133,7 +135,6 @@ namespace Flow.Launcher.Plugin.Program var t1 = Task.Run(IndexWin32Programs); var t2 = Task.Run(IndexUwpPrograms); await Task.WhenAll(t1, t2).ConfigureAwait(false); - ResetCache(); _settings.LastIndexTime = DateTime.Today; } @@ -235,7 +236,6 @@ namespace Flow.Launcher.Plugin.Program public void Dispose() { Win32.Dispose(); - UWP.Dispose(); } } } \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs index e4ce7ddb4..c843815ac 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs @@ -19,6 +19,7 @@ using Rect = System.Windows.Rect; using Flow.Launcher.Plugin.SharedModels; using Flow.Launcher.Infrastructure.Logger; using System.Runtime.Versioning; +using System.Threading.Channels; namespace Flow.Launcher.Plugin.Program.Programs { @@ -163,8 +164,10 @@ namespace Flow.Launcher.Plugin.Program.Programs catch (Exception e) { ProgramLogger.LogException($"|UWP|All|{p.InstalledLocation}|An unexpected error occured and " - + $"unable to convert Package to UWP for {p.Id.FullName}", e); - return new Application[] { }; + + $"unable to convert Package to UWP for {p.Id.FullName}", e); + return new Application[] + { + }; } #endif #if DEBUG //make developer aware and implement handling @@ -239,15 +242,37 @@ namespace Flow.Launcher.Plugin.Program.Programs } } - private static List _watchers = new(); + private static Channel PackageChangeChannel = Channel.CreateBounded(1); - public static void WatchPackageChange() + public static async Task WatchPackageChange() { - if (Environment.OSVersion.Version.Build >= 19041) - PackageCatalog.OpenForCurrentUser().PackageStatusChanged += (_, _) => + if (Environment.OSVersion.Version.Major >= 10) + { + var catalog = PackageCatalog.OpenForCurrentUser(); + catalog.PackageInstalling += (_, args) => { - Task.Delay(10000).ContinueWith(t => Main.IndexUwpPrograms()); + if (args.IsComplete) + PackageChangeChannel.Writer.TryWrite(default); }; + catalog.PackageUninstalling += (_, args) => + { + if (args.IsComplete) + PackageChangeChannel.Writer.TryWrite(default); + }; + catalog.PackageUpdating += (_, args) => + { + if (args.IsComplete) + PackageChangeChannel.Writer.TryWrite(default); + }; + + while (await PackageChangeChannel.Reader.WaitToReadAsync().ConfigureAwait(false)) + { + await Task.Delay(3000).ConfigureAwait(false); + PackageChangeChannel.Reader.TryRead(out _); + await Task.Run(Main.IndexUwpPrograms); + } + + } } public override string ToString() @@ -750,14 +775,6 @@ namespace Flow.Launcher.Plugin.Program.Programs } } - public static void Dispose() - { - foreach (var fileSystemWatcher in _watchers) - { - fileSystemWatcher.Dispose(); - } - } - public enum PackageVersion { Windows10, From ef4bb121f9f925a1d2d3b039e505686c136684c6 Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 23 Feb 2022 18:19:34 -0600 Subject: [PATCH 12/13] Add FileSystemWatcher to Watcherlist --- Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs index 3e568fa19..c3b0900a7 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs @@ -609,6 +609,8 @@ namespace Flow.Launcher.Plugin.Program.Programs watcher.Deleted += static (_, _) => indexQueue.Writer.TryWrite(default); watcher.EnableRaisingEvents = true; watcher.IncludeSubdirectories = true; + + Watchers.Add(watcher); } public static void Dispose() From 5404303c5f62ced6b8e854d24c060d6a6af2bc8a Mon Sep 17 00:00:00 2001 From: Hongtao Zhang Date: Wed, 23 Feb 2022 18:21:13 -0600 Subject: [PATCH 13/13] Wrap IndexWin32Programs with Task.Run --- Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs index c3b0900a7..2f3ea47d0 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs @@ -593,7 +593,7 @@ namespace Flow.Launcher.Plugin.Program.Programs while (reader.TryRead(out _)) { } - Main.IndexWin32Programs(); + await Task.Run(Main.IndexWin32Programs); } }