Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions source/BulkCrapUninstaller/EntryPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ private static void HandleBeingSecondInstance()
}
else
{
CustomMessageBox.ShowDialog(null, new CmbBasicSettings("BCUninstaller is already running", "BCUninstaller is already running", "You can start only one instance of BCUninstaller. Close previous instances and try again. If you don't see the BCUninstaller window or it's not responding, try closing it with Task Manager.", Icon.ExtractAssociatedIcon(location), "OK"));
}
}
catch (Exception ex)
{
CustomMessageBox.ShowDialog(null, new CmbBasicSettings("BCUninstaller is already running", "BCUninstaller is already running", "You can start only one instance of BCUninstaller. Close previous instances and try again. If you don't see the BCUninstaller window or it's not responding, try closing it with Task Manager.", DrawingTools.ExtractAssociatedIcon(location), "OK"));
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
Expand All @@ -166,4 +166,4 @@ private static void SetupDependancies()
//}
}
}
}
}
26 changes: 26 additions & 0 deletions source/BulkCrapUninstallerTests/DrawingToolsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Drawing;
using System.IO;
using Klocman.Tools;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace BulkCrapUninstallerTests
{
[TestClass]
public class DrawingToolsTests
{
[TestMethod]
public void CreateOwnedIconFromHandle_ReturnsUsableClone()
{
using var sourceIcon = SystemIcons.Application;
var handle = sourceIcon.GetHicon();

using var ownedIcon = DrawingTools.CreateOwnedIconFromHandle(handle);
using var stream = new MemoryStream();

ownedIcon.Save(stream);

Assert.IsTrue(stream.Length > 0);
Assert.AreEqual(sourceIcon.Size, ownedIcon.Size);
}
}
}
29 changes: 27 additions & 2 deletions source/KlocTools/Tools/DrawingTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,32 @@ public static Icon ExtractAssociatedIcon(string filePath)
var index = 0;
var handle = SafeNativeMethods.ExtractAssociatedIcon(new HandleRef(null, IntPtr.Zero), iconPath, ref index);
if (handle != IntPtr.Zero)
return Icon.FromHandle(handle);
return CreateOwnedIconFromHandle(handle);
}
return null;
}

/// <summary>
/// Clone an icon handle into a managed icon instance and release the original native handle.
/// </summary>
public static Icon CreateOwnedIconFromHandle(IntPtr handle)
{
if (handle == IntPtr.Zero)
throw new ArgumentException("Icon handle must not be zero", nameof(handle));

try
{
using (var temporaryIcon = Icon.FromHandle(handle))
{
return (Icon)temporaryIcon.Clone();
}
}
finally
{
SafeNativeMethods.DestroyIcon(handle);
}
}


/// <summary>
/// This class suppresses stack walks for unmanaged code permission.
Expand All @@ -69,6 +90,10 @@ internal static class SafeNativeMethods
{
[DllImport("shell32.dll", EntryPoint = "ExtractAssociatedIcon", CharSet = CharSet.Auto)]
internal static extern IntPtr ExtractAssociatedIcon(HandleRef hInst, StringBuilder iconPath, ref int index);

[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DestroyIcon(IntPtr hIcon);
}

public static Color ColorLerp(Color from, Color to, float ratio)
Expand Down Expand Up @@ -136,4 +161,4 @@ public static Icon IconFromImage(Image img)
return new Icon(ms);
}
}
}
}
2 changes: 1 addition & 1 deletion source/UninstallTools/Factory/ScoopFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ public static ApplicationUninstallerEntry CreateUninstallerEntry(
{
try
{
var icon = potentialIcon.EndsWith(".ico", StringComparison.OrdinalIgnoreCase) ? new Icon(potentialIcon) : Icon.ExtractAssociatedIcon(potentialIcon);
var icon = potentialIcon.EndsWith(".ico", StringComparison.OrdinalIgnoreCase) ? new Icon(potentialIcon) : DrawingTools.ExtractAssociatedIcon(potentialIcon);
if (icon == null || icon.Size == Size.Empty) continue;
entry.IconBitmap = icon;
break;
Expand Down
18 changes: 9 additions & 9 deletions source/UniversalUninstaller/UninstallSelection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ public UninstallSelection(DirectoryInfo target)
{
Icon = ProcessTools.GetIconFromEntryExe();
}
catch (Exception ex)
{
/* Fall back to a low quality icon */
var handle = Resources.icon.GetHicon();
Icon = Icon.FromHandle(handle);
Console.WriteLine(ex);
Klocman.LogWriter.WriteMessageToLog(ex.ToString());
}
catch (Exception ex)
{
/* Fall back to a low quality icon */
var handle = Resources.icon.GetHicon();
Icon = DrawingTools.CreateOwnedIconFromHandle(handle);

Console.WriteLine(ex);
Klocman.LogWriter.WriteMessageToLog(ex.ToString());
}

Text = string.Format(Localisation.UninstallSelection_Title, target.Name);
}
Expand Down