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

View File

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

View File

@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using Wox.Plugin.Program.Programs;
namespace Wox.Plugin.Program
{
[Serializable]
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.Windows;
using System.Windows.Controls;
using Wox.Plugin.Program.ProgramSources;
using Wox.Plugin.Program.Programs;
namespace Wox.Plugin.Program
{
@ -51,7 +51,7 @@ namespace Wox.Plugin.Program
private void btnDeleteProgramSource_OnClick(object sender, RoutedEventArgs e)
{
var selectedProgramSource = programSourceView.SelectedItem as UnregisteredPrograms;
var selectedProgramSource = programSourceView.SelectedItem as Settings.ProgramSource;
if (selectedProgramSource != null)
{
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)
{
var selectedProgramSource = programSourceView.SelectedItem as UnregisteredPrograms;
var selectedProgramSource = programSourceView.SelectedItem as Settings.ProgramSource;
if (selectedProgramSource != null)
{
var add = new AddProgramSource(selectedProgramSource, _settings);
@ -120,7 +120,7 @@ namespace Wox.Plugin.Program
{
if (Directory.Exists(s))
{
_settings.ProgramSources.Add(new UnregisteredPrograms
_settings.ProgramSources.Add(new Settings.ProgramSource
{
Location = s
});

View File

@ -4,15 +4,15 @@ using System.IO;
using System.Linq;
using Microsoft.Win32;
namespace Wox.Plugin.Program.ProgramSources
namespace Wox.Plugin.Program.Programs
{
[Serializable]
public class AppPathsPrograms : Win32
{
public override List<Program> LoadPrograms()
public static IEnumerable<Win32> All()
{
// 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";
using (var root = Registry.LocalMachine.OpenSubKey(appPaths))
{
@ -31,7 +31,7 @@ namespace Wox.Plugin.Program.ProgramSources
return programs;
}
private IEnumerable<Program> ProgramsFromRegistryKey(RegistryKey root)
private static IEnumerable<Win32> ProgramsFromRegistryKey(RegistryKey root)
{
var programs = root.GetSubKeyNames()
.Select(subkey => ProgramFromRegistrySubkey(root, subkey))
@ -39,7 +39,7 @@ namespace Wox.Plugin.Program.ProgramSources
return programs;
}
private Program ProgramFromRegistrySubkey(RegistryKey root, string subkey)
private static Win32 ProgramFromRegistrySubkey(RegistryKey root, string 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.Collections.Generic;
namespace Wox.Plugin.Program.ProgramSources
namespace Wox.Plugin.Program.Programs
{
[Serializable]
class StartMenu : Win32
{
public override List<Program> LoadPrograms()
public static IEnumerable<Win32> All(string[] suffixes)
{
var directory1 = Environment.GetFolderPath(Environment.SpecialFolder.Programs);
var directory2 = Environment.GetFolderPath(Environment.SpecialFolder.CommonPrograms);
var programs = new List<Program>();
GetAppFromDirectory(programs, directory1, MaxDepth);
GetAppFromDirectory(programs, directory2, MaxDepth);
var programs = new List<Win32>();
GetAppFromDirectory(programs, directory1, -1, suffixes);
GetAppFromDirectory(programs, directory2, -1, suffixes);
return programs;
}
}

View File

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

View File

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

View File

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

View File

@ -1,11 +1,11 @@
using System.Collections.Generic;
using Wox.Plugin.Program.ProgramSources;
using Wox.Plugin.Program.Programs;
namespace Wox.Plugin.Program
{
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 bool EnableStartMenuSource { get; set; } = true;
@ -13,5 +13,11 @@ namespace Wox.Plugin.Program
public bool EnableRegistrySource { get; set; } = true;
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\Win32.cs" />
<Compile Include="SuffixesConverter.cs" />
<Compile Include="Programs\Program.cs" />
<Compile Include="ProgramIndexCache.cs" />
<Compile Include="Main.cs" />
<Compile Include="ProgramSetting.xaml.cs">
<DependentUpon>ProgramSetting.xaml</DependentUpon>
</Compile>
<Compile Include="Programs\ProgramSource.cs" />
<Compile Include="Programs\AppPathsPrograms.cs" />
<Compile Include="Programs\UnregisteredPrograms.cs" />
<Compile Include="Settings.cs" />