Skip to content

Commit 7305653

Browse files
committed
Reindex when app install or deleted (and uwp update).
1 parent 78f3008 commit 7305653

File tree

3 files changed

+198
-52
lines changed

3 files changed

+198
-52
lines changed

Plugins/Flow.Launcher.Plugin.Program/Main.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
namespace Flow.Launcher.Plugin.Program
2020
{
21-
public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, ISavable, IAsyncReloadable
21+
public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, ISavable, IAsyncReloadable, IDisposable
2222
{
2323
internal static Win32[] _win32s { get; set; }
2424
internal static UWP.Application[] _uwps { get; set; }
@@ -126,6 +126,9 @@ public async Task InitAsync(PluginInitContext context)
126126

127127
if (!(_win32s.Any() && _uwps.Any()))
128128
await indexTask;
129+
130+
Win32.WatchProgramUpdate(_settings);
131+
UWP.WatchUWPInstallation();
129132
}
130133

131134
public static void IndexWin32Programs()
@@ -209,13 +212,11 @@ private void DisableProgram(IProgram programToDelete)
209212
return;
210213

211214
if (_uwps.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
212-
_uwps.Where(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier)
213-
.FirstOrDefault()
215+
_uwps.FirstOrDefault(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier)!
214216
.Enabled = false;
215217

216218
if (_win32s.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
217-
_win32s.Where(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier)
218-
.FirstOrDefault()
219+
_win32s.FirstOrDefault(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier)!
219220
.Enabled = false;
220221

221222
_settings.DisabledProgramSources
@@ -248,5 +249,10 @@ public async Task ReloadDataAsync()
248249
{
249250
await IndexPrograms();
250251
}
252+
public void Dispose()
253+
{
254+
Win32.Dispose();
255+
UWP.Dispose();
256+
}
251257
}
252258
}

Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs

Lines changed: 109 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ private void InitializeAppInfo()
7878
{
7979
var e = Marshal.GetExceptionForHR((int)hResult);
8080
ProgramLogger.LogException($"|UWP|InitializeAppInfo|{path}" +
81-
"|Error caused while trying to get the details of the UWP program", e);
81+
"|Error caused while trying to get the details of the UWP program", e);
8282

8383
Apps = new List<Application>().ToArray();
8484
}
@@ -91,38 +91,45 @@ private void InitializeAppInfo()
9191

9292

9393

94+
9495
/// http://www.hanselman.com/blog/GetNamespacesFromAnXMLDocumentWithXPathDocumentAndLINQToXML.aspx
9596
private string[] XmlNamespaces(string path)
9697
{
9798
XDocument z = XDocument.Load(path);
9899
if (z.Root != null)
99100
{
100-
var namespaces = z.Root.Attributes().
101-
Where(a => a.IsNamespaceDeclaration).
102-
GroupBy(
103-
a => a.Name.Namespace == XNamespace.None ? string.Empty : a.Name.LocalName,
104-
a => XNamespace.Get(a.Value)
105-
).Select(
106-
g => g.First().ToString()
107-
).ToArray();
101+
var namespaces = z.Root.Attributes().Where(a => a.IsNamespaceDeclaration).GroupBy(
102+
a => a.Name.Namespace == XNamespace.None ? string.Empty : a.Name.LocalName,
103+
a => XNamespace.Get(a.Value)
104+
).Select(
105+
g => g.First().ToString()
106+
).ToArray();
108107
return namespaces;
109108
}
110109
else
111110
{
112111
ProgramLogger.LogException($"|UWP|XmlNamespaces|{path}" +
113-
$"|Error occured while trying to get the XML from {path}", new ArgumentNullException());
112+
$"|Error occured while trying to get the XML from {path}", new ArgumentNullException());
114113

115-
return new string[] { };
114+
return new string[]
115+
{
116+
};
116117
}
117118
}
118119

119120
private void InitPackageVersion(string[] namespaces)
120121
{
121122
var versionFromNamespace = new Dictionary<string, PackageVersion>
122123
{
123-
{"http://schemas.microsoft.com/appx/manifest/foundation/windows10", PackageVersion.Windows10},
124-
{"http://schemas.microsoft.com/appx/2013/manifest", PackageVersion.Windows81},
125-
{"http://schemas.microsoft.com/appx/2010/manifest", PackageVersion.Windows8},
124+
{
125+
"http://schemas.microsoft.com/appx/manifest/foundation/windows10", PackageVersion.Windows10
126+
},
127+
{
128+
"http://schemas.microsoft.com/appx/2013/manifest", PackageVersion.Windows81
129+
},
130+
{
131+
"http://schemas.microsoft.com/appx/2010/manifest", PackageVersion.Windows8
132+
},
126133
};
127134

128135
foreach (var n in versionFromNamespace.Keys)
@@ -135,8 +142,8 @@ private void InitPackageVersion(string[] namespaces)
135142
}
136143

