Skip to content

Commit b497c69

Browse files
authored
Merge pull request #2726 from Flow-Launcher/plugin-program-hide-uninstallers
Program plugin: add option to hide uninstallers from results
2 parents 5c829e2 + 87542e4 commit b497c69

File tree

5 files changed

+44
-3
lines changed

5 files changed

+44
-3
lines changed

Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
<system:String x:Key="flowlauncher_plugin_program_index_PATH_tooltip">When enabled, Flow will load programs from the PATH environment variable</system:String>
3333
<system:String x:Key="flowlauncher_plugin_program_enable_hidelnkpath">Hide app path</system:String>
3434
<system:String x:Key="flowlauncher_plugin_program_enable_hidelnkpath_tooltip">For executable files such as UWP or lnk, hide the file path from being visible</system:String>
35+
<system:String x:Key="flowlauncher_plugin_program_enable_hideuninstallers">Hide uninstallers</system:String>
36+
<system:String x:Key="flowlauncher_plugin_program_enable_hideuninstallers_tooltip">Hides programs with common uninstaller names, such as unins000.exe</system:String>
3537
<system:String x:Key="flowlauncher_plugin_program_enable_description">Search in Program Description</system:String>
3638
<system:String x:Key="flowlauncher_plugin_program_enable_description_tooltip">Flow will search program's description</system:String>
3739
<system:String x:Key="flowlauncher_plugin_program_suffixes_header">Suffixes</system:String>
@@ -92,4 +94,4 @@
9294
<system:String x:Key="flowlauncher_plugin_program_run_as_administrator_not_supported_message">This app is not intended to be run as administrator</system:String>
9395
<system:String x:Key="flowlauncher_plugin_program_run_failed">Unable to run {0}</system:String>
9496

95-
</ResourceDictionary>
97+
</ResourceDictionary>

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using Flow.Launcher.Plugin.Program.Views;
1212
using Flow.Launcher.Plugin.Program.Views.Models;
1313
using Microsoft.Extensions.Caching.Memory;
14+
using Path = System.IO.Path;
1415
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
1516

1617
namespace Flow.Launcher.Plugin.Program
@@ -33,6 +34,17 @@ public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, I
3334
private static readonly MemoryCacheOptions cacheOptions = new() { SizeLimit = 1560 };
3435
private static MemoryCache cache = new(cacheOptions);
3536

37+
private static readonly string[] commonUninstallerNames =
38+
{
39+
"uninst.exe",
40+
"unins000.exe",
41+
"uninst000.exe",
42+
"uninstall.exe"
43+
};
44+
// For cases when the uninstaller is named like "Uninstall Program Name.exe"
45+
private const string CommonUninstallerPrefix = "uninstall";
46+
private const string CommonUninstallerSuffix = ".exe";
47+
3648
static Main()
3749
{
3850
}
@@ -52,6 +64,7 @@ public async Task<List<Result>> QueryAsync(Query query, CancellationToken token)
5264
.Concat(_uwps)
5365
.AsParallel()
5466
.WithCancellation(token)
67+
.Where(HideUninstallersFilter)
5568
.Where(p => p.Enabled)
5669
.Select(p => p.Result(query.Search, Context.API))
5770
.Where(r => r?.Score > 0)
@@ -68,6 +81,16 @@ public async Task<List<Result>> QueryAsync(Query query, CancellationToken token)
6881
return result;
6982
}
7083

84+
private bool HideUninstallersFilter(IProgram program)
85+
{
86+
if (!_settings.HideUninstallers) return true;
87+
if (program is not Win32 win32) return true;
88+
var fileName = Path.GetFileName(win32.ExecutablePath);
89+
return !commonUninstallerNames.Contains(fileName, StringComparer.OrdinalIgnoreCase) &&
90+
!(fileName.StartsWith(CommonUninstallerPrefix, StringComparison.OrdinalIgnoreCase) &&
91+
fileName.EndsWith(CommonUninstallerSuffix, StringComparison.OrdinalIgnoreCase));
92+
}
93+
7194
public async Task InitAsync(PluginInitContext context)
7295
{
7396
Context = context;

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ private void RemoveRedundantSuffixes()
102102
// CustomSuffixes no longer contains custom suffixes
103103
// users has tweaked the settings
104104
// or this function has been executed once
105-
if (UseCustomSuffixes == true || ProgramSuffixes == null)
105+
if (UseCustomSuffixes == true || ProgramSuffixes == null)
106106
return;
107107
var suffixes = ProgramSuffixes.ToList();
108108
foreach(var item in BuiltinSuffixesStatus)
@@ -117,6 +117,7 @@ private void RemoveRedundantSuffixes()
117117
public bool EnableStartMenuSource { get; set; } = true;
118118
public bool EnableDescription { get; set; } = false;
119119
public bool HideAppsPath { get; set; } = true;
120+
public bool HideUninstallers { get; set; } = false;
120121
public bool EnableRegistrySource { get; set; } = true;
121122
public bool EnablePathSource { get; set; } = false;
122123
public bool EnableUWP { get; set; } = true;

Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@
8585
Content="{DynamicResource flowlauncher_plugin_program_enable_hidelnkpath}"
8686
IsChecked="{Binding HideAppsPath}"
8787
ToolTip="{DynamicResource flowlauncher_plugin_program_enable_hidelnkpath_tooltip}" />
88+
<CheckBox
89+
Margin="12 0 12 0"
90+
Content="{DynamicResource flowlauncher_plugin_program_enable_hideuninstallers}"
91+
IsChecked="{Binding HideUninstallers}"
92+
ToolTip="{DynamicResource flowlauncher_plugin_program_enable_hideuninstallers_tooltip}" />
8893
<CheckBox
8994
Name="DescriptionEnabled"
9095
Margin="12,0,12,0"

Plugins/Flow.Launcher.Plugin.Program/Views/ProgramSetting.xaml.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public partial class ProgramSetting : UserControl
2424
private ListSortDirection _lastDirection;
2525

2626
// We do not save all program sources to settings, so using
27-
// this as temporary holder for displaying all loaded programs sources.
27+
// this as temporary holder for displaying all loaded programs sources.
2828
internal static List<ProgramSource> ProgramSettingDisplayList { get; set; }
2929

3030
public bool EnableDescription
@@ -47,6 +47,16 @@ public bool HideAppsPath
4747
}
4848
}
4949

50+
public bool HideUninstallers
51+
{
52+
get => _settings.HideUninstallers;
53+
set
54+
{
55+
Main.ResetCache();
56+
_settings.HideUninstallers = value;
57+
}
58+
}
59+
5060
public bool EnableRegistrySource
5161
{
5262
get => _settings.EnableRegistrySource;

0 commit comments

Comments
 (0)