fix #46 Reload index cache when the file changed in index directories

This commit is contained in:
qianlifeng 2014-08-14 22:21:07 +08:00
parent 8eb2f66b14
commit 13e629e17d
7 changed files with 124 additions and 56 deletions

View file

@ -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<string> watchedPath = new List<string>();
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;
});
}
}
}
}

View file

@ -28,7 +28,7 @@ namespace Wox.Plugin.SystemPlugins.Program
ThreadPool.QueueUserWorkItem(t => ThreadPool.QueueUserWorkItem(t =>
{ {
Dispatcher.Invoke(new Action(() => { indexingPanel.Visibility = Visibility.Visible; })); Dispatcher.Invoke(new Action(() => { indexingPanel.Visibility = Visibility.Visible; }));
Programs.LoadPrograms(); Programs.IndexPrograms();
Dispatcher.Invoke(new Action(() => { indexingPanel.Visibility = Visibility.Hidden; })); Dispatcher.Invoke(new Action(() => { indexingPanel.Visibility = Visibility.Hidden; }));
}); });
} }

View file

@ -22,7 +22,6 @@ namespace Wox.Plugin.SystemPlugins.Program.ProgramSources
var list = new List<Program>(); var list = new List<Program>();
ReadAppPaths(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths", 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 ReadAppPaths(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\App Paths", list); //TODO: need test more on 64-bit
return list; return list;
} }

View file

@ -10,7 +10,6 @@ namespace Wox.Plugin.SystemPlugins.Program.ProgramSources
{ {
[DllImport("shell32.dll")] [DllImport("shell32.dll")]
static extern bool SHGetSpecialFolderPath(IntPtr hwndOwner, [Out] StringBuilder lpszPath, int nFolder, bool fCreate); 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; const int CSIDL_COMMON_PROGRAMS = 0x17;
private static string getPath() private static string getPath()

View file

@ -1,4 +1,6 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Wox.Infrastructure.Storage.UserSettings; using Wox.Infrastructure.Storage.UserSettings;
@ -7,15 +9,14 @@ namespace Wox.Plugin.SystemPlugins.Program.ProgramSources
{ {
public class FileSystemProgramSource : AbstractProgramSource public class FileSystemProgramSource : AbstractProgramSource
{ {
public string BaseDirectory; private string baseDirectory;
public FileSystemProgramSource(string baseDirectory) public FileSystemProgramSource(string baseDirectory)
{ {
BaseDirectory = baseDirectory; this.baseDirectory = baseDirectory;
} }
public FileSystemProgramSource(ProgramSource source) public FileSystemProgramSource(ProgramSource source):this(source.Location)
: this(source.Location)
{ {
this.BonusPoints = source.BonusPoints; this.BonusPoints = source.BonusPoints;
} }
@ -23,33 +24,41 @@ namespace Wox.Plugin.SystemPlugins.Program.ProgramSources
public override List<Program> LoadPrograms() public override List<Program> LoadPrograms()
{ {
List<Program> list = new List<Program>(); List<Program> list = new List<Program>();
if (Directory.Exists(BaseDirectory)) if (Directory.Exists(baseDirectory))
{ {
GetAppFromDirectory(BaseDirectory, list); GetAppFromDirectory(baseDirectory, list);
FileChangeWatcher.AddWatch(baseDirectory);
} }
return list; return list;
} }
private void GetAppFromDirectory(string path, List<Program> list) private void GetAppFromDirectory(string path, List<Program> 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); if (UserSettingStorage.Instance.ProgramSuffixes.Split(';').Any(o => file.EndsWith("." + o)))
list.Add(p); {
Program p = CreateEntry(file);
list.Add(p);
}
}
foreach (var subDirectory in Directory.GetDirectories(path))
{
GetAppFromDirectory(subDirectory, list);
} }
} }
catch (UnauthorizedAccessException e)
foreach (var subDirectory in Directory.GetDirectories(path))
{ {
GetAppFromDirectory(subDirectory, list); Debug.WriteLine(string.Format("Can't access to directory {0}",path),"WoxDebug");
} }
} }
public override string ToString() public override string ToString()
{ {
return typeof(FileSystemProgramSource).Name + ":" + this.BaseDirectory; return typeof(FileSystemProgramSource).Name + ":" + this.baseDirectory;
} }
} }
} }

View file

@ -10,7 +10,7 @@ namespace Wox.Plugin.SystemPlugins.Program
{ {
public class Programs : BaseSystemPlugin, ISettingProvider public class Programs : BaseSystemPlugin, ISettingProvider
{ {
public static bool Initing = false; private static bool initing;
private static object lockObject = new object(); private static object lockObject = new object();
private static List<Program> programs = new List<Program>(); private static List<Program> programs = new List<Program>();
private static List<IProgramSource> sources = new List<IProgramSource>(); private static List<IProgramSource> sources = new List<IProgramSource>();
@ -59,55 +59,59 @@ namespace Wox.Plugin.SystemPlugins.Program
protected override void InitInternal(PluginInitContext context) protected override void InitInternal(PluginInitContext context)
{ {
this.context = context; this.context = context;
LoadPrograms(); IndexPrograms();
} }
public static void LoadPrograms() public static void IndexPrograms()
{ {
lock (lockObject) if (!initing)
{ {
Initing = true; lock (lockObject)
List<ProgramSource> programSources = new List<ProgramSource>();
programSources.AddRange(LoadDeaultProgramSources());
if (UserSettingStorage.Instance.ProgramSources != null &&
UserSettingStorage.Instance.ProgramSources.Count(o => o.Enabled) > 0)
{ {
programSources.AddRange(UserSettingStorage.Instance.ProgramSources.Where(o => o.Enabled)); initing = true;
}
programSources.ForEach(source => List<ProgramSource> programSources = new List<ProgramSource>();
{ programSources.AddRange(LoadDeaultProgramSources());
Type sourceClass; if (UserSettingStorage.Instance.ProgramSources != null &&
if (SourceTypes.TryGetValue(source.Type, out sourceClass)) UserSettingStorage.Instance.ProgramSources.Count(o => o.Enabled) > 0)
{ {
ConstructorInfo constructorInfo = sourceClass.GetConstructor(new[] { typeof(ProgramSource) }); programSources.AddRange(UserSettingStorage.Instance.ProgramSources.Where(o => o.Enabled));
if (constructorInfo != null)
{
IProgramSource programSource =
constructorInfo.Invoke(new object[] { source }) as IProgramSource;
sources.Add(programSource);
}
} }
});
var tempPrograms = new List<Program>(); sources.Clear();
foreach (var source in sources) programSources.ForEach(source =>
{
var list = source.LoadPrograms();
list.ForEach(o =>
{ {
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<Program>();
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;
} }
} }

View file

@ -65,6 +65,7 @@
<Compile Include="Folder\FolderPluginSettings.xaml.cs"> <Compile Include="Folder\FolderPluginSettings.xaml.cs">
<DependentUpon>FolderPluginSettings.xaml</DependentUpon> <DependentUpon>FolderPluginSettings.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Program\FileChangeWatcher.cs" />
<Compile Include="Program\Program.cs" /> <Compile Include="Program\Program.cs" />
<Compile Include="Program\ProgramSetting.xaml.cs"> <Compile Include="Program\ProgramSetting.xaml.cs">
<DependentUpon>ProgramSetting.xaml</DependentUpon> <DependentUpon>ProgramSetting.xaml</DependentUpon>