我一直在寻找一个c#库,它获取了许多大小的给定路径的图标,最后当我得到我需要的类时,它有一个问题:
此方法获取给定路径的图标:
public static BitmapSource GetIcon(string FileName, bool small, bool checkDisk, bool addOverlay)
{
SHFILEINFO shinfo = new SHFILEINFO();
uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
uint SHGFI_LINKOVERLAY = 0x000008000;
uint flags;
if (small)
{
flags = SHGFI_ICON | SHGFI_SMALLICON;
}
else
{
flags = SHGFI_ICON | SHGFI_LARGEICON;
}
if (!checkDisk)
flags |= SHGFI_USEFILEATTRIBUTES;
if (addOverlay)
flags |= SHGFI_LINKOVERLAY;
var res = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), flags);
if (res == 0)
{
throw (new System.IO.FileNotFoundException());
}
var ico = System.Drawing.Icon.FromHandle(shinfo.hIcon); //**Here**
var bs = BitmapFromIcon(ico);
ico.Dispose();
bs.Freeze();
DestroyIcon(shinfo.hIcon);
// CloseHandle(shinfo.hIcon); it always give exception
return bs;
}
public static extern Boolean CloseHandle(IntPtr handle);
此问题中的上一个代码正常工作,但是 AFTER 成功获取目录中文件路径的图标,它会给出异常这一行:
var ico = System.Drawing.Icon.FromHandle(shinfo.hIcon);
An exception of type 'System.IO.FileNotFoundException' occurred in WPF_REMOTE.exe but was not handled in user code
Additional information: Unable to find the specified file.
那么为什么会这样?
更新: 我发现它发生的原因是因为有一个包含unicode字符的路径而我需要使用SHFILEINFOW,仍然无法计算如何更改{{1转到SHFILEINFO
关于第SHFILEINFOW
行的另一个问题总是例外:
CloseHandle(shinfo.hIcon);
An exception of type 'System.Runtime.InteropServices.SEHException' occurred in WPF_REMOTE.exe but was not handled in user code
我想知道它为什么不起作用!如果方法在没有它的情况下工作,我为什么要使用它呢。
如果你有任何改进我可以在这堂课中使用告诉我,在此先感谢。
答案 0 :(得分:3)
在编辑了一些代码后我得到了它,你可以从这个库中轻松获取图标,在我的情况下我需要图标为byte []
public class IconHelper
{
// Constants that we need in the function call
private const int SHGFI_ICON = 0x100;
private const int SHGFI_SMALLICON = 0x1;
private const int SHGFI_LARGEICON = 0x0;
private const int SHIL_JUMBO = 0x4;
private const int SHIL_EXTRALARGE = 0x2;
// This structure will contain information about the file
public struct SHFILEINFO
{
// Handle to the icon representing the file
public IntPtr hIcon;
// Index of the icon within the image list
public int iIcon;
// Various attributes of the file
public uint dwAttributes;
// Path to the file
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string szDisplayName;
// File type
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
[System.Runtime.InteropServices.DllImport("Kernel32.dll")]
public static extern Boolean CloseHandle(IntPtr handle);
private struct IMAGELISTDRAWPARAMS
{
public int cbSize;
public IntPtr himl;
public int i;
public IntPtr hdcDst;
public int x;
public int y;
public int cx;
public int cy;
public int xBitmap; // x offest from the upperleft of bitmap
public int yBitmap; // y offset from the upperleft of bitmap
public int rgbBk;
public int rgbFg;
public int fStyle;
public int dwRop;
public int fState;
public int Frame;
public int crEffect;
}
[StructLayout(LayoutKind.Sequential)]
private struct IMAGEINFO
{
public IntPtr hbmImage;
public IntPtr hbmMask;
public int Unused1;
public int Unused2;
public Rect rcImage;
}
[DllImport("shell32.dll", EntryPoint = "#727")]
private extern static int SHGetImageList(
int iImageList,
ref Guid riid,
out IImageList ppv
);
// The signature of SHGetFileInfo (located in Shell32.dll)
[DllImport("Shell32.dll", CharSet = CharSet.Unicode)]
public static extern int SHGetFileInfo(string pszPath, int dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, uint uFlags);
[DllImport("Shell32.dll", CharSet = CharSet.Unicode)]
public static extern int SHGetFileInfo(IntPtr pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, uint uFlags);
[DllImport("shell32.dll", SetLastError = true)]
static extern int SHGetSpecialFolderLocation(IntPtr hwndOwner, Int32 nFolder,
ref IntPtr ppidl);
[DllImport("user32")]
public static extern int DestroyIcon(IntPtr hIcon);
public struct pair
{
public System.Drawing.Icon icon { get; set; }
public IntPtr iconHandleToDestroy { set; get; }
}
private static byte[] ByteFromIcon(System.Drawing.Icon ic)
{
var icon = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(ic.Handle,
System.Windows.Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
icon.Freeze();
byte[] data;
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(icon));
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
data = ms.ToArray();
}
return data;
}
private static byte[] GetSmallIcon(string FileName, IconSize iconSize)
{
SHFILEINFO shinfo = new SHFILEINFO();
uint flags;
if (iconSize == IconSize.Small)
{
flags = SHGFI_ICON | SHGFI_SMALLICON;
}
else
{
flags = SHGFI_ICON | SHGFI_LARGEICON;
}
var res = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), flags);
if (res == 0)
{
throw (new System.IO.FileNotFoundException());
}
var ico = (System.Drawing.Icon)System.Drawing.Icon.FromHandle(shinfo.hIcon);
var bs = ByteFromIcon(ico);
ico.Dispose();
DestroyIcon(shinfo.hIcon);
return bs;
}
private static byte[] GetLargeIcon(string FileName)
{
SHFILEINFO shinfo = new SHFILEINFO();
uint SHGFI_SYSICONINDEX = 0x4000;
int FILE_ATTRIBUTE_NORMAL = 0x80;
uint flags;
flags = SHGFI_SYSICONINDEX;
var res = SHGetFileInfo(FileName, FILE_ATTRIBUTE_NORMAL, ref shinfo, Marshal.SizeOf(shinfo), flags);
if (res == 0)
{
throw (new System.IO.FileNotFoundException());
}
var iconIndex = shinfo.iIcon;
Guid iidImageList = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950");
IImageList iml;
int size = SHIL_EXTRALARGE;
var hres = SHGetImageList(size, ref iidImageList, out iml); // writes iml
IntPtr hIcon = IntPtr.Zero;
int ILD_TRANSPARENT = 1;
hres = iml.GetIcon(iconIndex, ILD_TRANSPARENT, ref hIcon);
var ico = System.Drawing.Icon.FromHandle(hIcon);
var bs = ByteFromIcon(ico);
ico.Dispose();
DestroyIcon(hIcon);
return bs;
}
}
你可以为图标
获得四种不同的尺寸