public static void InitializePlugins(IPublicAPI api) { API = api; Parallel.ForEach(AllPlugins, pair => { var milliseconds = Stopwatch.Debug($"|PluginManager.InitializePlugins|Init method time cost for <{pair.Metadata.Name}>", () => { pair.Plugin.Init(new PluginInitContext { CurrentPluginMetadata = pair.Metadata, API = API }); }); pair.Metadata.InitTime += milliseconds; Log.Info($"|PluginManager.InitializePlugins|Total init cost for <{pair.Metadata.Name}> is <{pair.Metadata.InitTime}ms>"); }); _contextMenuPlugins = GetPluginsForInterface <IContextMenu>(); foreach (var plugin in AllPlugins) { if (IsGlobalPlugin(plugin.Metadata)) { GlobalPlugins.Add(plugin); } else { foreach (string actionKeyword in plugin.Metadata.ActionKeywords) { NonGlobalPlugins[actionKeyword] = plugin; } } } }
public static void InitializePlugins(IPublicAPI api) { API = api; Parallel.ForEach(AllPlugins, pair => { var milliseconds = Stopwatch.Debug($"|PluginManager.InitializePlugins|Init method time cost for <{pair.Metadata.Name}>", () => { pair.Plugin.Init(new PluginInitContext { CurrentPluginMetadata = pair.Metadata, API = API }); }); pair.Metadata.InitTime += milliseconds; Log.Info($"|PluginManager.InitializePlugins|Total init cost for <{pair.Metadata.Name}> is <{pair.Metadata.InitTime}ms>"); }); _contextMenuPlugins = GetPluginsForInterface <IContextMenu>(); foreach (var plugin in AllPlugins) { if (IsGlobalPlugin(plugin.Metadata)) { GlobalPlugins.Add(plugin); } // Plugins may have multiple ActionKeywords, eg. WebSearch plugin.Metadata.ActionKeywords.Where(x => x != Query.GlobalPluginWildcardSign) .ToList() .ForEach(x => NonGlobalPlugins[x] = plugin); } }
public static List <Result> QueryForPlugin(PluginPair pair, Query query, bool delayedExecution = false) { try { List <Result> results = null; var metadata = pair.Metadata; var milliseconds = Stopwatch.Debug($"|PluginManager.QueryForPlugin|Cost for {metadata.Name}", () => { if (delayedExecution && (pair.Plugin is IDelayedExecutionPlugin)) { results = ((IDelayedExecutionPlugin)pair.Plugin).Query(query, delayedExecution) ?? new List <Result>(); } else if (!delayedExecution) { results = pair.Plugin.Query(query) ?? new List <Result>(); } if (results != null) { UpdatePluginMetadata(results, metadata, query); UpdateResultWithActionKeyword(results, query); } }); metadata.QueryCount += 1; metadata.AvgQueryTime = metadata.QueryCount == 1 ? milliseconds : (metadata.AvgQueryTime + milliseconds) / 2; return(results); } catch (Exception e) { Log.Exception($"|PluginManager.QueryForPlugin|Exception for plugin <{pair.Metadata.Name}> when query <{query}>", e); return(new List <Result>()); } }
public static void PreloadImages() { //ImageCacheStroage.Instance.TopUsedImages can be changed during foreach, so we need to make a copy var imageList = new Dictionary <string, int>(_imageCache.TopUsedImages); Stopwatch.Debug($"Preload {imageList.Count} images", () => { foreach (var image in imageList) { if (!imageCache.ContainsKey(image.Key)) { ImageSource img = Load(image.Key, false); if (img != null) { img.Freeze(); //to make it copy to UI thread if (!imageCache.ContainsKey(image.Key)) { KeyValuePair <string, int> copyedImg = image; imageCache.Add(copyedImg.Key, img); } } } } }); }
public static void PreloadImages() { foreach (var icon in new[] { DefaultIcon, ErrorIcon }) { ImageSource img = new BitmapImage(new Uri(DefaultIcon)); img.Freeze(); ImageSources[icon] = img; } Task.Run(() => { Stopwatch.Debug("Preload images from cache", () => { _cache.TopUsedImages.AsParallel().Where(i => !ImageSources.ContainsKey(i.Key)).ForAll(i => { var img = Load(i.Key); if (img != null) { // todo happlebao magic // the image created on other threads can be accessed from main ui thread, // this line made it possible // should be changed the Dispatcher.InvokeAsync in the future img.Freeze(); ImageSources[i.Key] = img; } }); }); }); Log.Info($"Preload {_cache.TopUsedImages.Count} images from cache"); }
public static IEnumerable <PluginPair> CSharpPlugins(List <PluginMetadata> source) { var plugins = new List <PluginPair>(); var metadatas = source.Where(o => o.Language.ToUpper() == AllowedLanguage.CSharp); foreach (var metadata in metadatas) { var milliseconds = Stopwatch.Debug($"|PluginsLoader.CSharpPlugins|Constructor init cost for {metadata.Name}", () => { #if DEBUG var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(metadata.ExecuteFilePath); var types = assembly.GetTypes(); var type = types.First(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IPlugin))); var plugin = (IPlugin)Activator.CreateInstance(type); #else Assembly assembly; try { assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(metadata.ExecuteFilePath); } catch (Exception e) { Log.Exception($"|PluginsLoader.CSharpPlugins|Couldn't load assembly for {metadata.Name}", e); return; } var types = assembly.GetTypes(); Type type; try { type = types.First(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IPlugin))); } catch (InvalidOperationException e) { Log.Exception($"|PluginsLoader.CSharpPlugins|Can't find class implement IPlugin for <{metadata.Name}>", e); return; } IPlugin plugin; try { plugin = (IPlugin)Activator.CreateInstance(type); } catch (Exception e) { Log.Exception($"|PluginsLoader.CSharpPlugins|Can't create instance for <{metadata.Name}>", e); return; } #endif PluginPair pair = new PluginPair { Plugin = plugin, Metadata = metadata }; plugins.Add(pair); }); metadata.InitTime += milliseconds; } return(plugins); }
public static List <Result> QueryForPlugin(PluginPair pair, Query query, bool delayedExecution = false) { if (pair == null) { throw new ArgumentNullException(nameof(pair)); } if (!pair.IsPluginInitialized) { return(new List <Result>()); } try { List <Result> results = null; var metadata = pair.Metadata; var milliseconds = Stopwatch.Debug($"PluginManager.QueryForPlugin - Cost for {metadata.Name}", () => { if (delayedExecution && (pair.Plugin is IDelayedExecutionPlugin)) { results = ((IDelayedExecutionPlugin)pair.Plugin).Query(query, delayedExecution) ?? new List <Result>(); } else if (!delayedExecution) { results = pair.Plugin.Query(query) ?? new List <Result>(); } if (results != null) { UpdatePluginMetadata(results, metadata, query); UpdateResultWithActionKeyword(results, query); } }); if (milliseconds > 50) { Log.Warn($"PluginManager.QueryForPlugin {metadata.Name}. Query cost - {milliseconds} milliseconds", typeof(PluginManager)); } metadata.QueryCount += 1; metadata.AvgQueryTime = metadata.QueryCount == 1 ? milliseconds : (metadata.AvgQueryTime + milliseconds) / 2; return(results); } catch (Exception e) { Log.Exception($"Exception for plugin <{pair.Metadata.Name}> when query <{query}>", e, MethodBase.GetCurrentMethod().DeclaringType); return(new List <Result>()); } }
public static ImageSource Load(string path, bool addToCache = true) { if (string.IsNullOrEmpty(path)) { return(null); } ImageSource img = null; Stopwatch.Debug($"Loading image path: {path}", () => { if (addToCache) { _imageCache.Add(path); } if (imageCache.ContainsKey(path)) { img = imageCache[path]; } else { string ext = Path.GetExtension(path).ToLower(); if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase)) { img = new BitmapImage(new Uri(path)); } else if (selfExts.Contains(ext) && File.Exists(path)) { img = GetIcon(path); } else if (!string.IsNullOrEmpty(path) && imageExts.Contains(ext) && File.Exists(path)) { img = new BitmapImage(new Uri(path)); } if (img != null && addToCache) { if (!imageCache.ContainsKey(path)) { imageCache.Add(path, img); } } } }); return(img); }
/// <summary> /// Call initialize for all plugins /// </summary> /// <returns>return the list of failed to init plugins or null for none</returns> public static void InitializePlugins(IPublicAPI api) { API = api; var failedPlugins = new ConcurrentQueue <PluginPair>(); Parallel.ForEach(AllPlugins, pair => { try { var milliseconds = Stopwatch.Debug($"|PluginManager.InitializePlugins|Init method time cost for <{pair.Metadata.Name}>", () => { pair.Plugin.Init(new PluginInitContext { CurrentPluginMetadata = pair.Metadata, API = API }); }); pair.Metadata.InitTime += milliseconds; Log.Info($"|PluginManager.InitializePlugins|Total init cost for <{pair.Metadata.Name}> is <{pair.Metadata.InitTime}ms>"); } catch (Exception e) { Log.Exception(nameof(PluginManager), $"Fail to Init plugin: {pair.Metadata.Name}", e); pair.Metadata.Disabled = true; failedPlugins.Enqueue(pair); } }); _contextMenuPlugins = GetPluginsForInterface <IContextMenu>(); foreach (var plugin in AllPlugins) { if (IsGlobalPlugin(plugin.Metadata)) { GlobalPlugins.Add(plugin); } // Plugins may have multiple ActionKeywords, eg. WebSearch plugin.Metadata.ActionKeywords .Where(x => x != Query.GlobalPluginWildcardSign) .ToList() .ForEach(x => NonGlobalPlugins[x] = plugin); } if (failedPlugins.Any()) { var failed = string.Join(",", failedPlugins.Select(x => x.Metadata.Name)); API.ShowMsg($"Fail to Init Plugins", $"Plugins: {failed} - fail to load and would be disabled, please contact plugin creator for help", "", false); } }
public static void PreloadImages() { Stopwatch.Debug($"Preload {_cache.TopUsedImages.Count} images", () => { _cache.TopUsedImages.AsParallel().Where(i => !_imageSources.ContainsKey(i.Key)).ForAll(i => { var img = Load(i.Key, false); if (img != null) { // todo happlebao magic // the image created on other threads can be accessed from main ui thread, // this line made it possible // should be changed the Dispatcher.InvokeAsync in the future img.Freeze(); _imageSources[i.Key] = img; } }); }); }
public static List <Result> QueryForPlugin(PluginPair pair, Query query) { try { List <Result> results = null; var metadata = pair.Metadata; var milliseconds = Stopwatch.Debug($"|PluginManager.QueryForPlugin|Cost for {metadata.Name}", () => { results = pair.Plugin.Query(query) ?? new List <Result>(); UpdatePluginMetadata(results, metadata, query); }); metadata.QueryCount += 1; metadata.AvgQueryTime = metadata.QueryCount == 1 ? milliseconds : (metadata.AvgQueryTime + milliseconds) / 2; return(results); } catch (Exception e) { Log.Exception($"|PluginManager.QueryForPlugin|Exception for plugin <{pair.Metadata.Name}> when query <{query}>", e); return(new List <Result>()); } }
public static List <Result> QueryForPlugin(PluginPair pair, Query query) { var results = new List <Result>(); try { var metadata = pair.Metadata; var milliseconds = Stopwatch.Debug($"|PluginManager.QueryForPlugin|Cost for {metadata.Name}", () => { results = pair.Plugin.Query(query) ?? results; UpdatePluginMetadata(results, metadata, query); }); metadata.QueryCount += 1; metadata.AvgQueryTime = metadata.QueryCount == 1 ? milliseconds : (metadata.AvgQueryTime + milliseconds) / 2; } catch (Exception e) { throw new WoxPluginException(pair.Metadata.Name, "QueryForPlugin failed", e); } return(results); }
public static List <Result> QueryForPlugin(PluginPair pair, Query query, Dictionary <string, int> historyHistorySources) { List <Result> results = new List <Result>(); try { PluginMetadata metadata = pair.Metadata; long milliseconds = Stopwatch.Debug($"|PluginManager.QueryForPlugin|Cost for {metadata.Name}", () => { results = pair.Plugin.Query(query, historyHistorySources) ?? results; UpdatePluginMetadata(results, metadata, query); }); metadata.QueryCount += 1; metadata.AvgQueryTime = metadata.QueryCount == 1 ? milliseconds : (metadata.AvgQueryTime + milliseconds) / 2; return(results); } catch (Exception e) { Log.Exception( $"|PluginManager.QueryForPlugin|Exception for plugin <{pair.Metadata.Name}> when query <{query}>", e); return(new List <Result>()); } }
public static void InitializePlugins(IPublicAPI api) { //load plugin i18n languages ResourceMerger.UpdatePluginLanguages(); API = api; Parallel.ForEach(AllPlugins, pair => { var milliseconds = Stopwatch.Debug($"Plugin init: {pair.Metadata.Name}", () => { pair.Plugin.Init(new PluginInitContext { CurrentPluginMetadata = pair.Metadata, API = API }); }); pair.Metadata.InitTime += milliseconds; Log.Info($"Total init for {pair.Metadata.Name}: {pair.Metadata.InitTime}ms"); InternationalizationManager.Instance.UpdatePluginMetadataTranslations(pair); }); _contextMenuPlugins = GetPluginsForInterface <IContextMenu>(); foreach (var plugin in AllPlugins) { if (IsGlobalPlugin(plugin.Metadata)) { GlobalPlugins.Add(plugin); } else { foreach (string actionKeyword in plugin.Metadata.ActionKeywords) { NonGlobalPlugins[actionKeyword] = plugin; } } } }
public static void InitializePlugins(IPublicAPI api) { API = api ?? throw new ArgumentNullException(nameof(api)); var failedPlugins = new ConcurrentQueue <PluginPair>(); Parallel.ForEach(AllPlugins, pair => { try { var milliseconds = Stopwatch.Debug($"PluginManager.InitializePlugins - Init method time cost for <{pair.Metadata.Name}>", () => { pair.Plugin.Init(new PluginInitContext { CurrentPluginMetadata = pair.Metadata, API = API, }); }); pair.Metadata.InitTime += milliseconds; Log.Info($"Total init cost for <{pair.Metadata.Name}> is <{pair.Metadata.InitTime}ms>", MethodBase.GetCurrentMethod().DeclaringType); } catch (Exception e) { Log.Exception($"Fail to Init plugin: {pair.Metadata.Name}", e, MethodBase.GetCurrentMethod().DeclaringType); pair.Metadata.Disabled = true; failedPlugins.Enqueue(pair); } }); _contextMenuPlugins = GetPluginsForInterface <IContextMenu>(); if (failedPlugins.Any()) { var failed = string.Join(",", failedPlugins.Select(x => x.Metadata.Name)); API.ShowMsg($"Fail to Init Plugins", $"Plugins: {failed} - fail to load and would be disabled, please contact plugin creator for help", string.Empty, false); } }
public static void PreloadImages() { foreach (var icon in new[] { Constant.DefaultIcon, Constant.ErrorIcon }) { ImageSource img = new BitmapImage(new Uri(icon)); img.Freeze(); ImageSources[icon] = img; } Task.Run(() => { Stopwatch.Debug("Preload images from cache", () => { _cache.TopUsedImages.AsParallel().Where(i => !ImageSources.ContainsKey(i.Key)).ForAll(i => { var img = Load(i.Key); if (img != null) { ImageSources[i.Key] = img; } }); }); }); Log.Info($"Preload {_cache.TopUsedImages.Count} images from cache"); }
public static ImageSource Load(string path, bool addToCache = true) { ImageSource image = null; if (string.IsNullOrEmpty(path)) { path = Path.Combine(Wox.ProgramPath, "Images", "app.png"); image = new BitmapImage(new Uri(path)); return(image); } Stopwatch.Debug($"Loading image path: {path}", () => { if (addToCache) { _cache.Add(path); } if (_imageSources.ContainsKey(path)) { image = _imageSources[path]; } else { string ext = Path.GetExtension(path).ToLower(); if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase)) { image = new BitmapImage(new Uri(path)); } else if (SelfExts.Contains(ext) && File.Exists(path)) { image = GetIcon(path); } else if (!string.IsNullOrEmpty(path) && ImageExts.Contains(ext)) { if (File.Exists(path)) { image = new BitmapImage(new Uri(path)); } else { path = Path.Combine(Wox.ProgramPath, "Images", Path.GetFileName(path)); if (File.Exists(path)) { image = new BitmapImage(new Uri(path)); } else { path = Path.Combine(Wox.ProgramPath, "Images", "app.png"); image = new BitmapImage(new Uri(path)); } } } if (image != null && addToCache) { if (!_imageSources.ContainsKey(path)) { _imageSources[path] = image; } } } }); return(image); }
public static IEnumerable <PluginPair> DotNetPlugins(List <PluginMetadata> source) { var erroredPlugins = new List <string>(); var plugins = new List <PluginPair>(); var metadatas = source.Where(o => AllowedLanguage.IsDotNet(o.Language)); foreach (var metadata in metadatas) { var milliseconds = Stopwatch.Debug( $"|PluginsLoader.DotNetPlugins|Constructor init cost for {metadata.Name}", () => { #if DEBUG var assemblyLoader = new PluginAssemblyLoader(metadata.ExecuteFilePath); var assembly = assemblyLoader.LoadAssemblyAndDependencies(); var type = assemblyLoader.FromAssemblyGetTypeOfInterface(assembly, typeof(IPlugin), typeof(IAsyncPlugin)); var plugin = Activator.CreateInstance(type); #else Assembly assembly = null; object plugin = null; try { var assemblyLoader = new PluginAssemblyLoader(metadata.ExecuteFilePath); assembly = assemblyLoader.LoadAssemblyAndDependencies(); var type = assemblyLoader.FromAssemblyGetTypeOfInterface(assembly, typeof(IPlugin), typeof(IAsyncPlugin)); plugin = Activator.CreateInstance(type); } catch (Exception e) when(assembly == null) { Log.Exception($"|PluginsLoader.DotNetPlugins|Couldn't load assembly for the plugin: {metadata.Name}", e); } catch (InvalidOperationException e) { Log.Exception($"|PluginsLoader.DotNetPlugins|Can't find the required IPlugin interface for the plugin: <{metadata.Name}>", e); } catch (ReflectionTypeLoadException e) { Log.Exception($"|PluginsLoader.DotNetPlugins|The GetTypes method was unable to load assembly types for the plugin: <{metadata.Name}>", e); } catch (Exception e) { Log.Exception($"|PluginsLoader.DotNetPlugins|The following plugin has errored and can not be loaded: <{metadata.Name}>", e); } if (plugin == null) { erroredPlugins.Add(metadata.Name); return; } #endif plugins.Add(new PluginPair { Plugin = plugin, Metadata = metadata }); }); metadata.InitTime += milliseconds; } if (erroredPlugins.Count > 0) { var errorPluginString = String.Join(Environment.NewLine, erroredPlugins); var errorMessage = "The following " + (erroredPlugins.Count > 1 ? "plugins have " : "plugin has ") + "errored and cannot be loaded:"; Task.Run(() => { MessageBox.Show($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" + $"{errorPluginString}{Environment.NewLine}{Environment.NewLine}" + $"Please refer to the logs for more information", "", MessageBoxButtons.OK, MessageBoxIcon.Warning); }); } return(plugins); }