我的asp.net网站需要树文件。 为了获取图标,我尝试使用SHGetFileInfo api函数。 在非asp.net应用程序,它运行良好,返回更正图标。当我在asp.net上下文时,我得到了:
尝试读取或写入受保护的内存。
怎么了?我可以在asp.net上下文获得fiel图标吗?
代码:
public class ExtractIcon
{
[DllImport("Shell32.dll")]
private static extern int SHGetFileInfo(
string pszPath,
uint dwFileAttributes,
out SHFILEINFO psfi,
uint cbfileInfo,
uint uFlags
);
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public SHFILEINFO(bool b)
{
hIcon = IntPtr.Zero;
iIcon = 0;
dwAttributes = 0;
szDisplayName = String.Empty;
szTypeName = String.Empty;
}
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.LPStr, SizeConst = 80)]
public string szTypeName;
};
public const uint SHGFI_ICON = 0x000000100; // get icon
public const uint SHGFI_DISPLAYNAME = 0x000000200; // get display name
public const uint SHGFI_TYPENAME = 0x000000400; // get type name
public const uint SHGFI_ATTRIBUTES = 0x000000800; // get attributes
public const uint SHGFI_ICONLOCATION = 0x000001000; // get icon location
public const uint SHGFI_EXETYPE = 0x000002000; // return exe type
public const uint SHGFI_SYSICONINDEX = 0x000004000; // get system icon index
public const uint SHGFI_LINKOVERLAY = 0x000008000; // put a link overlay on icon
public const uint SHGFI_SELECTED = 0x000010000; // show icon in selected state
public const uint SHGFI_ATTR_SPECIFIED = 0x000020000; // get only specified attributes
public const uint SHGFI_LARGEICON = 0x000000000; // get large icon
public const uint SHGFI_SMALLICON = 0x000000001; // get small icon
public const uint SHGFI_OPENICON = 0x000000002; // get open icon
public const uint SHGFI_SHELLICONSIZE = 0x000000004; // get shell size icon
public const uint SHGFI_PIDL = 0x000000008; // pszPath is a pidl
public const uint SHGFI_USEFILEATTRIBUTES = 0x000000010; // use passed dwFileAttribute
public const uint SHGFI_ADDOVERLAYS = 0x000000020;
public const uint SHGFI_OVERLAYINDEX = 0x000000040;
private static Icon GetIcon(string strPath, uint flags)
{
SHFILEINFO info = new SHFILEINFO(true);
int cbFileInfo = Marshal.SizeOf(info);
SHGetFileInfo(strPath, 256, out info, (uint)cbFileInfo, flags);
return Icon.FromHandle(info.hIcon);
}
/// <summary>
/// Get the associated Icon for a file or application, this method always returns
/// an icon. If the strPath is invalid or there is no idonc the default icon is returned
/// </summary>
/// <param name="strPath">full path to the file</param>
/// <param name="bSmall">if true, the 16x16 icon is returned otherwise the 32x32</param>
/// <returns></returns>
public static Icon GetIcon(string strPath, bool bSmall)
{
uint flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
flags |= bSmall ? SHGFI_SMALLICON : SHGFI_LARGEICON;
return GetIcon(strPath, flags);
}
public static Icon GetIcon(string strPath, bool bSmall, bool bOpened)
{
uint flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
flags |= bSmall ? SHGFI_SMALLICON : SHGFI_LARGEICON;
flags |= bOpened ? SHGFI_OPENICON : 0;
return GetIcon(strPath, flags);
}
}
答案 0 :(得分:1)
您用于SHGetFileInfo
的P / Invoke签名是错误的 - 请使用at PInvoke.net。
SHGetFileInfo
返回在访问返回的数据之前需要检查成功的值。如果API调用失败,则访问您期望的Icon的结果是不可预测的(通常是不好的)。
一旦你知道错误是什么,你就可以把它作为一个单独的问题来解决。从托管代码P / Invoke Win32 API时,永远不应忽略错误检查代码。请阅读MSDN docs,了解成功与预期的错误。
在你的情况下:
SHGetFileInfo(strPath, 256, out info, (uint)cbFileInfo, flags);
return Icon.FromHandle(info.hIcon);
应该是这样的
IntPtr result = SHGetFileInfo(strPath, 256, out info, (uint)cbFileInfo, flags);
if (result != IntPtr.Zero)
{
return Icon.FromHandle(info.hIcon);
}
else
{
// add error handling here
}