Merge models

This commit is contained in:
bao-qian
2016-08-20 01:17:28 +01:00
parent 0c0ec29821
commit ee542f0fec
13 changed files with 131 additions and 166 deletions

View File

@@ -1,6 +1,6 @@
using System.Windows; using System.Windows;
using System.Windows.Forms; using System.Windows.Forms;
using Wox.Plugin.Program.ProgramSources; using Wox.Plugin.Program.Programs;
namespace Wox.Plugin.Program namespace Wox.Plugin.Program
{ {
@@ -9,7 +9,7 @@ namespace Wox.Plugin.Program
/// </summary> /// </summary>
public partial class AddProgramSource public partial class AddProgramSource
{ {
private UnregisteredPrograms _editing; private Settings.ProgramSource _editing;
private Settings _settings; private Settings _settings;
public AddProgramSource(Settings settings) public AddProgramSource(Settings settings)
@@ -19,7 +19,7 @@ namespace Wox.Plugin.Program
Directory.Focus(); Directory.Focus();
} }
public AddProgramSource(UnregisteredPrograms edit, Settings settings) public AddProgramSource(Settings.ProgramSource edit, Settings settings)
{ {
_editing = edit; _editing = edit;
_settings = settings; _settings = settings;
@@ -49,7 +49,7 @@ namespace Wox.Plugin.Program
if(_editing == null) if(_editing == null)
{ {
var source = new UnregisteredPrograms var source = new Settings.ProgramSource
{ {
Location = Directory.Text, Location = Directory.Text,
MaxDepth = max MaxDepth = max

View File

@@ -7,14 +7,14 @@ using System.Windows.Controls;
using Wox.Infrastructure; using Wox.Infrastructure;
using Wox.Infrastructure.Logger; using Wox.Infrastructure.Logger;
using Wox.Infrastructure.Storage; using Wox.Infrastructure.Storage;
using Wox.Plugin.Program.ProgramSources; using Wox.Plugin.Program.Programs;
using Stopwatch = Wox.Infrastructure.Stopwatch; using Stopwatch = Wox.Infrastructure.Stopwatch;
namespace Wox.Plugin.Program namespace Wox.Plugin.Program
{ {
public class Main : ISettingProvider, IPlugin, IPluginI18n, IContextMenu, ISavable public class Main : ISettingProvider, IPlugin, IPluginI18n, IContextMenu, ISavable
{ {
private static List<Program> _programs = new List<Program>(); private static List<Win32> _programs = new List<Win32>();
private static List<UWP> _uwps = new List<UWP>(); private static List<UWP> _uwps = new List<UWP>();
private PluginInitContext _context; private PluginInitContext _context;
@@ -59,12 +59,12 @@ namespace Wox.Plugin.Program
return result; return result;
} }
public Result ResultFromProgram(Program p) public Result ResultFromProgram(Win32 p)
{ {
var result = new Result var result = new Result
{ {
Title = p.Title, Title = p.Title,
SubTitle = p.Path, SubTitle = p.ExecutablePath,
IcoPath = p.IcoPath, IcoPath = p.IcoPath,
Score = p.Score, Score = p.Score,
ContextData = p, ContextData = p,
@@ -72,7 +72,7 @@ namespace Wox.Plugin.Program
{ {
var info = new ProcessStartInfo var info = new ProcessStartInfo
{ {
FileName = p.Path, FileName = p.ExecutablePath,
WorkingDirectory = p.Directory WorkingDirectory = p.Directory
}; };
var hide = StartProcess(info); var hide = StartProcess(info);
@@ -101,7 +101,7 @@ namespace Wox.Plugin.Program
} }
private int Score(Program program, string query) private int Score(Win32 program, string query)
{ {
var score1 = StringMatcher.Score(program.Title, query); var score1 = StringMatcher.Score(program.Title, query);
var score2 = StringMatcher.ScoreForPinyin(program.Title, query); var score2 = StringMatcher.ScoreForPinyin(program.Title, query);
@@ -128,59 +128,27 @@ namespace Wox.Plugin.Program
public static void IndexPrograms() public static void IndexPrograms()
{ {
var sources = ProgramSources(); _cache.Programs = AllWin32Programs();
_uwps = UWP.All();
var programs = sources.AsParallel()
.SelectMany(s => s.LoadPrograms())
// filter duplicate program
.GroupBy(x => new { ExecutePath = x.Path, ExecuteName = x.ExecutableName })
.Select(g => g.First());
programs = programs.Select(ScoreFilter);
_programs = programs.ToList();
_cache.Programs = _programs;
var windows10 = new Version(10, 0);
var support = Environment.OSVersion.Version.Major >= windows10.Major;
if (support)
{
_uwps = UWP.All();
}
} }
private static List<ProgramSource> ProgramSources() private static List<Win32> AllWin32Programs()
{ {
var sources = new List<ProgramSource>(); var appPaths = AppPathsPrograms.All();
var source1 = _settings.ProgramSources; var startMenu = StartMenu.All(_settings.ProgramSuffixes);
sources.AddRange(source1); var unregistered = UnregisteredPrograms.All(_settings.ProgramSources, _settings.ProgramSuffixes);
if (_settings.EnableStartMenuSource) var programs = appPaths.Concat(startMenu).Concat(unregistered);
{
var source2 = new StartMenu();
sources.Add(source2);
}
if (_settings.EnableRegistrySource)
{
var source3 = new AppPathsPrograms();
sources.Add(source3);
}
FileChangeWatcher.AddAll(source1, _settings.ProgramSuffixes); programs = programs.AsParallel()
foreach (var source in sources) // filter duplicate program
{ .GroupBy(x => new { ExecutePath = x.ExecutablePath, ExecuteName = x.ExecutableName })
var win32 = source as Win32; .Select(g => g.First())
if (win32 != null) .Select(ScoreFilter);
{
win32.Suffixes = _settings.ProgramSuffixes;
}
}
return sources; return programs.ToList();
} }
private static Win32 ScoreFilter(Win32 p)
private static Program ScoreFilter(Program p)
{ {
var start = new[] { "启动", "start" }; var start = new[] { "启动", "start" };
var doc = new[] { "帮助", "help", "文档", "documentation" }; var doc = new[] { "帮助", "help", "文档", "documentation" };
@@ -222,7 +190,7 @@ namespace Wox.Plugin.Program
public List<Result> LoadContextMenus(Result selectedResult) public List<Result> LoadContextMenus(Result selectedResult)
{ {
Program p = selectedResult.ContextData as Program; Win32 p = selectedResult.ContextData as Win32;
if (p != null) if (p != null)
{ {
List<Result> contextMenus = new List<Result> List<Result> contextMenus = new List<Result>
@@ -234,7 +202,7 @@ namespace Wox.Plugin.Program
{ {
var info = new ProcessStartInfo var info = new ProcessStartInfo
{ {
FileName = p.Path, FileName = p.ExecutablePath,
WorkingDirectory = p.Directory, WorkingDirectory = p.Directory,
Verb = "runas" Verb = "runas"
}; };

View File

@@ -1,11 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Wox.Plugin.Program.Programs;
namespace Wox.Plugin.Program namespace Wox.Plugin.Program
{ {
[Serializable] [Serializable]
public class ProgramIndexCache public class ProgramIndexCache
{ {
public List<Program> Programs = new List<Program>(); public List<Win32> Programs = new List<Win32>();
} }
} }

View File

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

View File

@@ -4,15 +4,15 @@ using System.IO;
using System.Linq; using System.Linq;
using Microsoft.Win32; using Microsoft.Win32;
namespace Wox.Plugin.Program.ProgramSources namespace Wox.Plugin.Program.Programs
{ {
[Serializable] [Serializable]
public class AppPathsPrograms : Win32 public class AppPathsPrograms : Win32
{ {
public override List<Program> LoadPrograms() public static IEnumerable<Win32> All()
{ {
// https://msdn.microsoft.com/en-us/library/windows/desktop/ee872121 // https://msdn.microsoft.com/en-us/library/windows/desktop/ee872121
var programs = new List<Program>(); var programs = new List<Win32>();
const string appPaths = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths"; const string appPaths = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths";
using (var root = Registry.LocalMachine.OpenSubKey(appPaths)) using (var root = Registry.LocalMachine.OpenSubKey(appPaths))
{ {
@@ -31,7 +31,7 @@ namespace Wox.Plugin.Program.ProgramSources
return programs; return programs;
} }
private IEnumerable<Program> ProgramsFromRegistryKey(RegistryKey root) private static IEnumerable<Win32> ProgramsFromRegistryKey(RegistryKey root)
{ {
var programs = root.GetSubKeyNames() var programs = root.GetSubKeyNames()
.Select(subkey => ProgramFromRegistrySubkey(root, subkey)) .Select(subkey => ProgramFromRegistrySubkey(root, subkey))
@@ -39,7 +39,7 @@ namespace Wox.Plugin.Program.ProgramSources
return programs; return programs;
} }
private Program ProgramFromRegistrySubkey(RegistryKey root, string subkey) private static Win32 ProgramFromRegistrySubkey(RegistryKey root, string subkey)
{ {
using (var key = root.OpenSubKey(subkey)) using (var key = root.OpenSubKey(subkey))
{ {
@@ -62,7 +62,7 @@ namespace Wox.Plugin.Program.ProgramSources
} }
} }
} }
return new Program(); return new Win32();
} }
} }
} }

View File

@@ -1,15 +0,0 @@
using System;
namespace Wox.Plugin.Program
{
[Serializable]
public class Program
{
public string Title { get; set; }
public string IcoPath { get; set; }
public string Path { get; set; }
public string Directory { get; set; }
public string ExecutableName { get; set; }
public int Score { get; set; }
}
}

View File

@@ -1,11 +0,0 @@
using System;
using System.Collections.Generic;
namespace Wox.Plugin.Program.ProgramSources
{
[Serializable]
public abstract class ProgramSource
{
public abstract List<Program> LoadPrograms();
}
}

View File

@@ -1,18 +1,18 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Wox.Plugin.Program.ProgramSources namespace Wox.Plugin.Program.Programs
{ {
[Serializable] [Serializable]
class StartMenu : Win32 class StartMenu : Win32
{ {
public override List<Program> LoadPrograms() public static IEnumerable<Win32> All(string[] suffixes)
{ {
var directory1 = Environment.GetFolderPath(Environment.SpecialFolder.Programs); var directory1 = Environment.GetFolderPath(Environment.SpecialFolder.Programs);
var directory2 = Environment.GetFolderPath(Environment.SpecialFolder.CommonPrograms); var directory2 = Environment.GetFolderPath(Environment.SpecialFolder.CommonPrograms);
var programs = new List<Program>(); var programs = new List<Win32>();
GetAppFromDirectory(programs, directory1, MaxDepth); GetAppFromDirectory(programs, directory1, -1, suffixes);
GetAppFromDirectory(programs, directory2, MaxDepth); GetAppFromDirectory(programs, directory2, -1, suffixes);
return programs; return programs;
} }
} }

View File

@@ -14,11 +14,12 @@ using Windows.Management.Deployment;
using Windows.Storage.Streams; using Windows.Storage.Streams;
using AppxPackaing; using AppxPackaing;
using Shell; using Shell;
using Wox.Infrastructure;
using Wox.Infrastructure.Logger; using Wox.Infrastructure.Logger;
using IStream = AppxPackaing.IStream; using IStream = AppxPackaing.IStream;
using Rect = System.Windows.Rect; using Rect = System.Windows.Rect;
namespace Wox.Plugin.Program.ProgramSources namespace Wox.Plugin.Program.Programs
{ {
public class UWP public class UWP
{ {
@@ -119,26 +120,35 @@ namespace Wox.Plugin.Program.ProgramSources
public static List<UWP> All() public static List<UWP> All()
{ {
var packages = CurrentUserPackages(); var windows10 = new Version(10, 0);
var uwps = new List<UWP>(); var support = Environment.OSVersion.Version.Major >= windows10.Major;
Parallel.ForEach(packages, p => if (support)
{ {
try var packages = CurrentUserPackages();
var uwps = new List<UWP>();
Parallel.ForEach(packages, p =>
{ {
var u = new UWP(p); try
if (u.Apps.Length > 0)
{ {
uwps.Add(u); var u = new UWP(p);
if (u.Apps.Length > 0)
{
uwps.Add(u);
}
} }
} catch (Exception e)
catch (Exception e) {
{ // if there are errors, just ignore it and continue
// if there are errors, just ignore it and continue var message = $"Can't parse {p.Id.Name}: {e.Message}";
var message = $"Can't parse {p.Id.Name}: {e.Message}"; Log.Error(message);
Log.Error(message); }
} });
}); return uwps;
return uwps; }
else
{
return new List<UWP>();
}
} }
private static IEnumerable<Package> CurrentUserPackages() private static IEnumerable<Package> CurrentUserPackages()
@@ -244,8 +254,7 @@ namespace Wox.Plugin.Program.ProgramSources
} }
else else
{ {
// todo: replaced with wox error logo return new BitmapImage(new Uri(Constant.ErrorIcon));
return new BitmapImage();
} }
} }
@@ -310,8 +319,7 @@ namespace Wox.Plugin.Program.ProgramSources
} }
else else
{ {
var bitmap = new BitmapImage(); return new BitmapImage(new Uri(Constant.ErrorIcon));
return bitmap;
} }
} }

View File

@@ -2,25 +2,22 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
namespace Wox.Plugin.Program.ProgramSources namespace Wox.Plugin.Program.Programs
{ {
[Serializable] [Serializable]
public class UnregisteredPrograms : Win32 public class UnregisteredPrograms : Win32
{ {
public string Location { get; set; } = ""; public static List<Win32> All(List<Settings.ProgramSource> sources, string[] suffixes)
public override List<Program> LoadPrograms()
{ {
if (Directory.Exists(Location) && MaxDepth >= -1) List<Win32> programs = new List<Win32>();
foreach (var source in sources)
{ {
var apps = new List<Program>(); if (System.IO.Directory.Exists(source.Location) && source.MaxDepth >= -1)
GetAppFromDirectory(apps, Location, MaxDepth); {
return apps; GetAppFromDirectory(programs, source.Location, source.MaxDepth, suffixes);
} }
else
{
return new List<Program>();
} }
return programs;
} }
} }
} }

View File

@@ -6,22 +6,26 @@ using System.Linq;
using Wox.Infrastructure.Exception; using Wox.Infrastructure.Exception;
using Wox.Infrastructure.Logger; using Wox.Infrastructure.Logger;
namespace Wox.Plugin.Program.ProgramSources namespace Wox.Plugin.Program.Programs
{ {
[Serializable] [Serializable]
public abstract class Win32 : ProgramSource public class Win32
{ {
public int MaxDepth { get; set; } = -1; public string Title { get; set; }
public string[] Suffixes { get; set; } = { "" }; public string IcoPath { get; set; }
public string ExecutablePath { get; set; }
public string Directory { get; set; }
public string ExecutableName { get; set; }
public int Score { get; set; }
protected Program CreateEntry(string file) protected static Win32 CreateEntry(string file)
{ {
var p = new Program var p = new Win32
{ {
Title = Path.GetFileNameWithoutExtension(file), Title = Path.GetFileNameWithoutExtension(file),
IcoPath = file, IcoPath = file,
Path = file, ExecutablePath = file,
Directory = Directory.GetParent(file).FullName Directory = System.IO.Directory.GetParent(file).FullName
}; };
switch (Path.GetExtension(file).ToLower()) switch (Path.GetExtension(file).ToLower())
@@ -44,33 +48,42 @@ namespace Wox.Plugin.Program.ProgramSources
return p; return p;
} }
protected void GetAppFromDirectory(List<Program> apps, string directory, int depth) protected static void GetAppFromDirectory(List<Win32> apps, string directory, int depth, string[] suffixes)
{ {
if (MaxDepth == -1 || MaxDepth < depth) if (depth == -1)
{ {
foreach (var f in Directory.GetFiles(directory)) }
else if (depth > 0)
{
depth = depth - 1;
}
else
{
return;
}
foreach (var f in System.IO.Directory.GetFiles(directory))
{
if (suffixes.Any(o => f.EndsWith("." + o)))
{ {
if (Suffixes.Any(o => f.EndsWith("." + o))) Win32 p;
try
{ {
Program p; p = CreateEntry(f);
try
{
p = CreateEntry(f);
}
catch (Exception e)
{
var woxPluginException = new WoxPluginException("Program",
$"GetAppFromDirectory failed: {directory}", e);
Log.Exception(woxPluginException);
continue;
}
apps.Add(p);
} }
catch (Exception e)
{
var woxPluginException = new WoxPluginException("Program",
$"GetAppFromDirectory failed: {directory}", e);
Log.Exception(woxPluginException);
continue;
}
apps.Add(p);
} }
foreach (var d in Directory.GetDirectories(directory)) }
{ foreach (var d in System.IO.Directory.GetDirectories(directory))
GetAppFromDirectory(apps, d, depth - 1); {
} GetAppFromDirectory(apps, d, depth, suffixes);
} }
} }
} }

View File

@@ -1,11 +1,11 @@
using System.Collections.Generic; using System.Collections.Generic;
using Wox.Plugin.Program.ProgramSources; using Wox.Plugin.Program.Programs;
namespace Wox.Plugin.Program namespace Wox.Plugin.Program
{ {
public class Settings public class Settings
{ {
public List<UnregisteredPrograms> ProgramSources { get; set; } = new List<UnregisteredPrograms>(); public List<ProgramSource> ProgramSources { get; set; } = new List<ProgramSource>();
public string[] ProgramSuffixes { get; set; } = {"bat", "appref-ms", "exe", "lnk"}; public string[] ProgramSuffixes { get; set; } = {"bat", "appref-ms", "exe", "lnk"};
public bool EnableStartMenuSource { get; set; } = true; public bool EnableStartMenuSource { get; set; } = true;
@@ -13,5 +13,11 @@ namespace Wox.Plugin.Program
public bool EnableRegistrySource { get; set; } = true; public bool EnableRegistrySource { get; set; } = true;
internal const char SuffixSeperator = ';'; internal const char SuffixSeperator = ';';
public class ProgramSource
{
public string Location { get; set; }
public int MaxDepth { get; set; }
}
} }
} }

View File

@@ -75,13 +75,11 @@
<Compile Include="Programs\UWP.cs" /> <Compile Include="Programs\UWP.cs" />
<Compile Include="Programs\Win32.cs" /> <Compile Include="Programs\Win32.cs" />
<Compile Include="SuffixesConverter.cs" /> <Compile Include="SuffixesConverter.cs" />
<Compile Include="Programs\Program.cs" />
<Compile Include="ProgramIndexCache.cs" /> <Compile Include="ProgramIndexCache.cs" />
<Compile Include="Main.cs" /> <Compile Include="Main.cs" />
<Compile Include="ProgramSetting.xaml.cs"> <Compile Include="ProgramSetting.xaml.cs">
<DependentUpon>ProgramSetting.xaml</DependentUpon> <DependentUpon>ProgramSetting.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Programs\ProgramSource.cs" />
<Compile Include="Programs\AppPathsPrograms.cs" /> <Compile Include="Programs\AppPathsPrograms.cs" />
<Compile Include="Programs\UnregisteredPrograms.cs" /> <Compile Include="Programs\UnregisteredPrograms.cs" />
<Compile Include="Settings.cs" /> <Compile Include="Settings.cs" />