diff --git a/Wox.Core/Plugin/PluginManager.cs b/Wox.Core/Plugin/PluginManager.cs
index fc9afb7401..27e2d48513 100644
--- a/Wox.Core/Plugin/PluginManager.cs
+++ b/Wox.Core/Plugin/PluginManager.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -92,21 +93,36 @@ namespace Wox.Core.Plugin
Settings.UpdatePluginSettings(_metadatas);
AllPlugins = PluginsLoader.Plugins(_metadatas, Settings);
}
+
+ ///
+ /// Call initialize for all plugins
+ ///
+ /// return the list of failed to init plugins or null for none
public static void InitializePlugins(IPublicAPI api)
{
API = api;
+ var failedPlugins = new ConcurrentQueue();
Parallel.ForEach(AllPlugins, pair =>
{
- var milliseconds = Stopwatch.Debug($"|PluginManager.InitializePlugins|Init method time cost for <{pair.Metadata.Name}>", () =>
+ try
{
- pair.Plugin.Init(new PluginInitContext
+ var milliseconds = Stopwatch.Debug($"|PluginManager.InitializePlugins|Init method time cost for <{pair.Metadata.Name}>", () =>
{
- CurrentPluginMetadata = pair.Metadata,
- API = API
+ 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>");
+ 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; // TODO: not sure this really disable it later on
+ failedPlugins.Enqueue(pair);
+ }
});
_contextMenuPlugins = GetPluginsForInterface();
@@ -121,6 +137,11 @@ namespace Wox.Core.Plugin
.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 InstallPlugin(string path)
diff --git a/Wox.Infrastructure/Logger/Log.cs b/Wox.Infrastructure/Logger/Log.cs
index 10e8128c5f..349920076c 100644
--- a/Wox.Infrastructure/Logger/Log.cs
+++ b/Wox.Infrastructure/Logger/Log.cs
@@ -11,7 +11,7 @@ namespace Wox.Infrastructure.Logger
{
public const string DirectoryName = "Logs";
- public static string CurrentLogDirectory { get; private set; }
+ public static string CurrentLogDirectory { get; }
static Log()
{
@@ -53,6 +53,14 @@ namespace Wox.Infrastructure.Logger
[MethodImpl(MethodImplOptions.Synchronized)]
public static void Exception(string className, string message, System.Exception exception, [CallerMemberName] string methodName = "")
+ {
+ var classNameWithMethod = CheckClassAndMessageAndReturnFullClassWithMethod(className, message, methodName);
+
+ ExceptionInternal(classNameWithMethod, message, exception);
+ }
+
+ private static string CheckClassAndMessageAndReturnFullClassWithMethod(string className, string message,
+ string methodName)
{
if (string.IsNullOrWhiteSpace(className))
{
@@ -60,16 +68,17 @@ namespace Wox.Infrastructure.Logger
}
if (string.IsNullOrWhiteSpace(message))
- { // todo: not sure we really need that
+ {
+ // todo: not sure we really need that
LogFaultyFormat($"Fail to specify a message during logging");
}
if (!string.IsNullOrWhiteSpace(methodName))
{
- className += "." + methodName;
+ return className + "." + methodName;
}
- ExceptionInternal(className, message, exception);
+ return className;
}
private static void ExceptionInternal(string classAndMethod, string message, System.Exception e)
@@ -140,18 +149,48 @@ namespace Wox.Infrastructure.Logger
LogInternal(message, LogLevel.Error);
}
+ public static void Error(string className, string message, [CallerMemberName] string methodName = "")
+ {
+ LogInternal(LogLevel.Error, className, message, methodName);
+ }
+
+ private static void LogInternal(LogLevel level, string className, string message, [CallerMemberName] string methodName = "")
+ {
+ var classNameWithMethod = CheckClassAndMessageAndReturnFullClassWithMethod(className, message, methodName);
+
+ var logger = LogManager.GetLogger(classNameWithMethod);
+
+ System.Diagnostics.Debug.WriteLine($"{level.Name}|{message}");
+ logger.Log(level, message);
+ }
+
+ public static void Debug(string className, string message, [CallerMemberName] string methodName = "")
+ {
+ LogInternal(LogLevel.Debug, className, message, methodName);
+ }
+
/// example: "|prefix|unprefixed"
public static void Debug(string message)
{
LogInternal(message, LogLevel.Debug);
}
+ public static void Info(string className, string message, [CallerMemberName] string methodName = "")
+ {
+ LogInternal(LogLevel.Info, className, message, methodName);
+ }
+
/// example: "|prefix|unprefixed"
public static void Info(string message)
{
LogInternal(message, LogLevel.Info);
}
+ public static void Warn(string className, string message, [CallerMemberName] string methodName = "")
+ {
+ LogInternal(LogLevel.Warn, className, message, methodName);
+ }
+
/// example: "|prefix|unprefixed"
public static void Warn(string message)
{
diff --git a/Wox.Plugin/IPublicAPI.cs b/Wox.Plugin/IPublicAPI.cs
index eb3f18fa70..8dc838963c 100644
--- a/Wox.Plugin/IPublicAPI.cs
+++ b/Wox.Plugin/IPublicAPI.cs
@@ -76,7 +76,7 @@ namespace Wox.Plugin
/// Message title
/// Message subtitle
/// Message icon path (relative path to your plugin folder)
- void ShowMsg(string title, string subTitle = "", string iconPath = "");
+ void ShowMsg(string title, string subTitle = "", string iconPath = "", bool useMainWindowAsOwner = true);
///
/// Open setting dialog
diff --git a/Wox.Plugin/PluginMetadata.cs b/Wox.Plugin/PluginMetadata.cs
index 5b4feb88ef..64b8b032c3 100644
--- a/Wox.Plugin/PluginMetadata.cs
+++ b/Wox.Plugin/PluginMetadata.cs
@@ -46,6 +46,9 @@ namespace Wox.Plugin
[Obsolete("Use IcoPath")]
public string FullIcoPath => IcoPath;
+ ///
+ /// Init time include both plugin load time and init time
+ ///
[JsonIgnore]
public long InitTime { get; set; }
[JsonIgnore]
diff --git a/Wox/PublicAPIInstance.cs b/Wox/PublicAPIInstance.cs
index ab198d6bf1..314fc13b67 100644
--- a/Wox/PublicAPIInstance.cs
+++ b/Wox/PublicAPIInstance.cs
@@ -91,12 +91,12 @@ namespace Wox
_mainVM.MainWindowVisibility = Visibility.Visible;
}
- public void ShowMsg(string title, string subTitle = "", string iconPath = "")
+ public void ShowMsg(string title, string subTitle = "", string iconPath = "", bool useMainWindowAsOwner = true)
{
Application.Current.Dispatcher.Invoke(() =>
{
- var m = new Msg { Owner = Application.Current.MainWindow };
- m.Show(title, subTitle, iconPath);
+ var msg = useMainWindowAsOwner ? new Msg {Owner = Application.Current.MainWindow} : new Msg();
+ msg.Show(title, subTitle, iconPath);
});
}