Fix file associated icon

This commit is contained in:
bao-qian
2016-05-03 23:21:03 +01:00
parent 174c7a776e
commit c2132e3772
5 changed files with 78 additions and 68 deletions

View File

@@ -16,8 +16,6 @@ namespace Wox.Plugin.Everything
public class Main : IPlugin, IPluginI18n, IContextMenu, ISavable public class Main : IPlugin, IPluginI18n, IContextMenu, ISavable
{ {
private readonly EverythingAPI _api = new EverythingAPI(); private readonly EverythingAPI _api = new EverythingAPI();
private static readonly List<string> ImageExts = new List<string> { ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".ico" };
private static readonly List<string> ExecutableExts = new List<string> { ".exe" };
private const string EverythingProcessName = "Everything"; private const string EverythingProcessName = "Everything";
private const string PortableEverything = "PortableEverything"; private const string PortableEverything = "PortableEverything";
@@ -74,7 +72,7 @@ namespace Wox.Plugin.Everything
Result r = new Result(); Result r = new Result();
r.Title = Path.GetFileName(path); r.Title = Path.GetFileName(path);
r.SubTitle = path; r.SubTitle = path;
r.IcoPath = GetIconPath(s); r.IcoPath = path;
r.Action = c => r.Action = c =>
{ {
bool hide; bool hide;
@@ -131,28 +129,6 @@ namespace Wox.Plugin.Everything
return results; return results;
} }
private string GetIconPath(SearchResult s)
{
var ext = Path.GetExtension(s.FullPath);
if (s.Type == ResultType.Folder)
{
return "Images\\folder.png";
}
else if (!string.IsNullOrEmpty(ext))
{
if (ImageExts.Contains(ext.ToLower()))
{
return "Images\\image.png";
}
else if (ExecutableExts.Contains(ext.ToLower()))
{
return s.FullPath;
}
}
return "Images\\file.png";
}
[DllImport("kernel32.dll")] [DllImport("kernel32.dll")]
private static extern int LoadLibrary(string name); private static extern int LoadLibrary(string name);

View File

@@ -17,9 +17,11 @@ namespace Wox.Infrastructure.Image
{ {
public static class ImageLoader public static class ImageLoader
{ {
private static readonly ConcurrentDictionary<string, ImageSource> _imageSources = new ConcurrentDictionary<string, ImageSource>(); private static readonly ConcurrentDictionary<string, ImageSource> ImageSources = new ConcurrentDictionary<string, ImageSource>();
private static readonly string DefaultIcon = Path.Combine(Wox.ProgramPath, "Images", "app.png");
private static readonly string ErrorIcon = Path.Combine(Wox.ProgramPath, "Images", "app_error.png");
private static readonly List<string> ImageExts = new List<string> private static readonly string[] ImageExtions =
{ {
".png", ".png",
".jpg", ".jpg",
@@ -30,16 +32,6 @@ namespace Wox.Infrastructure.Image
".ico" ".ico"
}; };
private static readonly List<string> SelfExts = new List<string>
{
".exe",
".lnk",
".ani",
".cur",
".sln",
".appref-ms"
};
private static readonly ImageCache _cache; private static readonly ImageCache _cache;
private static readonly BinaryStorage<ImageCache> _storage; private static readonly BinaryStorage<ImageCache> _storage;
@@ -54,34 +46,67 @@ namespace Wox.Infrastructure.Image
_storage.Save(); _storage.Save();
} }
private static ImageSource GetIcon(string fileName) private static ImageSource ShellIcon(string fileName)
{ {
try try
{ {
Icon icon = GetFileIcon(fileName) ?? Icon.ExtractAssociatedIcon(fileName); Icon icon = GetFileIcon(fileName);
if (icon != null) if (icon != null)
{ {
return Imaging.CreateBitmapSourceFromHIcon(icon.Handle, var image = ImageFromIcon(icon);
new Int32Rect(0, 0, icon.Width, icon.Height), BitmapSizeOptions.FromEmptyOptions()); return image;
}
else
{
return ImageSources[ErrorIcon];
} }
} }
catch (System.Exception e) catch (System.Exception e)
{ {
Log.Error(e); Log.Error(e);
return ImageSources[ErrorIcon];
} }
return null;
} }
private static ImageSource ImageFromIcon(Icon icon)
{
var image = Imaging.CreateBitmapSourceFromHIcon(
icon.Handle,
new Int32Rect(0, 0, icon.Width, icon.Height),
BitmapSizeOptions.FromEmptyOptions());
return image;
}
private static ImageSource AssociatedIcon(string path)
{
try
{
Icon icon = Icon.ExtractAssociatedIcon(path);
if (icon != null)
{
var image = ImageFromIcon(icon);
return image;
}
else
{
return ImageSources[ErrorIcon];
}
}
catch (System.Exception e)
{
Log.Error(e);
return ImageSources[ErrorIcon];
}
}
public static void PreloadImages() public static void PreloadImages()
{ {
var path = Path.Combine(Wox.ProgramPath, "Images", "app.png"); ImageSources[DefaultIcon] = new BitmapImage(new Uri(DefaultIcon));
_imageSources[path] = new BitmapImage(new Uri(path)); ImageSources[ErrorIcon] = new BitmapImage(new Uri(ErrorIcon));
Task.Factory.StartNew(() => Task.Factory.StartNew(() =>
{ {
Stopwatch.Debug("Preload images from cache", () => Stopwatch.Debug("Preload images from cache", () =>
{ {
_cache.TopUsedImages.AsParallel().Where(i => !_imageSources.ContainsKey(i.Key)).ForAll(i => _cache.TopUsedImages.AsParallel().Where(i => !ImageSources.ContainsKey(i.Key)).ForAll(i =>
{ {
var img = Load(i.Key); var img = Load(i.Key);
if (img != null) if (img != null)
@@ -91,7 +116,7 @@ namespace Wox.Infrastructure.Image
// this line made it possible // this line made it possible
// should be changed the Dispatcher.InvokeAsync in the future // should be changed the Dispatcher.InvokeAsync in the future
img.Freeze(); img.Freeze();
_imageSources[i.Key] = img; ImageSources[i.Key] = img;
} }
}); });
}); });
@@ -100,16 +125,15 @@ namespace Wox.Infrastructure.Image
} }
public static ImageSource Load(string path) public static ImageSource Load(string path)
{ {
ImageSource image; ImageSource image;
if (string.IsNullOrEmpty(path)) if (string.IsNullOrEmpty(path))
{ {
path = Path.Combine(Wox.ProgramPath, "Images", "app.png"); image = ImageSources[ErrorIcon];
image = _imageSources[path];
} }
else if (_imageSources.ContainsKey(path)) else if (ImageSources.ContainsKey(path))
{ {
image = _imageSources[path]; image = ImageSources[path];
} }
else else
{ {
@@ -118,37 +142,44 @@ namespace Wox.Infrastructure.Image
if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase)) if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
{ {
image = new BitmapImage(new Uri(path)); image = new BitmapImage(new Uri(path));
_imageSources[path] = image; ImageSources[path] = image;
} }
else if (File.Exists(path) && Path.IsPathRooted(path)) else if (Path.IsPathRooted(path))
{ {
if (SelfExts.Contains(ext)) if (Directory.Exists(path))
{ {
image = GetIcon(path); image = ShellIcon(path);
_imageSources[path] = image; ImageSources[path] = image;
} }
else if (ImageExts.Contains(ext)) else if (File.Exists(path))
{ {
image = new BitmapImage(new Uri(path)); if (ImageExtions.Contains(ext))
_imageSources[path] = image; {
image = new BitmapImage(new Uri(path));
ImageSources[path] = image;
}
else
{
image = AssociatedIcon(path);
ImageSources[path] = image;
}
} }
else else
{ {
path = Path.Combine(Wox.ProgramPath, "Images", "app.png"); image = ImageSources[ErrorIcon];
image = _imageSources[path];
} }
} }
else else
{ {
path = Path.Combine(Wox.ProgramPath, "Images", Path.GetFileName(path)); var defaultDirectoryPath = Path.Combine(Wox.ProgramPath, "Images", Path.GetFileName(path));
if (File.Exists(path)) if (File.Exists(defaultDirectoryPath))
{ {
image = new BitmapImage(new Uri(path)); image = new BitmapImage(new Uri(defaultDirectoryPath));
ImageSources[path] = image;
} }
else else
{ {
path = Path.Combine(Wox.ProgramPath, "Images", "app.png"); image = ImageSources[ErrorIcon];
image = _imageSources[path];
} }
} }
} }

View File

@@ -49,7 +49,7 @@ namespace Wox.Plugin
set set
{ {
_pluginDirectory = value; _pluginDirectory = value;
if (!string.IsNullOrEmpty(IcoPath) && Path.IsPathRooted(IcoPath)) if (!string.IsNullOrEmpty(IcoPath) && !Path.IsPathRooted(IcoPath))
{ {
IcoPath = Path.Combine(value, IcoPath); IcoPath = Path.Combine(value, IcoPath);
} }

BIN
Wox/Images/app_error.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -198,6 +198,9 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<Resource Include="Images\history.png" /> <Resource Include="Images\history.png" />
<Resource Include="Images\app_error.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Resource>
<Content Include="Languages\en.xaml"> <Content Include="Languages\en.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>