137144
ProgramLogger.LogException($"|UWP|XmlNamespaces|{Location}" +
138-
"|Trying to get the package version of the UWP program, but a unknown UWP appmanifest version "
139-
+ $"{FullName} from location {Location} is returned.", new FormatException());
145+
"|Trying to get the package version of the UWP program, but a unknown UWP appmanifest version "
146+
+ $"{FullName} from location {Location} is returned.", new FormatException());
140147

141148
Version = PackageVersion.Unknown;
142149
}
@@ -172,15 +179,17 @@ public static Application[] All()
172179
}).ToArray();
173180

174181
var updatedListWithoutDisabledApps = applications
175-
.Where(t1 => !Main._settings.DisabledProgramSources
176-
.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier))
177-
.Select(x => x);
182+
.Where(t1 => !Main._settings.DisabledProgramSources
183+
.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier))
184+
.Select(x => x);
178185

179186
return updatedListWithoutDisabledApps.ToArray();
180187
}
181188
else
182189
{
183-
return new Application[] { };
190+
return new Application[]
191+
{
192+
};
184193
}
185194
}
186195

@@ -216,7 +225,7 @@ private static IEnumerable<Package> CurrentUserPackages()
216225
catch (Exception e)
217226
{
218227
ProgramLogger.LogException("UWP", "CurrentUserPackages", $"id", "An unexpected error occured and "
219-
+ $"unable to verify if package is valid", e);
228+
+ $"unable to verify if package is valid", e);
220229
return false;
221230
}
222231

@@ -226,10 +235,30 @@ private static IEnumerable<Package> CurrentUserPackages()
226235
}
227236
else
228237
{
229-
return new Package[] { };
238+
return new Package[]
239+
{
240+
};
230241
}
231242
}
232243

244+
private static List<FileSystemWatcher> _watchers = new();
245+
246+
private static void GenerateWatcher(string path)
247+
{
248+
var watcher = new FileSystemWatcher(path);
249+
watcher.Created += static (_, _) => Task.Run(Main.IndexUwpPrograms);
250+
watcher.Deleted += static (_, _) => Task.Run(Main.IndexUwpPrograms);
251+
watcher.EnableRaisingEvents = true;
252+
}
253+
254+
public static void WatchUWPInstallation()
255+
{
256+
PackageCatalog.OpenForCurrentUser().PackageStatusChanged += (_, _) =>
257+
{
258+
Task.Delay(10000).ContinueWith(t => Main.IndexUwpPrograms());
259+
};
260+
}
261+
233262
public override string ToString()
234263
{
235264
return FamilyName;
@@ -326,7 +355,7 @@ public Result Result(string query, IPublicAPI api)
326355
e.SpecialKeyState.ShiftPressed &&
327356
!e.SpecialKeyState.AltPressed &&
328357
!e.SpecialKeyState.WinPressed
329-
);
358+
);
330359

331360
if (elevated && CanRunElevated)
332361
{
@@ -359,14 +388,12 @@ public List<Result> ContextMenus(IPublicAPI api)
359388
new Result
360389
{
361390
Title = api.GetTranslation("flowlauncher_plugin_program_open_containing_folder"),
362-
363391
Action = _ =>
364392
{
365393
Main.Context.API.OpenDirectory(Package.Location);
366394

367395
return true;
368396
},
369-
370397
IcoPath = "Images/folder.png"
371398
}
372399
};
@@ -415,8 +442,7 @@ private async void LaunchElevated()
415442

416443
var info = new ProcessStartInfo(command)
417444
{
418-
UseShellExecute = true,
419-
Verb = "runas",
445+
UseShellExecute = true, Verb = "runas",
420446
};
421447

