求大牛解惑,关于ShGetFileInfo

fanbingyuan 2011-01-01 05:37:30
上代码 调用SHGetFileInfo

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct FileInfoStruct
{
public IntPtr hIcon;
public int iIcon;
public int dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
}
class Win32
{

/// <summary>
/// 以下为获取图标Api
/// </summary>
public const uint SHGFI_ICON = 0x100;
public const uint SHGFI_LARGEICON = 0x0; // 'Large icon
public const uint SHGFI_SMALLICON = 0x1; // 'Small icon
public const uint SHGFI_USEFILEATTRIBUTES = 0x10;

[DllImport("shell32.dll",EntryPoint="SHGetFileInfo",SetLastError=true,CharSet=CharSet.Auto)]
public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref FileInfoStruct psfi, uint cbSizeFileInfo, uint uFlags);

[DllImport("shell32.dll",EntryPoint="ExtractIconEx")]
public static extern uint ExtractIconEx(string lpszFile, int nIconIndex, int[] phiconLarge, int[] phiconSmall, uint nIcons);

[DllImport("user32.dll",EntryPoint="DestoryIcon")]
public static extern int DestoryIcon(IntPtr hIcon);
}

写的方法

public static class GetSystemIcon
{
///
/// 依据文件名读取图标,若指定文件不存在,则返回空值。
///
///
///
public static Icon GetIconByFileName(string fileName,bool isLargeIcon)
{
if (fileName == null || fileName.Equals(string.Empty)) return null;
if (!File.Exists(fileName)) return null;

FileInfoStruct psfi = new FileInfoStruct();
if (isLargeIcon) //获取大图标
{
Win32.SHGetFileInfo(fileName, 0, ref psfi, (uint)Marshal.SizeOf(psfi), Win32.SHGFI_ICON | Win32.SHGFI_USEFILEATTRIBUTES | Win32.SHGFI_LARGEICON);
}
else //获取小图标
{
Win32.SHGetFileInfo(fileName, 0, ref psfi, (uint)Marshal.SizeOf(psfi), Win32.SHGFI_ICON | Win32.SHGFI_USEFILEATTRIBUTES | Win32.SHGFI_SMALLICON);
}
Icon icon = Icon.FromHandle(psfi.hIcon).Clone() as Icon;
Win32.DestoryIcon(psfi.hIcon);
return icon;
}
}

调用的时候老是提示传入的win32句柄无效。昨天还能取出来,今天改了改。不知道哪不对了,分不多了。。。包涵包涵
...全文
212 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
杀猪杀屁股,各有各的搞法,抛开那个结构吧,因为里面有个字符数组,在。Net中不好定义,看看我的做法:

class Program
{
const int SHGFI_TYPENAME = 0x000000400;
const int SHGFI_DISPLAYNAME = 0x000000200;
const int sizeOfFileInfo = 352;//FileInfoStruct结构大小
[DllImport("shell32.dll", EntryPoint = "SHGetFileInfo", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr SHGetFileInfo(string name, int attr, IntPtr pInfo, int infoSize, int flags);
static void Main(string[] args)
{
string name = @"F:\Title.bmp";
IntPtr pInfo = Marshal.AllocHGlobal(sizeOfFileInfo);//申请平台内存
SHGetFileInfo(name, -1, pInfo, sizeOfFileInfo, SHGFI_DISPLAYNAME);
byte[] buffers = new byte[260];//读取指定位置指定字节,就是结构中的szDisplayName字段
for (int i = 12; i < buffers.Length; i++)
{
buffers[i-12] = Marshal.ReadByte(pInfo, i);
}
int m = 0;//因为读来的是Unicode双字节字符,做下判断
for (int i = 0; i < buffers.Length; i++)
{
if (buffers[i] == 0)
m++;
else
m--;
if(m==2)
break;
Console.Write((char)buffers[i]);
}
Console.WriteLine();
Marshal.FreeHGlobal(pInfo);
}
}
}



输出 Title.BMP, 结果正确
wuyq11 2011-01-01
  • 打赏
  • 举报
回复
判断
IntPtr hIcon=(IntPtr)ExtractIcon(this.Handle,FileName,iIndex);
if(hIcon != IntPtr.Zero)
  • 打赏
  • 举报
回复
SHGetFileInfo函数的第三个参数应该是一个文件信息结构指针
那就不能简单的ref了(原因很复杂,大概意思就是变量在托管的内存中会因为垃圾回收及优化内存的原因可能改变位置)
结构转指针,和指针转结构,。Net提供了专门的类和方法:
System.Runtime.InteropServices.Marshal类的两个方法去MSDN查一下用法:
Marshal.PtrToStructure//平台指针转托管结构
StructureToPtr托管结构转非平台指针//

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