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

245 lines
8.4 KiB
C#
Raw Permalink Normal View History

using System;
2014-01-04 12:26:13 +00:00
using System.Collections.Generic;
using System.Diagnostics;
2014-01-04 12:26:13 +00:00
using System.Linq;
2021-01-02 09:58:30 +00:00
using System.Threading;
2016-11-30 01:07:48 +00:00
using System.Threading.Tasks;
2016-01-06 21:34:42 +00:00
using System.Windows.Controls;
2020-04-21 09:12:17 +00:00
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Plugin.Program.Programs;
using Flow.Launcher.Plugin.Program.Views;
2022-10-20 08:36:58 +00:00
using Flow.Launcher.Plugin.Program.Views.Models;
2021-05-27 11:28:17 +00:00
using Microsoft.Extensions.Caching.Memory;
2020-04-21 09:12:17 +00:00
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
2014-01-04 12:26:13 +00:00
2020-04-21 09:12:17 +00:00
namespace Flow.Launcher.Plugin.Program
2014-01-04 12:26:13 +00:00
{
public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, ISavable, IAsyncReloadable, IDisposable
2014-01-04 12:26:13 +00:00
{
2019-09-08 12:18:55 +00:00
internal static Win32[] _win32s { get; set; }
internal static UWP.Application[] _uwps { get; set; }
internal static Settings _settings { get; set; }
2019-10-17 20:53:00 +00:00
2021-11-06 06:10:29 +00:00
internal static PluginInitContext Context { get; private set; }
private static BinaryStorage<Win32[]> _win32Storage;
2019-11-28 23:38:50 +00:00
private static BinaryStorage<UWP.Application[]> _uwpStorage;
2021-05-24 02:21:39 +00:00
private static readonly List<Result> emptyResults = new();
2021-05-27 11:28:17 +00:00
private static readonly MemoryCacheOptions cacheOptions = new()
{
SizeLimit = 1560
};
private static MemoryCache cache = new(cacheOptions);
static Main()
{
}
public void Save()
{
_win32Storage.Save(_win32s);
_uwpStorage.Save(_uwps);
}
2021-01-02 09:58:30 +00:00
public async Task<List<Result>> QueryAsync(Query query, CancellationToken token)
2014-01-04 12:26:13 +00:00
{
2021-05-27 11:28:17 +00:00
var result = await cache.GetOrCreateAsync(query.Search, async entry =>
{
var resultList = await Task.Run(() =>
_win32s.Cast<IProgram>()
.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;
entry.SetSize(resultList.Count);
entry.SetSlidingExpiration(TimeSpan.FromHours(8));
return resultList;
});
return result;
2014-01-04 12:26:13 +00:00
}
2021-01-02 09:58:30 +00:00
public async Task InitAsync(PluginInitContext context)
2014-01-04 12:26:13 +00:00
{
2021-11-06 18:58:28 +00:00
Context = context;
2021-01-02 09:58:30 +00:00
_settings = context.API.LoadSettingJsonStorage<Settings>();
2021-01-02 09:58:30 +00:00
Stopwatch.Normal("|Flow.Launcher.Plugin.Program.Main|Preload programs cost", () =>
{
_win32Storage = new BinaryStorage<Win32[]>("Win32");
2022-10-21 10:35:10 +00:00
_win32s = _win32Storage.TryLoad(Array.Empty<Win32>());
_uwpStorage = new BinaryStorage<UWP.Application[]>("UWP");
2022-10-21 10:35:10 +00:00
_uwps = _uwpStorage.TryLoad(Array.Empty<UWP.Application>());
2021-01-02 09:58:30 +00:00
});
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 cacheEmpty = !_win32s.Any() && !_uwps.Any();
2021-01-02 09:58:30 +00:00
var a = Task.Run(() =>
{
Stopwatch.Normal("|Flow.Launcher.Plugin.Program.Main|Win32Program index cost", IndexWin32Programs);
2021-01-02 09:58:30 +00:00
});
var b = Task.Run(() =>
{
2022-10-15 16:32:24 +00:00
Stopwatch.Normal("|Flow.Launcher.Plugin.Program.Main|UWPPRogram index cost", IndexUwpPrograms);
2021-01-02 09:58:30 +00:00
});
if (cacheEmpty)
await Task.WhenAll(a, b);
2021-05-24 02:21:39 +00:00
Win32.WatchProgramUpdate(_settings);
2022-11-17 09:39:09 +00:00
_ = UWP.WatchPackageChange();
}
public static void IndexWin32Programs()
{
2019-11-16 00:37:01 +00:00
var win32S = Win32.All(_settings);
2020-10-14 15:43:16 +00:00
_win32s = win32S;
ResetCache();
}
2021-01-02 09:58:30 +00:00
public static void IndexUwpPrograms()
{
var windows10 = new Version(10, 0);
var support = Environment.OSVersion.Version.Major >= windows10.Major;
2022-10-21 10:35:10 +00:00
var applications = support ? UWP.All() : Array.Empty<UWP.Application>();
2020-10-14 15:43:16 +00:00
_uwps = applications;
ResetCache();
}
2014-03-22 05:50:20 +00:00
public static async Task IndexProgramsAsync()
{
2022-10-29 18:37:22 +00:00
var a = Task.Run(() =>
{
Stopwatch.Normal("|Flow.Launcher.Plugin.Program.Main|Win32Program index cost", IndexWin32Programs);
});
var b = Task.Run(() =>
{
Stopwatch.Normal("|Flow.Launcher.Plugin.Program.Main|UWPProgram index cost", IndexUwpPrograms);
});
await Task.WhenAll(a, b).ConfigureAwait(false);
_settings.LastIndexTime = DateTime.Today;
}
internal static void ResetCache()
{
2021-05-27 11:28:17 +00:00
var oldCache = cache;
cache = new MemoryCache(cacheOptions);
oldCache.Dispose();
2019-11-28 23:38:50 +00:00
}
2019-09-07 05:58:13 +00:00
2016-01-06 21:34:42 +00:00
public Control CreateSettingPanel()
{
2021-11-06 18:58:28 +00:00
return new ProgramSetting(Context, _settings, _win32s, _uwps);
}
2015-02-07 12:17:49 +00:00
public string GetTranslatedPluginTitle()
{
2021-11-06 18:58:28 +00:00
return Context.API.GetTranslation("flowlauncher_plugin_program_plugin_name");
2015-02-07 12:17:49 +00:00
}
public string GetTranslatedPluginDescription()
{
2021-11-06 18:58:28 +00:00
return Context.API.GetTranslation("flowlauncher_plugin_program_plugin_description");
2015-02-07 12:17:49 +00:00
}
public List<Result> LoadContextMenus(Result selectedResult)
{
var menuOptions = new List<Result>();
var program = selectedResult.ContextData as IProgram;
if (program != null)
{
2021-11-06 18:58:28 +00:00
menuOptions = program.ContextMenus(Context.API);
}
menuOptions.Add(
2021-01-02 09:58:30 +00:00
new Result
{
2021-11-06 18:58:28 +00:00
Title = Context.API.GetTranslation("flowlauncher_plugin_program_disable_program"),
2021-01-02 09:58:30 +00:00
Action = c =>
{
DisableProgram(program);
2021-11-06 18:58:28 +00:00
Context.API.ShowMsg(
Context.API.GetTranslation("flowlauncher_plugin_program_disable_dlgtitle_success"),
Context.API.GetTranslation(
2021-01-02 09:58:30 +00:00
"flowlauncher_plugin_program_disable_dlgtitle_success_message"));
return false;
},
2021-10-07 10:58:54 +00:00
IcoPath = "Images/disable.png",
Glyph = new GlyphInfo(FontFamily: "/Resources/#Segoe Fluent Icons", Glyph: "\xece4"),
2021-01-02 09:58:30 +00:00
}
);
return menuOptions;
}
2022-10-21 10:39:03 +00:00
private static void DisableProgram(IProgram programToDelete)
{
if (_settings.DisabledProgramSources.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
return;
if (_uwps.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
{
2022-10-28 10:06:44 +00:00
var program = _uwps.First(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier);
program.Enabled = false;
_settings.DisabledProgramSources.Add(new ProgramSource(program));
2022-10-28 08:44:44 +00:00
_ = Task.Run(() =>
2022-10-25 06:41:46 +00:00
{
IndexUwpPrograms();
2022-10-25 06:41:46 +00:00
_settings.LastIndexTime = DateTime.Today;
});
}
2022-10-25 06:41:46 +00:00
else if (_win32s.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
{
2022-10-28 10:06:44 +00:00
var program = _win32s.First(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier);
program.Enabled = false;
_settings.DisabledProgramSources.Add(new ProgramSource(program));
2022-10-28 08:44:44 +00:00
_ = Task.Run(() =>
2022-10-25 06:41:46 +00:00
{
IndexWin32Programs();
2022-10-25 06:41:46 +00:00
_settings.LastIndexTime = DateTime.Today;
});
}
}
public static void StartProcess(Func<ProcessStartInfo, Process> runProcess, ProcessStartInfo info)
{
try
{
runProcess(info);
}
catch (Exception)
{
var name = "Plugin: Program";
var message = $"Unable to start: {info.FileName}";
2021-11-06 18:58:28 +00:00
Context.API.ShowMsg(name, message, string.Empty);
}
}
2019-10-06 02:15:06 +00:00
2021-01-02 09:58:30 +00:00
public async Task ReloadDataAsync()
2019-10-06 02:15:06 +00:00
{
await IndexProgramsAsync();
2019-10-06 02:15:06 +00:00
}
2022-10-21 10:39:03 +00:00
public void Dispose()
{
Win32.Dispose();
}
2014-01-04 12:26:13 +00:00
}
}