Files
2026-08-27 11:22:54 -06:00

91 lines
2.1 KiB
C#

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
namespace Crysome.Client.Util;
internal static class ShellSmallIconPng
{
private struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
}
private const uint SHGFI_ICON = 256u;
private const uint SHGFI_SMALLICON = 1u;
private const uint SHGFI_USEFILEATTRIBUTES = 16u;
private const uint FILE_ATTRIBUTE_DIRECTORY = 16u;
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern bool DestroyIcon(IntPtr hIcon);
public static byte[] TryGetPng(string fullPath, bool isDirectory)
{
if (string.IsNullOrEmpty(fullPath))
{
return null;
}
try
{
if (!isDirectory && File.Exists(fullPath))
{
using (Icon icon = Icon.ExtractAssociatedIcon(fullPath))
{
if (icon == null)
{
return null;
}
return IconToPng(icon);
}
}
SHFILEINFO psfi = default(SHFILEINFO);
uint dwFileAttributes = (isDirectory ? 16u : 0u);
if (SHGetFileInfo(fullPath, dwFileAttributes, ref psfi, (uint)Marshal.SizeOf<SHFILEINFO>(), 273u) == IntPtr.Zero || psfi.hIcon == IntPtr.Zero)
{
return null;
}
IntPtr hIcon = psfi.hIcon;
try
{
using Icon icon2 = Icon.FromHandle(hIcon);
using Icon ico = (Icon)icon2.Clone();
return IconToPng(ico);
}
finally
{
DestroyIcon(hIcon);
}
}
catch
{
return null;
}
}
private static byte[] IconToPng(Icon ico)
{
using Bitmap bitmap = ico.ToBitmap();
using MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Png);
return memoryStream.ToArray();
}
}