From 13e629e17dd9bd1bfebc6db04dcfc920ec0afa8f Mon Sep 17 00:00:00 2001 From: qianlifeng Date: Thu, 14 Aug 2014 22:21:07 +0800 Subject: [PATCH] fix #46 Reload index cache when the file changed in index directories --- .../Program/FileChangeWatcher.cs | 56 +++++++++++++ .../Program/ProgramSetting.xaml.cs | 2 +- .../ProgramSources/AppPathsProgramSource.cs | 1 - .../CommonStartMenuProgramSource.cs | 1 - .../ProgramSources/FileSystemProgramSource.cs | 39 +++++---- Wox.Plugin.SystemPlugins/Program/Programs.cs | 80 ++++++++++--------- .../Wox.Plugin.SystemPlugins.csproj | 1 + 7 files changed, 124 insertions(+), 56 deletions(-) create mode 100644 Wox.Plugin.SystemPlugins/Program/FileChangeWatcher.cs diff --git a/Wox.Plugin.SystemPlugins/Program/FileChangeWatcher.cs b/Wox.Plugin.SystemPlugins/Program/FileChangeWatcher.cs new file mode 100644 index 0000000000..4c007cac95 --- /dev/null +++ b/Wox.Plugin.SystemPlugins/Program/FileChangeWatcher.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using Wox.Infrastructure.Storage.UserSettings; + +namespace Wox.Plugin.SystemPlugins.Program +{ + internal class FileChangeWatcher + { + private static bool isIndexing = false; + private static List watchedPath = new List(); + + public static void AddWatch(string path, bool includingSubDirectory = true) + { + if (watchedPath.Contains(path)) return; + if (!Directory.Exists(path)) + { + Debug.WriteLine(string.Format("FileChangeWatcher: {0} doesn't exist", path),"WoxDebug"); + return; + } + + watchedPath.Add(path); + foreach (string fileType in UserSettingStorage.Instance.ProgramSuffixes.Split(';')) + { + FileSystemWatcher watcher = new FileSystemWatcher + { + Path = path, + IncludeSubdirectories = includingSubDirectory, + Filter = string.Format("*.{0}", fileType), + EnableRaisingEvents = true + }; + watcher.Changed += FileChanged; + watcher.Created += FileChanged; + watcher.Deleted += FileChanged; + watcher.Renamed += FileChanged; + } + } + + private static void FileChanged(object source, FileSystemEventArgs e) + { + if (!isIndexing) + { + ThreadPool.QueueUserWorkItem(o => + { + Programs.IndexPrograms(); + isIndexing = false; + }); + } + } + + } +} diff --git a/Wox.Plugin.SystemPlugins/Program/ProgramSetting.xaml.cs b/Wox.Plugin.SystemPlugins/Program/ProgramSetting.xaml.cs index dded9ae5d2..a1b750b428 100644 --- a/Wox.Plugin.SystemPlugins/Program/ProgramSetting.xaml.cs +++ b/Wox.Plugin.SystemPlugins/Program/ProgramSetting.xaml.cs @@ -28,7 +28,7 @@ namespace Wox.Plugin.SystemPlugins.Program ThreadPool.QueueUserWorkItem(t => { Dispatcher.Invoke(new Action(() => { indexingPanel.Visibility = Visibility.Visible; })); - Programs.LoadPrograms(); + Programs.IndexPrograms(); Dispatcher.Invoke(new Action(() => { indexingPanel.Visibility = Visibility.Hidden; })); }); } diff --git a/Wox.Plugin.SystemPlugins/Program/ProgramSources/AppPathsProgramSource.cs b/Wox.Plugin.SystemPlugins/Program/ProgramSources/AppPathsProgramSource.cs index f6777e93e4..1cc37b8747 100644 --- a/Wox.Plugin.SystemPlugins/Program/ProgramSources/AppPathsProgramSource.cs +++ b/Wox.Plugin.SystemPlugins/Program/ProgramSources/AppPathsProgramSource.cs @@ -22,7 +22,6 @@ namespace Wox.Plugin.SystemPlugins.Program.ProgramSources var list = new List(); ReadAppPaths(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths", list); ReadAppPaths(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\App Paths", list); //TODO: need test more on 64-bit - return list; } diff --git a/Wox.Plugin.SystemPlugins/Program/ProgramSources/CommonStartMenuProgramSource.cs b/Wox.Plugin.SystemPlugins/Program/ProgramSources/CommonStartMenuProgramSource.cs index 9e940faf8e..67910e2625 100644 --- a/Wox.Plugin.SystemPlugins/Program/ProgramSources/CommonStartMenuProgramSource.cs +++ b/Wox.Plugin.SystemPlugins/Program/ProgramSources/CommonStartMenuProgramSource.cs @@ -10,7 +10,6 @@ namespace Wox.Plugin.SystemPlugins.Program.ProgramSources { [DllImport("shell32.dll")] static extern bool SHGetSpecialFolderPath(IntPtr hwndOwner, [Out] StringBuilder lpszPath, int nFolder, bool fCreate); - const int CSIDL_COMMON_STARTMENU = 0x16; // \Windows\Start Menu\Programs const int CSIDL_COMMON_PROGRAMS = 0x17; private static string getPath() diff --git a/Wox.Plugin.SystemPlugins/Program/ProgramSources/FileSystemProgramSource.cs b/Wox.Plugin.SystemPlugins/Program/ProgramSources/FileSystemProgramSource.cs index 28e00f7fb3..ec30bf5021 100644 --- a/Wox.Plugin.SystemPlugins/Program/ProgramSources/FileSystemProgramSource.cs +++ b/Wox.Plugin.SystemPlugins/Program/ProgramSources/FileSystemProgramSource.cs @@ -1,4 +1,6 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using Wox.Infrastructure.Storage.UserSettings; @@ -7,15 +9,14 @@ namespace Wox.Plugin.SystemPlugins.Program.ProgramSources { public class FileSystemProgramSource : AbstractProgramSource { - public string BaseDirectory; + private string baseDirectory; public FileSystemProgramSource(string baseDirectory) { - BaseDirectory = baseDirectory; + this.baseDirectory = baseDirectory; } - public FileSystemProgramSource(ProgramSource source) - : this(source.Location) + public FileSystemProgramSource(ProgramSource source):this(source.Location) { this.BonusPoints = source.BonusPoints; } @@ -23,33 +24,41 @@ namespace Wox.Plugin.SystemPlugins.Program.ProgramSources public override List LoadPrograms() { List list = new List(); - if (Directory.Exists(BaseDirectory)) + if (Directory.Exists(baseDirectory)) { - GetAppFromDirectory(BaseDirectory, list); + GetAppFromDirectory(baseDirectory, list); + FileChangeWatcher.AddWatch(baseDirectory); } return list; } private void GetAppFromDirectory(string path, List list) { - foreach (string file in Directory.GetFiles(path)) + try { - if (UserSettingStorage.Instance.ProgramSuffixes.Split(';').Any(o => file.EndsWith("." + o))) + foreach (string file in Directory.GetFiles(path)) { - Program p = CreateEntry(file); - list.Add(p); + if (UserSettingStorage.Instance.ProgramSuffixes.Split(';').Any(o => file.EndsWith("." + o))) + { + Program p = CreateEntry(file); + list.Add(p); + } + } + + foreach (var subDirectory in Directory.GetDirectories(path)) + { + GetAppFromDirectory(subDirectory, list); } } - - foreach (var subDirectory in Directory.GetDirectories(path)) + catch (UnauthorizedAccessException e) { - GetAppFromDirectory(subDirectory, list); + Debug.WriteLine(string.Format("Can't access to directory {0}",path),"WoxDebug"); } } public override string ToString() { - return typeof(FileSystemProgramSource).Name + ":" + this.BaseDirectory; + return typeof(FileSystemProgramSource).Name + ":" + this.baseDirectory; } } } diff --git a/Wox.Plugin.SystemPlugins/Program/Programs.cs b/Wox.Plugin.SystemPlugins/Program/Programs.cs index 5665d9ae72..ff87a84667 100644 --- a/Wox.Plugin.SystemPlugins/Program/Programs.cs +++ b/Wox.Plugin.SystemPlugins/Program/Programs.cs @@ -10,7 +10,7 @@ namespace Wox.Plugin.SystemPlugins.Program { public class Programs : BaseSystemPlugin, ISettingProvider { - public static bool Initing = false; + private static bool initing; private static object lockObject = new object(); private static List programs = new List(); private static List sources = new List(); @@ -59,55 +59,59 @@ namespace Wox.Plugin.SystemPlugins.Program protected override void InitInternal(PluginInitContext context) { this.context = context; - LoadPrograms(); + IndexPrograms(); } - public static void LoadPrograms() + public static void IndexPrograms() { - lock (lockObject) + if (!initing) { - Initing = true; - - List programSources = new List(); - programSources.AddRange(LoadDeaultProgramSources()); - if (UserSettingStorage.Instance.ProgramSources != null && - UserSettingStorage.Instance.ProgramSources.Count(o => o.Enabled) > 0) + lock (lockObject) { - programSources.AddRange(UserSettingStorage.Instance.ProgramSources.Where(o => o.Enabled)); - } + initing = true; - programSources.ForEach(source => - { - Type sourceClass; - if (SourceTypes.TryGetValue(source.Type, out sourceClass)) + List programSources = new List(); + programSources.AddRange(LoadDeaultProgramSources()); + if (UserSettingStorage.Instance.ProgramSources != null && + UserSettingStorage.Instance.ProgramSources.Count(o => o.Enabled) > 0) { - ConstructorInfo constructorInfo = sourceClass.GetConstructor(new[] { typeof(ProgramSource) }); - if (constructorInfo != null) - { - IProgramSource programSource = - constructorInfo.Invoke(new object[] { source }) as IProgramSource; - sources.Add(programSource); - } + programSources.AddRange(UserSettingStorage.Instance.ProgramSources.Where(o => o.Enabled)); } - }); - var tempPrograms = new List(); - foreach (var source in sources) - { - var list = source.LoadPrograms(); - list.ForEach(o => + sources.Clear(); + programSources.ForEach(source => { - o.Source = source; + Type sourceClass; + if (SourceTypes.TryGetValue(source.Type, out sourceClass)) + { + ConstructorInfo constructorInfo = sourceClass.GetConstructor(new[] {typeof (ProgramSource)}); + if (constructorInfo != null) + { + IProgramSource programSource = + constructorInfo.Invoke(new object[] {source}) as IProgramSource; + sources.Add(programSource); + } + } }); - tempPrograms.AddRange(list); + + var tempPrograms = new List(); + foreach (var source in sources) + { + var list = source.LoadPrograms(); + list.ForEach(o => + { + o.Source = source; + }); + tempPrograms.AddRange(list); + } + + // filter duplicate program + tempPrograms = tempPrograms.GroupBy(x => new {x.ExecutePath, x.ExecuteName}) + .Select(g => g.First()).ToList(); + + programs = tempPrograms; + initing = false; } - - // filter duplicate program - tempPrograms = tempPrograms.GroupBy(x => new { x.ExecutePath, x.ExecuteName }) - .Select(g => g.First()).ToList(); - - programs = tempPrograms; - Initing = false; } } diff --git a/Wox.Plugin.SystemPlugins/Wox.Plugin.SystemPlugins.csproj b/Wox.Plugin.SystemPlugins/Wox.Plugin.SystemPlugins.csproj index 00c8e2d28e..e915bdf239 100644 --- a/Wox.Plugin.SystemPlugins/Wox.Plugin.SystemPlugins.csproj +++ b/Wox.Plugin.SystemPlugins/Wox.Plugin.SystemPlugins.csproj @@ -65,6 +65,7 @@ FolderPluginSettings.xaml + ProgramSetting.xaml