Simple SystemIconsHandler for ASP.NET
One of web projects I'm working on needed a web file explorer. There was one specific requirement for this explorer, files should be displayed with icons they have on server. I decided that the best way will be dedicated HttpHandler.
So first I needed to P/Invoke SHGetFileInfo and DestroyIcon functions:
So first I needed to P/Invoke SHGetFileInfo and DestroyIcon functions:
/// <summary>With those two functions getting icon for file looks like this:
/// Retrieves information about an object in the file system, such as a file, folder, directory, or drive root
/// </summary>
/// <param name="pszPath">Contains the path and file name. Both absolute and relative paths are valid</param>
/// <param name="dwFileAttributes">A combination of one or more file attribute flags</param>
/// <param name="psfi">SHFILEINFO structure to receive the file information</param>
/// <param name="cbSizeFileInfo">The size, in bytes, of the SHFILEINFO structure</param>
/// <param name="uFlags">The flags that specify the file information to retrieve</param>
/// <returns>Meaning depends on the uFlags parameter</returns>
[DllImport("shell32.dll")]
static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFileInfo psfi, uint cbSizeFileInfo, uint uFlags);
/// <summary>
/// Destroys an icon and frees any memory the icon occupied
/// </summary>
/// <param name="handle">Handle to the icon to be destroyed</param>
/// <returns>If the function succeeds, the return value is nonzero</returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
extern static bool DestroyIcon(IntPtr handle);
Icon tempIcon;There is only one difference when getting icon for folder:
SHFileInfo tempFileInfo = new SHFileInfo();
//Getting SHFileInfo for file (based on extension)
SHGetFileInfo(extension, 0, ref tempFileInfo, (uint)Marshal.SizeOf(tempFileInfo), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES | (uint)iconSize);
//Creating Icon based on SHFileInfo
tempIcon = (Icon)Icon.FromHandle(tempFileInfo.hIcon);
//Making managed clone
Icon managedIcon = (Icon)tempIcon.Clone();
//Destroying unmanaged handle
DestroyIcon(tempIcon.Handle);
return managedIcon;
//Getting SHFileInfo for folder
SHGetFileInfo(null,
FILE_ATTRIBUTE_DIRECTORY, ref tempFileInfo, (uint)Marshal.SizeOf(tempFileInfo), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES | (uint)iconSize | (uint)folderType );
So having this done, all what is left is processing request:
public void ProcessRequest(HttpContext context)
{
Icon systemIcon = null;
//Ckecking parameters
if(!String.IsNullOrEmpty(context.Request.QueryString["type"])
&& !String.IsNullOrEmpty(context.Request.QueryString["size"]))
{
//Setting icon size
IconSize size = IconSize.SHGFI_SMALLICON;
if (context.Request.QueryString["size"].Equals("large"))
size = IconSize.SHGFI_LARGEICON;
//Getting icon
if (context.Request.QueryString["type"].Equals("dir"))
systemIcon = GetFolderIcon(size,
FolderType.SHGFI_CLOSEICON);
else if(context.Request.QueryString["type"].Equals("file"))
systemIcon = GetExtensionIcon(
context.Request.QueryString["ext"], size);
}
if (systemIcon != null)
{
MemoryStream systemIconStream = new MemoryStream();
//Converting icon to .png
systemIcon.ToBitmap().Save(systemIconStream,
ImageFormat.Png);
systemIconStream.Close();
byte[] systemIconBytes = systemIconStream.GetBuffer();
//Setting the response
context.Response.ContentType = "image/png";
context.Response.BufferOutput = true;
context.Response.OutputStream.Write(systemIconBytes, 0,
systemIconBytes.Length);
}
}
Simple example can be found here. Below you can see it's result.