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.Infrastructure/UAC.cs b/Wox.Infrastructure/UAC.cs deleted file mode 100644 index 2ee5aff981..0000000000 --- a/Wox.Infrastructure/UAC.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Security.Principal; -using System.Text; -using System.Windows; -using System.Windows.Forms; -using System.Windows.Media.Imaging; -using Size = System.Drawing.Size; - -namespace Wox.Infrastructure -{ - - public static class UAC - { - /// - /// Execute methods that require Admin role, which will popup UAC window. - /// - /// Notes: - /// 1. Invoker method shouldn't have any parameters - /// 2. Add attribute [MethodImpl(MethodImplOptions.NoInlining)] to invoker method - /// - /// Example: - /// [MethodImpl(MethodImplOptions.NoInlining)] - /// private void OnStartWithWindowUnChecked() - /// { - /// UAC.ExecuteAdminMethod(() => SetStartup(false)); - /// } - /// - /// - /// - public static void ExecuteAdminMethod(Action method) - { - if (method == null) return; - if (Environment.OSVersion.Version.Major <= 5 || IsAdministrator()) - { - method(); - return; - } - - StackTrace stackTrace = new StackTrace(); - // Get calling method name - MethodBase callingMethod = stackTrace.GetFrame(1).GetMethod(); - string methodName = callingMethod.Name; - if (callingMethod.ReflectedType == null) return; - - string className = callingMethod.ReflectedType.Name; - string nameSpace = callingMethod.ReflectedType.Namespace; - string args = string.Format("UAC {0} {1} {2}", nameSpace,className,methodName); - Debug.WriteLine(args); - var psi = new ProcessStartInfo - { - FileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Wox.UAC.exe"), - Arguments = args, - CreateNoWindow = true, - Verb = "runas" - }; - - try - { - var process = new Process(); - process.StartInfo = psi; - process.Start(); - } - catch (Exception e) - { - MessageBox.Show("Execute failed: " + e); -#if (DEBUG) - { - throw; - } -#endif - - } - - } - - private static bool IsAdministrator() - { - var identity = WindowsIdentity.GetCurrent(); - if (identity != null) - { - var principal = new WindowsPrincipal(identity); - return principal.IsInRole(WindowsBuiltInRole.Administrator); - } - - return false; - } - } -} \ No newline at end of file diff --git a/Wox.Infrastructure/Wox.Infrastructure.csproj b/Wox.Infrastructure/Wox.Infrastructure.csproj index 723ebd6f0a..c34ad3a0ce 100644 --- a/Wox.Infrastructure/Wox.Infrastructure.csproj +++ b/Wox.Infrastructure/Wox.Infrastructure.csproj @@ -53,7 +53,6 @@ - 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.UAC/FileTypeAssociateInstaller.cs b/Wox.UAC/FileTypeAssociateInstaller.cs new file mode 100644 index 0000000000..e0ececd9cf --- /dev/null +++ b/Wox.UAC/FileTypeAssociateInstaller.cs @@ -0,0 +1,70 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Windows; +using ICSharpCode.SharpZipLib.Zip; +using Microsoft.Win32; +using Newtonsoft.Json; +using Wox.Plugin; + +namespace Wox.UAC +{ + public class FileTypeAssociateInstaller + { + [DllImport("shell32.dll")] + private static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2); + + /// + /// associate filetype with specified program + /// + /// + /// + /// + /// + private static void SaveReg(string filePath, string fileType, string iconPath, bool overrides) + { + RegistryKey classRootKey = Registry.ClassesRoot.OpenSubKey("", true); + RegistryKey woxKey = classRootKey.OpenSubKey(fileType, true); + if (woxKey != null) + { + if (!overrides) + { + return; + } + classRootKey.DeleteSubKeyTree(fileType); + } + classRootKey.CreateSubKey(fileType); + woxKey = classRootKey.OpenSubKey(fileType, true); + woxKey.SetValue("", "wox.wox"); + woxKey.SetValue("Content Type", "application/wox"); + + RegistryKey iconKey = woxKey.CreateSubKey("DefaultIcon"); + iconKey.SetValue("", iconPath); + + woxKey.CreateSubKey("shell"); + RegistryKey shellKey = woxKey.OpenSubKey("shell", true); + shellKey.SetValue("", "Open"); + RegistryKey openKey = shellKey.CreateSubKey("open"); + openKey.SetValue("", "Open with wox"); + + openKey = shellKey.OpenSubKey("open", true); + openKey.CreateSubKey("command"); + RegistryKey commandKey = openKey.OpenSubKey("command", true); + string pathString = "\"" + filePath + "\" \"installPlugin\" \"%1\""; + commandKey.SetValue("", pathString); + + //refresh cache + SHChangeNotify(0x8000000, 0, IntPtr.Zero, IntPtr.Zero); + } + + public void RegisterInstaller() + { + string filePath = Directory.GetCurrentDirectory() + "\\Wox.exe"; + string iconPath = Directory.GetCurrentDirectory() + "\\app.ico"; + + SaveReg(filePath, ".wox", iconPath, true); + } + + } +} diff --git a/Wox.UAC/MainWindow.xaml.cs b/Wox.UAC/MainWindow.xaml.cs index 9b8e500fc1..bcf8e9780a 100644 --- a/Wox.UAC/MainWindow.xaml.cs +++ b/Wox.UAC/MainWindow.xaml.cs @@ -6,7 +6,7 @@ namespace Wox.UAC { public partial class MainWindow : Window { - PluginInstaller installer = new PluginInstaller(); + FileTypeAssociateInstaller installer = new FileTypeAssociateInstaller(); public MainWindow() { @@ -16,32 +16,12 @@ namespace Wox.UAC { switch (param[1]) { - case "UAC": - Invoke(param[2], param[3], param[4]); - break; - case "AssociatePluginInstaller": installer.RegisterInstaller(); break; - - case "InstallPlugin": - var path = param[2]; - installer.Install(path); - break; } } Application.Current.Shutdown(0); } - - private static void Invoke(string namespaceName, string className, string methodName) - { - Type type = Type.GetType(namespaceName + "." + className + "," + namespaceName); - if (type != null) - { - object instance = Activator.CreateInstance(type); - MethodInfo method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); - if (method != null) method.Invoke(instance, null); - } - } } } diff --git a/Wox.UAC/Wox.UAC.csproj b/Wox.UAC/Wox.UAC.csproj index 57d5bf8398..c69e5857fb 100644 --- a/Wox.UAC/Wox.UAC.csproj +++ b/Wox.UAC/Wox.UAC.csproj @@ -82,7 +82,7 @@ - + Code diff --git a/Wox.sln b/Wox.sln index 2e910e6552..e07a5c6c06 100644 --- a/Wox.sln +++ b/Wox.sln @@ -25,7 +25,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 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wox.Plugin.Youdao", "Plugins\Wox.Plugin.Youdao\Wox.Plugin.Youdao.csproj", "{AE02E18E-2134-472B-9282-32CDE36B5F0C}" EndProject 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.UAC/PluginInstaller.cs b/Wox/Helper/PluginInstaller.cs similarity index 61% rename from Wox.UAC/PluginInstaller.cs rename to Wox/Helper/PluginInstaller.cs index 044a84c660..1780609713 100644 --- a/Wox.UAC/PluginInstaller.cs +++ b/Wox/Helper/PluginInstaller.cs @@ -1,106 +1,54 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Runtime.InteropServices; +using System.Linq; +using System.Text; using System.Windows; using ICSharpCode.SharpZipLib.Zip; -using Microsoft.Win32; using Newtonsoft.Json; using Wox.Plugin; +using Wox.PluginLoader; -namespace Wox.UAC +namespace Wox.Helper { public class PluginInstaller { - [DllImport("shell32.dll")] - private static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2); - /// - /// associate filetype with specified program - /// - /// - /// - /// - /// - private static void SaveReg(string filePath, string fileType, string iconPath, bool overrides) - { - RegistryKey classRootKey = Registry.ClassesRoot.OpenSubKey("", true); - RegistryKey woxKey = classRootKey.OpenSubKey(fileType, true); - if (woxKey != null) - { - if (!overrides) - { - return; - } - classRootKey.DeleteSubKeyTree(fileType); - } - classRootKey.CreateSubKey(fileType); - woxKey = classRootKey.OpenSubKey(fileType, true); - woxKey.SetValue("", "wox.wox"); - woxKey.SetValue("Content Type", "application/wox"); - - RegistryKey iconKey = woxKey.CreateSubKey("DefaultIcon"); - iconKey.SetValue("", iconPath); - - woxKey.CreateSubKey("shell"); - RegistryKey shellKey = woxKey.OpenSubKey("shell", true); - shellKey.SetValue("", "Open"); - RegistryKey openKey = shellKey.CreateSubKey("open"); - openKey.SetValue("", "Open with wox"); - - openKey = shellKey.OpenSubKey("open", true); - openKey.CreateSubKey("command"); - RegistryKey commandKey = openKey.OpenSubKey("command", true); - string pathString = "\"" + filePath + "\" \"installPlugin\" \"%1\""; - commandKey.SetValue("", pathString); - - //refresh cache - SHChangeNotify(0x8000000, 0, IntPtr.Zero, IntPtr.Zero); - } - - public void RegisterInstaller() - { - string filePath = Directory.GetCurrentDirectory() + "\\Wox.UAC.exe"; - string iconPath = Directory.GetCurrentDirectory() + "\\app.ico"; - - SaveReg(filePath, ".wox", iconPath, true); - } - - public void Install(string path) + public static void Install(string path) { 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)) { @@ -113,7 +61,7 @@ namespace Wox.UAC 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); } } @@ -129,27 +77,18 @@ namespace Wox.UAC 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."); } } } private static PluginMetadata GetMetadataFromJson(string pluginDirectory) - { + { string configPath = Path.Combine(pluginDirectory, "plugin.json"); PluginMetadata metadata; @@ -208,7 +147,7 @@ namespace Wox.UAC /// The ziped file. /// The STR directory. /// overwirte - private void UnZip(string zipedFile, string strDirectory, bool overWrite) + private static void UnZip(string zipedFile, string strDirectory, bool overWrite) { if (strDirectory == "") strDirectory = Directory.GetCurrentDirectory(); diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs index 80f2f2482a..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,13 @@ namespace Wox private bool queryHasReturn; private ToolTip toolTip = new ToolTip(); - public MainWindow() { InitializeComponent(); + Initialized = true; + + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; + progressBar.ToolTip = toolTip; InitialTray(); resultCtrl.OnMouseClickItem += AcceptSelect; @@ -62,6 +66,29 @@ 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) + { + if (!System.Diagnostics.Debugger.IsAttached) + { + string error = "Wox has an error that can't be handled. " + e.ExceptionObject; + Log.Error(error); + if (e.IsTerminating) + { + notifyIcon.Visible = false; + MessageBox.Show(error); + } + } } public void SetHotkey(string hotkeyStr, EventHandler action) @@ -214,21 +241,22 @@ namespace Wox case "hidestart": HideApp(); break; + + case "installplugin": + var path = args[1]; + if (!File.Exists(path)) + { + MessageBox.Show("Plugin " + path + " didn't exist"); + return; + } + PluginInstaller.Install(path); + break; } } } - 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() })); } } diff --git a/Wox/SettingWindow.xaml b/Wox/SettingWindow.xaml index 5c3c5f390b..442f34085f 100644 --- a/Wox/SettingWindow.xaml +++ b/Wox/SettingWindow.xaml @@ -23,7 +23,9 @@ - + + + diff --git a/Wox/SettingWindow.xaml.cs b/Wox/SettingWindow.xaml.cs index e2999dbd47..919cf73d64 100644 --- a/Wox/SettingWindow.xaml.cs +++ b/Wox/SettingWindow.xaml.cs @@ -1,24 +1,22 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Security.Permissions; using System.Windows; using System.Windows.Controls; -using System.Windows.Forms; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using Microsoft.Win32; -using Wox.Helper; +using IWshRuntimeLibrary; using Wox.Infrastructure; using Wox.Infrastructure.UserSettings; +using Application = System.Windows.Forms.Application; +using File = System.IO.File; using MessageBox = System.Windows.MessageBox; namespace Wox { public partial class SettingWidow : Window { + string woxLinkPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Startup), "wox.lnk"); public MainWindow MainWindow; public SettingWidow() @@ -33,8 +31,6 @@ namespace Wox Loaded += Setting_Loaded; } - - private void Setting_Loaded(object sender, RoutedEventArgs ev) { ctlHotkey.OnHotkeyChanged += ctlHotkey_OnHotkeyChanged; @@ -60,7 +56,7 @@ namespace Wox cbReplaceWinR.IsChecked = CommonStorage.Instance.UserSetting.ReplaceWinR; webSearchView.ItemsSource = CommonStorage.Instance.UserSetting.WebSearches; lvCustomHotkey.ItemsSource = CommonStorage.Instance.UserSetting.CustomPluginHotkeys; - cbStartWithWindows.IsChecked = CommonStorage.Instance.UserSetting.StartWoxOnSystemStartup; + cbStartWithWindows.IsChecked = File.Exists(woxLinkPath); } public void ReloadWebSearchView() @@ -121,50 +117,30 @@ namespace Wox private void CbStartWithWindows_OnChecked(object sender, RoutedEventArgs e) { - if (!CommonStorage.Instance.UserSetting.StartWoxOnSystemStartup) - { - CommonStorage.Instance.UserSetting.StartWoxOnSystemStartup = true; - OnStartWithWindowsChecked(); - CommonStorage.Instance.Save(); - } + CreateStartupFolderShortcut(); } private void CbStartWithWindows_OnUnchecked(object sender, RoutedEventArgs e) { - CommonStorage.Instance.UserSetting.StartWoxOnSystemStartup = false; - OnStartWithWindowUnChecked(); - CommonStorage.Instance.Save(); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private void OnStartWithWindowUnChecked() - { - UAC.ExecuteAdminMethod(() => SetStartup(false)); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private void OnStartWithWindowsChecked() - { - UAC.ExecuteAdminMethod(() => SetStartup(true)); - } - - private void SetStartup(bool startup) - { - RegistryKey rk = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true); - - if (rk != null) + if (File.Exists(woxLinkPath)) { - if (startup) - { - rk.SetValue("Wox", Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Wox.exe hidestart")); - } - else - { - rk.DeleteValue("Wox", false); - } + File.Delete(woxLinkPath); } } + private void CreateStartupFolderShortcut() + { + WshShellClass wshShell = new WshShellClass(); + + IWshShortcut shortcut = (IWshShortcut)wshShell.CreateShortcut(woxLinkPath); + shortcut.TargetPath = Application.ExecutablePath; + shortcut.Arguments = "hideStart"; + shortcut.WorkingDirectory = Application.StartupPath; + shortcut.Description = "Launch Wox"; + shortcut.IconLocation = Application.StartupPath + @"\App.ico"; + shortcut.Save(); + } + void ctlHotkey_OnHotkeyChanged(object sender, System.EventArgs e) { if (ctlHotkey.CurrentHotkeyAvailable) @@ -192,7 +168,7 @@ namespace Wox { CustomPluginHotkey item = lvCustomHotkey.SelectedItem as CustomPluginHotkey; if (item != null && - MessageBox.Show("Are your sure to delete " + item.Hotkey + " plugin hotkey?","Delete Custom Plugin Hotkey", + MessageBox.Show("Are your sure to delete " + item.Hotkey + " plugin hotkey?", "Delete Custom Plugin Hotkey", MessageBoxButton.YesNo) == MessageBoxResult.Yes) { CommonStorage.Instance.UserSetting.CustomPluginHotkeys.Remove(item); @@ -233,6 +209,9 @@ namespace Wox #endregion - + private void BtnEnableInstaller_OnClick(object sender, RoutedEventArgs e) + { + Process.Start("Wox.UAC.exe", "AssociatePluginInstaller"); + } } } diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj index e120aef13c..3506ed8de6 100644 --- a/Wox/Wox.csproj +++ b/Wox/Wox.csproj @@ -130,6 +130,7 @@ + @@ -290,6 +291,26 @@ + + + {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} + 1 + 0 + 0 + tlbimp + False + True + + + {50A7E9B0-70EF-11D1-B75A-00A0C90564FE} + 1 + 0 + 0 + tlbimp + False + True + +