diff --git a/Flow.Launcher.Core/Plugin/PluginAssemblyLoader.cs b/Flow.Launcher.Core/Plugin/PluginAssemblyLoader.cs index 273698b86..f473cbc65 100644 --- a/Flow.Launcher.Core/Plugin/PluginAssemblyLoader.cs +++ b/Flow.Launcher.Core/Plugin/PluginAssemblyLoader.cs @@ -1,5 +1,6 @@ using Flow.Launcher.Infrastructure; using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; @@ -11,17 +12,23 @@ namespace Flow.Launcher.Core.Plugin { private readonly AssemblyDependencyResolver dependencyResolver; - private readonly AssemblyDependencyResolver referencedPluginPackageDependencyResolver; - private readonly AssemblyName assemblyName; + private static readonly List loadedAssembly; + + static PluginAssemblyLoader() + { + loadedAssembly = new List(AppDomain.CurrentDomain.GetAssemblies()); + AppDomain.CurrentDomain.AssemblyLoad += (sender, args) => + { + loadedAssembly.Add(args.LoadedAssembly); + }; + } + internal PluginAssemblyLoader(string assemblyFilePath) { dependencyResolver = new AssemblyDependencyResolver(assemblyFilePath); assemblyName = new AssemblyName(Path.GetFileNameWithoutExtension(assemblyFilePath)); - - referencedPluginPackageDependencyResolver = - new AssemblyDependencyResolver(Path.Combine(Constant.ProgramDirectory, "Flow.Launcher.Plugin.dll")); } internal Assembly LoadAssemblyAndDependencies() @@ -33,10 +40,10 @@ namespace Flow.Launcher.Core.Plugin { string assemblyPath = dependencyResolver.ResolveAssemblyToPath(assemblyName); - // When resolving dependencies, ignore assembly depenedencies that already exits with Flow.Launcher.Plugin - // Otherwise will get unexpected behaviour with plugins, e.g. JsonIgnore attribute not honored in WebSearch or other plugins - // that use Newtonsoft.Json - if (assemblyPath == null || ExistsInReferencedPluginPackage(assemblyName)) + // When resolving dependencies, ignore assembly depenedencies that already exits with Flow.Launcher + // Otherwise duplicate assembly will be loaded and some weird behavior will occur, such as WinRT.Runtime.dll + // will fail due to loading multiple versions in process, each with their own static instance of registration state + if (assemblyPath == null || ExistsInReferencedPackage(assemblyName)) return null; return LoadFromAssemblyPath(assemblyPath); @@ -45,13 +52,14 @@ namespace Flow.Launcher.Core.Plugin internal Type FromAssemblyGetTypeOfInterface(Assembly assembly, params Type[] types) { var allTypes = assembly.ExportedTypes; - return allTypes.First(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Intersect(types).Any()); } - internal bool ExistsInReferencedPluginPackage(AssemblyName assemblyName) + internal bool ExistsInReferencedPackage(AssemblyName assemblyName) { - return referencedPluginPackageDependencyResolver.ResolveAssemblyToPath(assemblyName) != null; + if (loadedAssembly.Any(a => a.FullName == assemblyName.FullName)) + return true; + return false; } } -} +} \ No newline at end of file diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs index 8f0de798c..76713ce2a 100644 --- a/Flow.Launcher.Core/Updater.cs +++ b/Flow.Launcher.Core/Updater.cs @@ -87,7 +87,7 @@ namespace Flow.Launcher.Core UpdateManager.RestartApp(Constant.ApplicationFileName); } } - catch (Exception e) when (e is HttpRequestException || e is WebException || e is SocketException || e is TaskCanceledException) + catch (Exception e) when (e is HttpRequestException || e is WebException || e is SocketException || e.InnerException is TimeoutException) { Log.Exception($"|Updater.UpdateApp|Check your connection and proxy settings to github-cloud.s3.amazonaws.com.", e); api.ShowMsg(api.GetTranslation("update_flowlauncher_fail"), diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs index 4135bb59a..7eca5a568 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/Main.cs @@ -125,8 +125,7 @@ namespace Flow.Launcher.Plugin.WebSearch { var suggestions = await source.Suggestions(keyword, token).ConfigureAwait(false); - if (token.IsCancellationRequested) - return null; + token.ThrowIfCancellationRequested(); var resultsFromSuggestion = suggestions?.Select(o => new Result { diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs index 385a9f8b5..94458ff52 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Baidu.cs @@ -25,15 +25,16 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources const string api = "http://suggestion.baidu.com/su?json=1&wd="; result = await Http.GetAsync(api + Uri.EscapeUriString(query), token).ConfigureAwait(false); } - catch (TaskCanceledException) - { - return null; - } - catch (HttpRequestException e) + catch (Exception e) when (e is HttpRequestException || e.InnerException is TimeoutException) { Log.Exception("|Baidu.Suggestions|Can't get suggestion from baidu", e); return null; } + catch (OperationCanceledException) + { + return null; + } + if (string.IsNullOrEmpty(result)) return new List(); Match match = _reg.Match(result); @@ -44,7 +45,7 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources { json = JsonDocument.Parse(match.Groups[1].Value); } - catch(JsonException e) + catch (JsonException e) { Log.Exception("|Baidu.Suggestions|can't parse suggestions", e); return new List(); diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs index 1a1f10d0c..966a6ca16 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Bing.cs @@ -40,13 +40,13 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources } - catch (TaskCanceledException) + catch (Exception e) when (e is HttpRequestException || e.InnerException is TimeoutException) { - return new List(); + Log.Exception("|Baidu.Suggestions|Can't get suggestion from baidu", e); + return null; } - catch (HttpRequestException e) + catch (OperationCanceledException) { - Log.Exception("|Bing.Suggestions|Can't get suggestion from Bing", e); return new List(); } catch (JsonException e) diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs index 4ca9b2ede..91ab921b6 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SuggestionSources/Google.cs @@ -22,7 +22,7 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources using var resultStream = await Http.GetStreamAsync(api + Uri.EscapeUriString(query)).ConfigureAwait(false); - using var json = await JsonDocument.ParseAsync(resultStream); + using var json = await JsonDocument.ParseAsync(resultStream, cancellationToken: token); if (json == null) return new List(); @@ -32,13 +32,13 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources return results.EnumerateArray().Select(o => o.GetString()).ToList(); } - catch (TaskCanceledException) + catch (Exception e) when (e is HttpRequestException || e.InnerException is TimeoutException) { - return new List(); + Log.Exception("|Baidu.Suggestions|Can't get suggestion from baidu", e); + return null; } - catch (HttpRequestException e) + catch (OperationCanceledException) { - Log.Exception("|Google.Suggestions|Can't get suggestion from google", e); return new List(); } catch (JsonException e) diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json b/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json index 6e9986749..996c9b686 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/plugin.json @@ -25,7 +25,7 @@ "Name": "Web Searches", "Description": "Provide the web search ability", "Author": "qianlifeng", - "Version": "1.3.2", + "Version": "1.3.3", "Language": "csharp", "Website": "https://github.com/Flow-Launcher/Flow.Launcher", "ExecuteFileName": "Flow.Launcher.Plugin.WebSearch.dll",