diff --git a/Plugins/Wox.Plugin.Doc/Main.cs b/Plugins/Wox.Plugin.Doc/Main.cs index 170ce72e50..7dec42fab6 100644 --- a/Plugins/Wox.Plugin.Doc/Main.cs +++ b/Plugins/Wox.Plugin.Doc/Main.cs @@ -53,7 +53,7 @@ namespace Wox.Plugin.Doc public void Init(PluginInitContext context) { - docsetBasePath = context.CurrentPluginMetadata.PluginDirecotry + @"Docset"; + docsetBasePath = Path.Combine(context.CurrentPluginMetadata.PluginDirecotry, @"Docset"); if (!Directory.Exists(docsetBasePath)) Directory.CreateDirectory(docsetBasePath); diff --git a/Plugins/Wox.Plugin.PluginManagement/Images/plugin.png b/Plugins/Wox.Plugin.PluginManagement/Images/plugin.png new file mode 100644 index 0000000000..aa447afd8d Binary files /dev/null and b/Plugins/Wox.Plugin.PluginManagement/Images/plugin.png differ diff --git a/Plugins/Wox.Plugin.PluginManagement/Main.cs b/Plugins/Wox.Plugin.PluginManagement/Main.cs new file mode 100644 index 0000000000..82abb4014b --- /dev/null +++ b/Plugins/Wox.Plugin.PluginManagement/Main.cs @@ -0,0 +1,176 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Windows.Forms; +using Newtonsoft.Json; + +namespace Wox.Plugin.PluginManagement +{ + public class Main : IPlugin + { + private static string PluginPath = AppDomain.CurrentDomain.BaseDirectory + "Plugins"; + private static string PluginConfigName = "plugin.json"; + private PluginInitContext context; + + public List Query(Query query) + { + List results = new List(); + if (query.ActionParameters.Count == 0) + { + results.Add(new Result() + { + Title = "wpm list", + SubTitle = "list plugins installed", + IcoPath = "Images\\plugin.png", + Action = e => + { + context.ChangeQuery("wpm list"); + return false; + } + }); + results.Add(new Result() + { + Title = "wpm uninstall ", + SubTitle = "uninstall plugin", + IcoPath = "Images\\plugin.png", + Action = e => + { + context.ChangeQuery("wpm uninstall "); + return false; + } + }); + return results; + } + + if (query.ActionParameters.Count > 0) + { + switch (query.ActionParameters[0].ToLower()) + { + case "list": + results = ListInstalledPlugins(); + break; + + case "uninstall": + results = ListUnInstalledPlugins(query); + break; + } + } + + return results; + } + + private List ListUnInstalledPlugins(Query query) + { + List results = new List(); + List allInstalledPlugins = ParseThirdPartyPlugins(); + if (query.ActionParameters.Count > 1) + { + string pluginName = query.ActionParameters[1]; + allInstalledPlugins = + allInstalledPlugins.Where(o => o.Name.ToLower().Contains(pluginName.ToLower())).ToList(); + } + + foreach (PluginMetadata plugin in allInstalledPlugins) + { + results.Add(new Result() + { + Title = plugin.Name, + SubTitle = plugin.Description, + IcoPath = "Images\\plugin.png", + Action = e => + { + UnInstalledPlugins(plugin); + return true; + } + }); + } + return results; + } + + private void UnInstalledPlugins(PluginMetadata plugin) + { + string content = string.Format("Do you want to uninstall following plugin?\r\n\r\nName: {0}\r\nVersion: {1}\r\nAuthor: {2}",plugin.Name, plugin.Version, plugin.Author); + if (MessageBox.Show(content, "Wox", MessageBoxButtons.YesNo) == DialogResult.Yes) + { + File.Create(Path.Combine(plugin.PluginDirecotry, "NeedDelete.txt")); + MessageBox.Show("This plugin has been removed, restart Wox to take effect"); + } + } + + private List ListInstalledPlugins() + { + List results = new List(); + foreach (PluginMetadata plugin in ParseThirdPartyPlugins()) + { + results.Add(new Result() + { + Title = plugin.Name, + SubTitle = plugin.Description, + IcoPath = "Images\\plugin.png" + }); + } + return results; + } + + private static List ParseThirdPartyPlugins() + { + List pluginMetadatas = new List(); + if (!Directory.Exists(PluginPath)) + Directory.CreateDirectory(PluginPath); + + string[] directories = Directory.GetDirectories(PluginPath); + foreach (string directory in directories) + { + PluginMetadata metadata = GetMetadataFromJson(directory); + if (metadata != null) pluginMetadatas.Add(metadata); + } + + return pluginMetadatas; + } + + private static PluginMetadata GetMetadataFromJson(string pluginDirectory) + { + string configPath = Path.Combine(pluginDirectory, PluginConfigName); + PluginMetadata metadata; + + if (!File.Exists(configPath)) + { + return null; + } + + try + { + metadata = JsonConvert.DeserializeObject(File.ReadAllText(configPath)); + metadata.PluginType = PluginType.ThirdParty; + metadata.PluginDirecotry = pluginDirectory; + } + catch (Exception) + { + string error = string.Format("Parse plugin config {0} failed: json format is not valid", configPath); + return null; + } + + + if (!AllowedLanguage.IsAllowed(metadata.Language)) + { + string error = string.Format("Parse plugin config {0} failed: invalid language {1}", configPath, + metadata.Language); + return null; + } + if (!File.Exists(metadata.ExecuteFilePath)) + { + string error = string.Format("Parse plugin config {0} failed: ExecuteFile {1} didn't exist", configPath, + metadata.ExecuteFilePath); + return null; + } + + return metadata; + } + + public void Init(PluginInitContext context) + { + this.context = context; + } + } +} diff --git a/Wox.Plugin/Wox.Plugin.PluginManagement/Properties/AssemblyInfo.cs b/Plugins/Wox.Plugin.PluginManagement/Properties/AssemblyInfo.cs similarity index 100% rename from Wox.Plugin/Wox.Plugin.PluginManagement/Properties/AssemblyInfo.cs rename to Plugins/Wox.Plugin.PluginManagement/Properties/AssemblyInfo.cs diff --git a/Wox.Plugin/Wox.Plugin.PluginManagement/Wox.Plugin.PluginManagement.csproj b/Plugins/Wox.Plugin.PluginManagement/Wox.Plugin.PluginManagement.csproj similarity index 58% rename from Wox.Plugin/Wox.Plugin.PluginManagement/Wox.Plugin.PluginManagement.csproj rename to Plugins/Wox.Plugin.PluginManagement/Wox.Plugin.PluginManagement.csproj index f66ee5248d..0a2f1384af 100644 --- a/Wox.Plugin/Wox.Plugin.PluginManagement/Wox.Plugin.PluginManagement.csproj +++ b/Plugins/Wox.Plugin.PluginManagement/Wox.Plugin.PluginManagement.csproj @@ -1,58 +1,84 @@ - - - - - Debug - AnyCPU - {049490F0-ECD2-4148-9B39-2135EC346EBE} - Library - Properties - Wox.Plugin.PluginManagement - Wox.Plugin.PluginManagement - v3.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - {8451ecdd-2ea4-4966-bb0a-7bbc40138e80} - Wox.Plugin - - - - + + + + + Debug + AnyCPU + {049490F0-ECD2-4148-9B39-2135EC346EBE} + Library + Properties + Wox.Plugin.PluginManagement + Wox.Plugin.PluginManagement + v3.5 + 512 + ..\..\ + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\packages\Newtonsoft.Json.5.0.8\lib\net35\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + {8451ecdd-2ea4-4966-bb0a-7bbc40138e80} + Wox.Plugin + + + + + + Always + + + + + + + + xcopy /Y /E $(TargetDir)*.* $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\ +xcopy /Y /E $(ProjectDir)Images $(SolutionDir)Wox\bin\Debug\Plugins\$(ProjectName)\Images\ + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。启用“NuGet 程序包还原”可下载这些程序包。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.PluginManagement/packages.config b/Plugins/Wox.Plugin.PluginManagement/packages.config new file mode 100644 index 0000000000..9520f36d83 --- /dev/null +++ b/Plugins/Wox.Plugin.PluginManagement/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Plugins/Wox.Plugin.PluginManagement/plugin.json b/Plugins/Wox.Plugin.PluginManagement/plugin.json new file mode 100644 index 0000000000..ee149e9c10 --- /dev/null +++ b/Plugins/Wox.Plugin.PluginManagement/plugin.json @@ -0,0 +1,11 @@ +{ + "ID":"D2D2C23B084D422DB66FE0C79D6C2A6A", + "ActionKeyword":"wpm", + "Name":"Wox Plugin Management", + "Description":"Manage your plugins in Wox", + "Author":"qianlifeng", + "Version":"1.0", + "Language":"csharp", + "Website":"http://www.getwox.com/plugin", + "ExecuteFileName":"Wox.Plugin.PluginManagement.dll" +} diff --git a/Wox.Plugin/PluginInitContext.cs b/Wox.Plugin/PluginInitContext.cs index f60626e0c5..38013797e9 100644 --- a/Wox.Plugin/PluginInitContext.cs +++ b/Wox.Plugin/PluginInitContext.cs @@ -15,9 +15,15 @@ namespace Wox.Plugin public Action CloseApp { get; set; } public Action HideApp { get; set; } public Action ShowApp { get; set; } - public Action ShowMsg { get; set; } + public Action ShowMsg { get; set; } public Action OpenSettingDialog { get; set; } public Action ShowCurrentResultItemTooltip { get; set; } + + /// + /// reload all plugins + /// + public Action ReloadPlugins { get; set; } + } } diff --git a/Wox.Plugin/Wox.Plugin.PluginManagement/Main.cs b/Wox.Plugin/Wox.Plugin.PluginManagement/Main.cs deleted file mode 100644 index 086820fb0e..0000000000 --- a/Wox.Plugin/Wox.Plugin.PluginManagement/Main.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Wox.Plugin.PluginManagement -{ - public class Main:IPlugin - { - private PluginInitContext context; - - public List Query(Query query) - { - return null; - } - - public void Init(PluginInitContext context) - { - this.context = context; - } - } -} diff --git a/Wox.sln b/Wox.sln index 45cb55dae0..ec105248c6 100644 --- a/Wox.sln +++ b/Wox.sln @@ -27,7 +27,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.UAC", "Wox.UAC\Wox.UAC. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.Clipboard", "Plugins\Wox.Plugin.Clipboard\Wox.Plugin.Clipboard.csproj", "{8C14DC11-2737-4DCB-A121-5D7BDD57FEA2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.PluginManagement", "Wox.Plugin\Wox.Plugin.PluginManagement\Wox.Plugin.PluginManagement.csproj", "{049490F0-ECD2-4148-9B39-2135EC346EBE}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.PluginManagement", "Plugins\Wox.Plugin.PluginManagement\Wox.Plugin.PluginManagement.csproj", "{049490F0-ECD2-4148-9B39-2135EC346EBE}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Wox/App.xaml.cs b/Wox/App.xaml.cs index dcea10c2d3..5f3e2d468f 100644 --- a/Wox/App.xaml.cs +++ b/Wox/App.xaml.cs @@ -1,10 +1,12 @@ using System; using System.Collections.ObjectModel; +using System.IO; using System.Linq; using System.Threading; using System.Windows; using Microsoft.VisualBasic.ApplicationServices; using Wox.Commands; +using Wox.Helper; using StartupEventArgs = System.Windows.StartupEventArgs; namespace Wox @@ -66,6 +68,22 @@ namespace Wox { base.OnStartup(e); + //for install plugin command when wox didn't start up + //we shouldn't init MainWindow, just intall plugin and exit. + if (e.Args.Length > 0 && e.Args[0].ToLower() == "installplugin") + { + var path = e.Args[1]; + if (!File.Exists(path)) + { + MessageBox.Show("Plugin " + path + " didn't exist"); + return; + } + PluginInstaller.Install(path); + Environment.Exit(0); + return; + } + + window = new MainWindow(); if (e.Args.Length == 0 || e.Args[0].ToLower() != "hidestart") { diff --git a/Wox/Helper/PluginInstaller.cs b/Wox/Helper/PluginInstaller.cs index 44ccdb3481..1780609713 100644 --- a/Wox/Helper/PluginInstaller.cs +++ b/Wox/Helper/PluginInstaller.cs @@ -8,6 +8,7 @@ using System.Windows; using ICSharpCode.SharpZipLib.Zip; using Newtonsoft.Json; using Wox.Plugin; +using Wox.PluginLoader; namespace Wox.Helper { @@ -18,37 +19,36 @@ namespace Wox.Helper { if (File.Exists(path)) { - string tempFoler = System.IO.Path.GetTempPath() + "\\wox\\plugins"; + string tempFoler = Path.Combine(Path.GetTempPath(), "wox\\plugins"); if (Directory.Exists(tempFoler)) { Directory.Delete(tempFoler, true); } UnZip(path, tempFoler, true); - string iniPath = tempFoler + "\\plugin.json"; + string iniPath = Path.Combine(tempFoler, "plugin.json"); if (!File.Exists(iniPath)) { - MessageBox.Show("Install failed: config is missing"); + MessageBox.Show("Install failed: plugin config is missing"); return; } PluginMetadata plugin = GetMetadataFromJson(tempFoler); if (plugin == null || plugin.Name == null) { - MessageBox.Show("Install failed: config of this plugin is invalid"); + MessageBox.Show("Install failed: plugin config is invalid"); return; } - string pluginFolerPath = AppDomain.CurrentDomain.BaseDirectory + "Plugins"; + string pluginFolerPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins"); if (!Directory.Exists(pluginFolerPath)) { - MessageBox.Show("Install failed: cound't find plugin directory"); - return; + Directory.CreateDirectory(pluginFolerPath); } - string newPluginPath = pluginFolerPath + "\\" + plugin.Name; + string newPluginPath = Path.Combine(pluginFolerPath, plugin.Name); string content = string.Format( - "Do you want to install following plugin?\r\nName: {0}\r\nVersion: {1}\r\nAuthor: {2}", + "Do you want to install following plugin?\r\n\r\nName: {0}\r\nVersion: {1}\r\nAuthor: {2}", plugin.Name, plugin.Version, plugin.Author); if (Directory.Exists(newPluginPath)) { @@ -61,7 +61,7 @@ namespace Wox.Helper else { content = string.Format( - "Do you want to update following plugin?\r\nName: {0}\r\nOld Version: {1}\r\nNew Version: {2}\r\nAuthor: {3}", + "Do you want to update following plugin?\r\n\r\nName: {0}\r\nOld Version: {1}\r\nNew Version: {2}\r\nAuthor: {3}", plugin.Name, existingPlugin.Version, plugin.Version, plugin.Author); } } @@ -77,21 +77,12 @@ namespace Wox.Helper UnZip(path, newPluginPath, true); Directory.Delete(tempFoler, true); + if (MainWindow.Initialized) + { + Plugins.Init(); + } - string wox = AppDomain.CurrentDomain.BaseDirectory + "Wox.exe"; - if (File.Exists(wox)) - { - ProcessStartInfo info = new ProcessStartInfo(wox, "reloadplugin") - { - UseShellExecute = true - }; - Process.Start(info); - MessageBox.Show("You have installed plugin " + plugin.Name + " successfully."); - } - else - { - MessageBox.Show("You have installed plugin " + plugin.Name + " successfully. Please restart your wox to use new plugin."); - } + MessageBox.Show("You have installed plugin " + plugin.Name + " successfully."); } } } diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index 9454e9a205..88eb589bd3 100644 --- a/Wox/MainWindow.xaml.cs +++ b/Wox/MainWindow.xaml.cs @@ -31,6 +31,7 @@ namespace Wox public partial class MainWindow { private static readonly object locker = new object(); + public static bool Initialized = false; private static readonly List waitShowResultList = new List(); private readonly GloablHotkey globalHotkey = new GloablHotkey(); @@ -41,10 +42,10 @@ namespace Wox private bool queryHasReturn; private ToolTip toolTip = new ToolTip(); - public MainWindow() { InitializeComponent(); + Initialized = true; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; @@ -65,6 +66,15 @@ namespace Wox SetHotkey(CommonStorage.Instance.UserSetting.Hotkey, OnHotkey); SetCustomPluginHotkey(); + + globalHotkey.hookedKeyboardCallback += KListener_hookedKeyboardCallback; + } + + private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) + { + Left = (SystemParameters.PrimaryScreenWidth - ActualWidth) / 2; + Top = (SystemParameters.PrimaryScreenHeight - ActualHeight) / 3; + Plugins.Init(); } private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) @@ -75,6 +85,7 @@ namespace Wox Log.Error(error); if (e.IsTerminating) { + notifyIcon.Visible = false; MessageBox.Show(error); } } @@ -244,17 +255,8 @@ namespace Wox } } - private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) - { - Left = (SystemParameters.PrimaryScreenWidth - ActualWidth) / 2; - Top = (SystemParameters.PrimaryScreenHeight - ActualHeight) / 3; - Plugins.Init(); - - globalHotkey.hookedKeyboardCallback += KListener_hookedKeyboardCallback; - } - private bool KListener_hookedKeyboardCallback(KeyEvent keyevent, int vkcode, SpecialKeyState state) { if (CommonStorage.Instance.UserSetting.ReplaceWinR) diff --git a/Wox/PluginLoader/BasePluginLoader.cs b/Wox/PluginLoader/BasePluginLoader.cs index 5729254fa6..cd1f6efb89 100644 --- a/Wox/PluginLoader/BasePluginLoader.cs +++ b/Wox/PluginLoader/BasePluginLoader.cs @@ -48,6 +48,11 @@ namespace Wox.PluginLoader string[] directories = Directory.GetDirectories(PluginPath); foreach (string directory in directories) { + if (File.Exists((Path.Combine(directory, "NeedDelete.txt")))) + { + Directory.Delete(directory,true); + continue; + } PluginMetadata metadata = GetMetadataFromJson(directory); if (metadata != null) pluginMetadatas.Add(metadata); } diff --git a/Wox/PluginLoader/Plugins.cs b/Wox/PluginLoader/Plugins.cs index 579c1d94f4..4b3361dc67 100644 --- a/Wox/PluginLoader/Plugins.cs +++ b/Wox/PluginLoader/Plugins.cs @@ -36,7 +36,8 @@ namespace Wox.PluginLoader ShowApp = () => App.Window.ShowApp(), ShowMsg = (title, subTitle, iconPath) => App.Window.ShowMsg(title, subTitle, iconPath), OpenSettingDialog = () => App.Window.OpenSettingDialog(), - ShowCurrentResultItemTooltip = (msg) => App.Window.ShowCurrentResultItemTooltip(msg) + ShowCurrentResultItemTooltip = (msg) => App.Window.ShowCurrentResultItemTooltip(msg), + ReloadPlugins = ()=> Init() })); } }