Skip to content

Commit

Permalink
Added better error handling to icon loading to prevent crashes (fixes #…
Browse files Browse the repository at this point in the history
  • Loading branch information
Danielku15 committed Aug 15, 2017
1 parent af826de commit a2cee6d
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 24 deletions.
63 changes: 44 additions & 19 deletions BetterStartPage.Control/Converter/PathToSystemIconConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.VisualStudio.Shell;

namespace BetterStartPage.Control.Converter
{
Expand Down Expand Up @@ -49,38 +50,59 @@ private ImageSource GetFileIcon(string fileName)
{
// if file does not exist, create a temp file with the same file extension
var isTemp = false;
if (!File.Exists(fileName) && !Directory.Exists(fileName))
try
{
isTemp = true;
fileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + Path.GetExtension(fileName));
File.WriteAllText(fileName, string.Empty);
}

var shinfo = new SHFILEINFO();
if (!File.Exists(fileName) && !Directory.Exists(fileName))
{
isTemp = true;
fileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + Path.GetExtension(fileName));
File.WriteAllText(fileName, string.Empty);
}

var flags = SHGFI_SYSICONINDEX;
if (fileName.IndexOf(":", StringComparison.Ordinal) == -1)
flags = flags | SHGFI_USEFILEATTRIBUTES;
flags = flags | SHGFI_ICON | SHGFI_SMALLICON;
var shinfo = new SHFILEINFO();

SHGetFileInfo(fileName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), flags);
var icon = Icon.FromHandle(shinfo.hIcon);
var bitmap = icon.ToBitmap();
var flags = SHGFI_SYSICONINDEX;
if (fileName.IndexOf(":", StringComparison.Ordinal) == -1)
{
flags = flags | SHGFI_USEFILEATTRIBUTES;
}
flags = flags | SHGFI_ICON | SHGFI_SMALLICON;

IntPtr hBitmap = bitmap.GetHbitmap();
try
var hr = SHGetFileInfo(fileName, 0, ref shinfo, (uint) Marshal.SizeOf(shinfo), flags);
if (hr != IntPtr.Zero)
{
Bitmap bitmap;
using (var icon = Icon.FromHandle(shinfo.hIcon))
{
bitmap = icon.ToBitmap();
}
DestroyIcon(shinfo.hIcon);

var hBitmap = bitmap.GetHbitmap();
try
{
return Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
finally
{
DeleteObject(hBitmap);
}
}
}
catch (Exception e)
{
return Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
ActivityLog.LogError("BetterStartPage", "Failed to create icon: " + e);
}
finally
{
DeleteObject(hBitmap);
if (isTemp)
{
File.Delete(fileName);
}
}

return null;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
Expand All @@ -106,6 +128,9 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu
[DllImport("gdi32.dll")]
private static extern bool DeleteObject(IntPtr hObject);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private extern static bool DestroyIcon(IntPtr handle);

[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
Expand Down
4 changes: 2 additions & 2 deletions BetterStartPage.Control/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.13.0.0")]
[assembly: AssemblyFileVersion("1.13.0.0")]
[assembly: AssemblyVersion("1.14.0.0")]
[assembly: AssemblyFileVersion("1.14.0.0")]
4 changes: 2 additions & 2 deletions BetterStartPage/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.13.0.0")]
[assembly: AssemblyFileVersion("1.13.0.0")]
[assembly: AssemblyVersion("1.14.0.0")]
[assembly: AssemblyFileVersion("1.14.0.0")]
3 changes: 3 additions & 0 deletions BetterStartPage/ReleaseNotes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# 1.14
- Added error handling for icon loading (bug #25)

# 1.13
- Added export/import feature for easier migration.

Expand Down
2 changes: 1 addition & 1 deletion BetterStartPage/source.extension.vsixmanifest
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<Metadata>
<Identity Id="E6BD5606-CCEC-4364-B60B-8FB70BA3575B" Version="1.13" Language="en-US" Publisher="Danielku15" />
<Identity Id="E6BD5606-CCEC-4364-B60B-8FB70BA3575B" Version="1.14" Language="en-US" Publisher="Danielku15" />
<DisplayName>BetterStartPage</DisplayName>
<Description xml:space="preserve">This is a VS2015 like start page which replaces the news section by a custom project dashboard.
In the project dashboard you can organize your solutions and projects into different groups for fast access.
Expand Down

0 comments on commit a2cee6d

Please sign in to comment.