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 =>
{
Dispatcher.Invoke(new Action(() => { indexingPanel.Visibility = Visibility.Visible; }));
Programs.LoadPrograms();
Programs.IndexPrograms();
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>();
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;
}

View File

@@ -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()

View File

@@ -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<Program> LoadPrograms()
{
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;
}
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);
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;
}
}
}

View File

@@ -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<Program> programs = new List<Program>();
private static List<IProgramSource> sources = new List<IProgramSource>();
@@ -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<ProgramSource> programSources = new List<ProgramSource>();
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<ProgramSource> programSources = new List<ProgramSource>();
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<Program>();
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<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">
<DependentUpon>FolderPluginSettings.xaml</DependentUpon>
</Compile>
<Compile Include="Program\FileChangeWatcher.cs" />
<Compile Include="Program\Program.cs" />
<Compile Include="Program\ProgramSetting.xaml.cs">
<DependentUpon>ProgramSetting.xaml</DependentUpon>