422448
Main.StartProcess(Process.Start, info);
@@ -493,7 +519,7 @@ internal string ResourceFromPri(string packageFullName, string packageName, stri
493519
else
494520
{
495521
ProgramLogger.LogException($"|UWP|ResourceFromPri|{Package.Location}|Can't load null or empty result "
496-
+ $"pri {source} in uwp location {Package.Location}", new NullReferenceException());
522+
+ $"pri {source} in uwp location {Package.Location}", new NullReferenceException());
497523
return string.Empty;
498524
}
499525
}
@@ -533,9 +559,15 @@ internal string LogoUriFromManifest(AppxPackageHelper.IAppxManifestApplication a
533559
{
534560
var logoKeyFromVersion = new Dictionary<PackageVersion, string>
535561
{
536-
{ PackageVersion.Windows10, "Square44x44Logo" },
537-
{ PackageVersion.Windows81, "Square30x30Logo" },
538-
{ PackageVersion.Windows8, "SmallLogo" },
562+
{
563+
PackageVersion.Windows10, "Square44x44Logo"
564+
},
565+
{
566+
PackageVersion.Windows81, "Square30x30Logo"
567+
},
568+
{
569+
PackageVersion.Windows8, "SmallLogo"
570+
},
539571
};
540572
if (logoKeyFromVersion.ContainsKey(Package.Version))
541573
{
@@ -572,14 +604,40 @@ internal string LogoPathFromUri(string uri)
572604
{
573605
var end = path.Length - extension.Length;
574606
var prefix = path.Substring(0, end);
575-
var paths = new List<string> { path };
607+
var paths = new List<string>
608+
{
609+
path
610+
};
576611

577612
var scaleFactors = new Dictionary<PackageVersion, List<int>>
578613
{
579614
// scale factors on win10: https://docs.microsoft.com/en-us/windows/uwp/controls-and-patterns/tiles-and-notifications-app-assets#asset-size-tables,
580-
{ PackageVersion.Windows10, new List<int> { 100, 125, 150, 200, 400 } },
581-
{ PackageVersion.Windows81, new List<int> { 100, 120, 140, 160, 180 } },
582-
{ PackageVersion.Windows8, new List<int> { 100 } }
615+
{
616+
PackageVersion.Windows10, new List<int>
617+
{
618+
100,
619+
125,
620+
150,
621+
200,
622+
400
623+
}
624+
},
625+
{
626+
PackageVersion.Windows81, new List<int>
627+
{
628+
100,
629+
120,
630+
140,
631+
160,
632+
180
633+
}
634+
},
635+
{
636+
PackageVersion.Windows8, new List<int>
637+
{
638+
100
639+
}
640+
}
583641
};
584642

585643
if (scaleFactors.ContainsKey(Package.Version))
@@ -598,15 +656,15 @@ internal string LogoPathFromUri(string uri)
598656
else
599657
{
600658
ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" +
601-
$"|{UserModelId} can't find logo uri for {uri} in package location: {Package.Location}", new FileNotFoundException());
659+
$"|{UserModelId} can't find logo uri for {uri} in package location: {Package.Location}", new FileNotFoundException());
602660
return string.Empty;
603661
}
604662
}
605663
else
606664
{
607665
ProgramLogger.LogException($"|UWP|LogoPathFromUri|{Package.Location}" +
608-
$"|Unable to find extension from {uri} for {UserModelId} " +
609-
$"in package location {Package.Location}", new FileNotFoundException());
666+
$"|Unable to find extension from {uri} for {UserModelId} " +
667+
$"in package location {Package.Location}", new FileNotFoundException());
610668
return string.Empty;
611669
}
612670
}
@@ -633,8 +691,8 @@ private BitmapImage ImageFromPath(string path)
633691
else
634692
{
635693
ProgramLogger.LogException($"|UWP|ImageFromPath|{(string.IsNullOrEmpty(path) ? "Not Avaliable" : path)}" +
636-
$"|Unable to get logo for {UserModelId} from {path} and" +
637-
$" located in {Package.Location}", new FileNotFoundException());
694+
$"|Unable to get logo for {UserModelId} from {path} and" +
695+
$" located in {Package.Location}", new FileNotFoundException());
638696
return new BitmapImage(new Uri(Constant.MissingImgIcon));
639697
}
640698
}
@@ -682,8 +740,8 @@ private ImageSource PlatedImage(BitmapImage image)
682740
else
683741
{
684742
ProgramLogger.LogException($"|UWP|PlatedImage|{Package.Location}" +
685-
$"|Unable to convert background string {BackgroundColor} " +
686-
$"to color for {Package.Location}", new InvalidOperationException());
743+
$"|Unable to convert background string {BackgroundColor} " +
744+
$"to color for {Package.Location}", new InvalidOperationException());
687745

688746
return new BitmapImage(new Uri(Constant.MissingImgIcon));
689747
}
@@ -701,6 +759,14 @@ public override string ToString()
701759
}
702760
}
703761

762+
public static void Dispose()
763+
{
764+
foreach (var fileSystemWatcher in _watchers)
765+
{
766+
fileSystemWatcher.Dispose();
767+
}
768+
}
769+
704770
public enum PackageVersion
705771
{
706772
Windows10,
@@ -728,5 +794,6 @@ private static extern Hresult SHCreateStreamOnFileEx(string fileName, Stgm grfMo
728794
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
729795
private static extern Hresult SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, uint cchOutBuf,
730796
IntPtr ppvReserved);
797+
731798
}
732799
}

0 commit comments

Comments
 (0)