Program plugin: remove complicated inheritance

This commit is contained in:
bao-qian
2016-07-21 19:51:47 +01:00
parent 0c9015bb77
commit 1de68051e3
13 changed files with 93 additions and 187 deletions

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Windows;
using System.Windows.Forms;
using Wox.Plugin.Program.ProgramSources;
namespace Wox.Plugin.Program
{
@@ -9,7 +10,7 @@ namespace Wox.Plugin.Program
/// </summary>
public partial class AddProgramSource
{
private ProgramSource _editing;
private FileSystemProgramSource _editing;
private Settings _settings;
public AddProgramSource(Settings settings)
@@ -20,7 +21,7 @@ namespace Wox.Plugin.Program
Directory.Focus();
}
public AddProgramSource(ProgramSource edit, Settings settings)
public AddProgramSource(FileSystemProgramSource edit, Settings settings)
{
_editing = edit;
_settings = settings;
@@ -51,12 +52,11 @@ namespace Wox.Plugin.Program
if(_editing == null)
{
var source = new ProgramSource
var source = new FileSystemProgramSource
{
Location = Directory.Text,
MaxDepth = max,
Suffixes = Suffixes.Text.Split(ProgramSource.SuffixSeperator),
Type = "FileSystemProgramSource",
Enabled = true
};
_settings.ProgramSources.Add(source);

View File

@@ -16,14 +16,6 @@ namespace Wox.Plugin.Program
{
private static readonly object IndexLock = new object();
private static List<Program> _programs = new List<Program>();
private static List<IProgramSource> _sources = new List<IProgramSource>();
private static readonly Dictionary<string, Type> SourceTypes = new Dictionary<string, Type>
{
{"FileSystemProgramSource", typeof(FileSystemProgramSource)},
{"CommonStartMenuProgramSource", typeof(CommonStartMenuProgramSource)},
{"UserStartMenuProgramSource", typeof(UserStartMenuProgramSource)},
{"AppPathsProgramSource", typeof(AppPathsProgramSource)}
};
private PluginInitContext _context;
@@ -105,18 +97,7 @@ namespace Wox.Plugin.Program
sources.AddRange(_settings.ProgramSources);
}
_sources = sources.AsParallel()
.Where(s => s.Enabled && SourceTypes.ContainsKey(s.Type))
.Select(s =>
{
var sourceClass = SourceTypes[s.Type];
var constructorInfo = sourceClass.GetConstructor(new[] { typeof(ProgramSource) });
var programSource = constructorInfo?.Invoke(new object[] { s }) as IProgramSource;
return programSource;
})
.Where(s => s != null).ToList();
_programs = _sources.AsParallel()
_programs = sources.AsParallel()
.SelectMany(s => s.LoadPrograms())
// filter duplicate program
.GroupBy(x => new { ExecutePath = x.Path, ExecuteName = x.ExecutableName })
@@ -134,23 +115,20 @@ namespace Wox.Plugin.Program
{
var list = new List<ProgramSource>
{
new ProgramSource
new CommonStartMenuProgramSource
{
BonusPoints = 0,
Enabled = _settings.EnableStartMenuSource,
Type = "CommonStartMenuProgramSource"
},
new ProgramSource
new UserStartMenuProgramSource
{
BonusPoints = 0,
Enabled = _settings.EnableStartMenuSource,
Type = "UserStartMenuProgramSource"
},
new ProgramSource
new AppPathsProgramSource
{
BonusPoints = -10,
Enabled = _settings.EnableRegistrySource,
Type = "AppPathsProgramSource"
}
};
return list;

View File

@@ -2,6 +2,7 @@ using System;
using System.Text.RegularExpressions;
using System.Threading;
using Wox.Infrastructure;
using Wox.Plugin.Program.ProgramSources;
namespace Wox.Plugin.Program
{
@@ -14,6 +15,6 @@ namespace Wox.Plugin.Program
public string Directory { get; set; }
public string ExecutableName { get; set; }
public int Score { get; set; }
public IProgramSource Source { get; set; }
public ProgramSource Source { get; set; }
}
}

View File

@@ -2,6 +2,7 @@
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using Wox.Plugin.Program.ProgramSources;
namespace Wox.Plugin.Program
{
@@ -50,7 +51,7 @@ namespace Wox.Plugin.Program
private void btnDeleteProgramSource_OnClick(object sender, RoutedEventArgs e)
{
ProgramSource selectedProgramSource = programSourceView.SelectedItem as ProgramSource;
var selectedProgramSource = programSourceView.SelectedItem as FileSystemProgramSource;
if (selectedProgramSource != null)
{
string msg = string.Format(context.API.GetTranslation("wox_plugin_program_delete_program_source"), selectedProgramSource.Location);
@@ -70,7 +71,7 @@ namespace Wox.Plugin.Program
private void btnEditProgramSource_OnClick(object sender, RoutedEventArgs e)
{
ProgramSource selectedProgramSource = programSourceView.SelectedItem as ProgramSource;
var selectedProgramSource = programSourceView.SelectedItem as FileSystemProgramSource;
if (selectedProgramSource != null)
{
var add = new AddProgramSource(selectedProgramSource, _settings);
@@ -119,10 +120,9 @@ namespace Wox.Plugin.Program
{
if (Directory.Exists(s))
{
_settings.ProgramSources.Add(new ProgramSource
_settings.ProgramSources.Add(new FileSystemProgramSource
{
Location = s,
Type = "FileSystemProgramSource",
Enabled = true
});

View File

@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using Microsoft.Win32;
using Wox.Infrastructure.Logger;
@@ -8,24 +7,19 @@ using Wox.Infrastructure.Logger;
namespace Wox.Plugin.Program.ProgramSources
{
[Serializable]
[Browsable(false)]
public class AppPathsProgramSource : AbstractProgramSource
public class AppPathsProgramSource : ProgramSource
{
public AppPathsProgramSource()
{
BonusPoints = -10;
}
public AppPathsProgramSource(ProgramSource source) : this()
{
BonusPoints = source.BonusPoints;
}
public override List<Program> LoadPrograms()
{
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
ReadAppPaths(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\App Paths", list);
//TODO: need test more on 64-bit
return list;
}
@@ -40,12 +34,12 @@ namespace Wox.Plugin.Program.ProgramSources
{
using (var key = root.OpenSubKey(item))
{
string path = key.GetValue("") as string;
var path = key.GetValue("") as string;
if (string.IsNullOrEmpty(path)) continue;
// fix path like this ""\"C:\\folder\\executable.exe\"""
const int begin = 0;
int end = path.Length - 1;
var end = path.Length - 1;
const char quotationMark = '"';
if (path[begin] == quotationMark && path[end] == quotationMark)
{
@@ -66,10 +60,5 @@ namespace Wox.Plugin.Program.ProgramSources
}
}
}
public override string ToString()
{
return typeof(AppPathsProgramSource).Name;
}
}
}
}

View File

@@ -1,40 +1,30 @@
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
namespace Wox.Plugin.Program.ProgramSources
{
[Serializable]
[Browsable(false)]
public class CommonStartMenuProgramSource : FileSystemProgramSource
public sealed class CommonStartMenuProgramSource : FileSystemProgramSource
{
private const int CSIDL_COMMON_PROGRAMS = 0x17;
// todo happlebao how to pass location before loadPrograms
public CommonStartMenuProgramSource()
{
Location = getPath();
}
[DllImport("shell32.dll")]
static extern bool SHGetSpecialFolderPath(IntPtr hwndOwner, [Out] StringBuilder lpszPath, int nFolder, bool fCreate);
const int CSIDL_COMMON_PROGRAMS = 0x17;
private static extern bool SHGetSpecialFolderPath(IntPtr hwndOwner, [Out] StringBuilder lpszPath, int nFolder,
bool fCreate);
private static string getPath()
{
StringBuilder commonStartMenuPath = new StringBuilder(560);
var commonStartMenuPath = new StringBuilder(560);
SHGetSpecialFolderPath(IntPtr.Zero, commonStartMenuPath, CSIDL_COMMON_PROGRAMS, false);
return commonStartMenuPath.ToString();
}
public CommonStartMenuProgramSource(string[] suffixes)
: base(getPath(), suffixes)
{
}
public CommonStartMenuProgramSource(ProgramSource source)
: this(source.Suffixes)
{
BonusPoints = source.BonusPoints;
}
public override string ToString()
{
return typeof(CommonStartMenuProgramSource).Name;
}
}
}
}

View File

@@ -8,35 +8,17 @@ using Wox.Infrastructure.Logger;
namespace Wox.Plugin.Program.ProgramSources
{
[Serializable]
public class FileSystemProgramSource : AbstractProgramSource
public class FileSystemProgramSource : ProgramSource
{
private string _baseDirectory;
private int _maxDepth;
private string[] _suffixes;
public FileSystemProgramSource(string baseDirectory, int maxDepth, string[] suffixes)
{
_baseDirectory = baseDirectory;
_maxDepth = maxDepth;
_suffixes = suffixes;
}
public FileSystemProgramSource(string baseDirectory, string[] suffixes)
: this(baseDirectory, -1, suffixes) {}
public FileSystemProgramSource(ProgramSource source)
: this(source.Location, source.MaxDepth, source.Suffixes)
{
BonusPoints = source.BonusPoints;
}
public string Location { get; set; } = "";
public override List<Program> LoadPrograms()
{
List<Program> list = new List<Program>();
if (Directory.Exists(_baseDirectory))
var list = new List<Program>();
if (Directory.Exists(Location))
{
GetAppFromDirectory(_baseDirectory, list);
FileChangeWatcher.AddWatch(_baseDirectory, _suffixes);
GetAppFromDirectory(Location, list);
FileChangeWatcher.AddWatch(Location, Suffixes);
}
return list;
}
@@ -48,17 +30,17 @@ namespace Wox.Plugin.Program.ProgramSources
private void GetAppFromDirectory(string path, List<Program> list, int depth)
{
if(_maxDepth != -1 && depth > _maxDepth)
if (MaxDepth != -1 && depth > MaxDepth)
{
return;
}
try
{
foreach (string file in Directory.GetFiles(path))
foreach (var file in Directory.GetFiles(path))
{
if (_suffixes.Any(o => file.EndsWith("." + o)))
if (Suffixes.Any(o => file.EndsWith("." + o)))
{
Program p = CreateEntry(file);
var p = CreateEntry(file);
p.Source = this;
list.Add(p);
}
@@ -75,10 +57,10 @@ namespace Wox.Plugin.Program.ProgramSources
Log.Exception(woxPluginException);
}
}
public override string ToString()
{
return typeof(FileSystemProgramSource).Name + ":" + _baseDirectory;
var display = GetType().Name + Location;
return display;
}
}
}
}

View File

@@ -1,49 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
namespace Wox.Plugin.Program
{
public interface IProgramSource
{
List<Program> LoadPrograms();
int BonusPoints { get; set; }
}
[Serializable]
public abstract class AbstractProgramSource : IProgramSource
{
public abstract List<Program> LoadPrograms();
public int BonusPoints { get; set; }
protected Program CreateEntry(string file)
{
var p = new Program
{
Title = Path.GetFileNameWithoutExtension(file),
IcoPath = file,
Path = file,
Directory = Directory.GetParent(file).FullName
};
switch (Path.GetExtension(file).ToLower())
{
case ".exe":
p.ExecutableName = Path.GetFileName(file);
try
{
FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(file);
if (!string.IsNullOrEmpty(versionInfo.FileDescription))
{
p.Title = versionInfo.FileDescription;
}
}
catch (Exception) { }
break;
}
return p;
}
}
}

View File

@@ -1,24 +1,51 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
namespace Wox.Plugin.Program
namespace Wox.Plugin.Program.ProgramSources
{
[Serializable]
public class ProgramSource
public abstract class ProgramSource
{
public string Location { get; set; }
public string Type { get; set; }
public int BonusPoints { get; set; }
public bool Enabled { get; set; }
public const char SuffixSeperator = ';';
public int BonusPoints { get; set; } = 0;
public bool Enabled { get; set; } = true;
// happlebao todo: temp hack for program suffixes
public string[] Suffixes { get; set; } = {"bat", "appref-ms", "exe", "lnk"};
public const char SuffixSeperator = ';';
public int MaxDepth { get; set; }
public Dictionary<string, string> Meta { get; set; }
public int MaxDepth { get; set; } = -1;
public override string ToString()
public abstract List<Program> LoadPrograms();
protected Program CreateEntry(string file)
{
return (Type ?? "") + ":" + Location ?? "";
var p = new Program
{
Title = Path.GetFileNameWithoutExtension(file),
IcoPath = file,
Path = file,
Directory = Directory.GetParent(file).FullName
};
switch (Path.GetExtension(file).ToLower())
{
case ".exe":
p.ExecutableName = Path.GetFileName(file);
try
{
var versionInfo = FileVersionInfo.GetVersionInfo(file);
if (!string.IsNullOrEmpty(versionInfo.FileDescription))
{
p.Title = versionInfo.FileDescription;
}
}
catch (Exception)
{
}
break;
}
return p;
}
}
}
}

View File

@@ -1,26 +1,14 @@
using System;
using System.ComponentModel;
namespace Wox.Plugin.Program.ProgramSources
{
[Serializable]
[Browsable(false)]
public class UserStartMenuProgramSource : FileSystemProgramSource
public sealed class UserStartMenuProgramSource : FileSystemProgramSource
{
public UserStartMenuProgramSource(string[] suffixes)
: base(Environment.GetFolderPath(Environment.SpecialFolder.Programs), suffixes)
public UserStartMenuProgramSource()
{
}
public UserStartMenuProgramSource(ProgramSource source)
: this(source.Suffixes)
{
BonusPoints = source.BonusPoints;
}
public override string ToString()
{
return typeof(UserStartMenuProgramSource).Name;
Location = Environment.GetFolderPath(Environment.SpecialFolder.Programs);
}
}
}
}

View File

@@ -1,5 +1,6 @@
using System.Windows;
using System.Linq;
using Wox.Plugin.Program.ProgramSources;
namespace Wox.Plugin.Program
{

View File

@@ -1,12 +1,12 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Wox.Plugin.Program.ProgramSources;
namespace Wox.Plugin.Program
{
public class Settings
{
public List<ProgramSource> ProgramSources { get; set; } = new List<ProgramSource>();
public List<FileSystemProgramSource> ProgramSources { get; set; } = new List<FileSystemProgramSource>();
public string[] ProgramSuffixes { get; set; } = {"bat", "appref-ms", "exe", "lnk"};
public bool EnableStartMenuSource { get; set; } = true;

View File

@@ -61,7 +61,6 @@
<DependentUpon>AddProgramSource.xaml</DependentUpon>
</Compile>
<Compile Include="FileChangeWatcher.cs" />
<Compile Include="ProgramSources\IProgramSource.cs" />
<Compile Include="SuffixesConverter.cs" />
<Compile Include="Program.cs" />
<Compile Include="ProgramIndexCache.cs" />