OSIcon






4.84/5 (22 votes)
Library for handling and retrieving system icons
NOTE: If you are using Visual Studio use the Packet Manager NuGet to obtain the library: OSIcon
If you want to obtain the most recent source code, contribute, fork or open an issue, please go to github OSIcon project.
Table of Contents
Introduction
This library can retrieve icons from extensions and files, with additional information like file type (hard drive, folder, PHP Script File, ...). The library also provides a class for CACHE icons and creates an ImageList
with the added icons.
Using the Code
Classes in the library
WinAPI
namespace (Contains all Win API calls)Shell32 static
class (all API calls for Shell32.dll)- DwmApi static class (all API calls for Dmwapi.dll)
User32 static
class (all API calls for User32.dll)Comctl32 static
class (all API calls for Comctl32.dll)IShellFolder
interface
-
Controls
FileExplorer
A control that behaves like Windows Explorer
- Utilities static class (helper functions)
IconReader static
class (read, handle icons)IconManager
class (IconReader
wrapper with caching features, automatic creation ofImageList
)WindowsThumbnail
class to retrieve Windows thumbnails on taskbarAbout static
class (stores some constants about the library, author, webpage, etc.)
Using the IconReader class
Get any icon from a file using "OSIcon.IconReader.ExtractIconFromFile(path, isLarge);
".
// To extract the file icon we simply can do:
// First param will be the path to file.
// Last param define icon size (true = Large, false = Small)
Icon icon = OSIcon.IconReader.ExtractIconFromFile("C:\\pathtofile.png", true);
Now, if you want to extract an icon from a resource file like shell32.dll, you can do: "OSIcon.IconReader.ExtractIconFromFile(path, iconIndex);
".
// 5, is the icon index
// http://cfs6.tistory.com/upload_control/download.blog?
// fhandle=YmxvZzEwMTUzNkBmczYudGlzdG9yeS5jb206L2F0dGFjaC8wLzAxMDAwMDAwMDAwMC5qcGc%3D
// 5 will return Open Folder image from shell32.dll
Icon icon = OSIcon.IconReader.ExtractIconFromFile("C:\\Windows\\system32\\shell32.dll", 5);
In Windows Explorer, FileZilla, etc., we can see the file type (Folder, PHP Script, Dynamic Link Library, etc.). To retrieve that information, we need to use some API calls. Using OSIcon, this is quite simple: "OSIcon.IconReader.GetFileIcon(pathOrExtension, IconReader.IconSize);
".
// NOTE: filename can be an partial extension (.png), or a full path ("C:\\file.png")
// IconInfo class store all information about the icon
IconInfo iconInfo = OSIcon.IconReader.GetFileIcon(".png", IconReader.IconSize.Large);
MessageBox.Show(string.Format("Display Name: {0}\nFile Type: {1}",
iconInfo.DisplayName, iconInfo.TypeName));
We can also retrieve file extensions from regedit and extract their icons, using: "OSIcon.IconReader.GetFileTypeAndIcon();
".
// Get all available extensions
// Dictionary Key = extension, value = path to icon
Dictionary<string, string> _iconList = _iconList =
OSIcon.IconReader.GetFileTypeAndIcon();
// Foreach each extension
foreach (KeyValuePair<string, string> list in _iconList)
// Extract icon from file
Icon icon = OSIcon.IconReader.ExtractIconFromFile(_iconList[extension],
isLarge ? true : false);
Getting all icons on a file is quite simple, using: "ExtractIconsFromFile(path, isLarge);
".
// From Sample Application see: "IconExplorer.cs" UserControl
filename = "C:\\Windows\\system32\\shell.dll";
Icon[] icons = IconReader.ExtractIconsFromFile(filename, true);
if(icons.Length == 0) return; // No icons found, return
// Loop through icons array
for (int i = 0; i < icons.Length; i++)
{
// Do something here, im adding icon to an ImageList
imageList.Images.Add(i.ToString(), icons[i]);
}
Using the IconManager class
Sometimes, we need to display our files and have 100s of files of the same type, e.g., .php; you can reuse icons obtained from the first PHP file in that case. (Please see FileExplorer control)
IconProperties
classIconsInfo
(stores icons information and indexes)Dictionary<IconReader.IconSize, IconInfo>
// If you want create a ImageList to store collected icons use true
// Small ImageList (true/false), Large ImageList (true/false)
// new OSIcon.IconManager() == new OSIcon.IconManager(true, true)
//
// Initalize Class, and create small, large, extralarge, jumbo
// Last param if set true, disable ExtraLarge or Jumbo if not supported by current OS
OSIcon.IconManager iconManager = new OSIcon.IconManager(true, true, true, true, true);
// Add some special icons to be used
// Add folder images
iconManager.AddFolder();
// Add Computer Drives (DVD Drive, Floppy, Hard Disk, etc.)
iconManager.AddComputerDrives();
// You also can add manualy, icons images to ImageList
// I use ":" because file path can't have ':' in name, so its a special mark
iconManager.ImageList[IconReader.IconSize.Small].Images.Add(
":Up-icon:", Properties.Resources.Up_icon16x16);
iconManager.ImageList[IconReader.IconSize.Large].Images.Add(
":Up-icon:", Properties.Resources.Up_icon32x32);
// ExtraLarge was introduced on XP so if you running XP
// or above add ExtraLarge capabilities
if (OSIcon.Utils.IsXpOrAbove())
{
iconManager.ImageList[IconReader.IconSize.ExtraLarge].Images.Add(
":Up-icon:", Properties.Resources.Up_icon48x48);
}
// Jumbo was introduced on Vista so if you
// running Vista or above add Jumbo capabilities
if (OSIcon.Utils.IsVistaOrAbove())
{
iconManager.ImageList[IconReader.IconSize.Jumbo].Images.Add(
":Up-icon:", Properties.Resources.Up_icon256x256);
}
// NOTE: iconManager.ImageList[IconReader.Size]
// can be assign in any control that uses ImageList
The class is initialized and ready to use; now, we create a function to show My Computer and the path contents:
void ShowMyComputer()
{
// List all drives on computer
foreach (string drive in Directory.GetLogicalDrives())
{
// Always when you add a icon to list it will return IconProperties
// and cache it on class
OSIcon.IconManager.IconProperties iconProp =
OSIcon.iconManager.AddEx(drive, IconManager.IconSizeSupported);
// Do something here!, sample from OSIcon Explorer:
var item = new ListViewItem(iconProp[IconSize.Small].DisplayName)
{
ImageIndex = iconProp[IconSize.Small].ItemIndex
};
item.SubItems.Add(string.Empty);
item.SubItems.Add(iconProp.IconsInfo[IconSize.Small].TypeName);
item.Tag = drive;
lvFileExplorer.Items.Add(item);
}
}
// Next function will show path contents
public void ShowPathContents(string path)
{
if (path == null)
return;
// Path is empty so Show MyComputer
if (path == string.Empty)
{
ShowMyComputer();
return;
}
try
{
Cursor = Cursors.WaitCursor;
btnGoUp.Enabled = true;
RewindManager.Add(path);
btnGoBack.Enabled = RewindManager.CanPrevious;
btnGoForward.Enabled = RewindManager.CanForward;
lbSelected.Text = string.Empty;
CurrentPath = path;
lvFileExplorer.BeginUpdate();
lvFileExplorer.Items.Clear();
//CreateGoUpFolder(path);
TotalFilesSize = 0;
TotalFolders = 0;
TotalFiles = 0;
// Loop through folders inside current folder
foreach (var folder in Directory.EnumerateDirectories(path))
{
// Get folder name from path
var dirInfo = new DirectoryInfo(folder);
// Remove system directories
if ((dirInfo.Attributes & FileAttributes.System) == FileAttributes.System)
continue;
var item = new ListViewItem(Path.GetFileName(folder)) { Tag = folder };
var iconProp = IconManager[IconManager.FolderClosed];
item.ImageIndex = iconProp[IconSize.Small].ItemIndex;
item.SubItems.Add(dirInfo.LastWriteTime.ToString(CultureInfo.CurrentCulture));
item.SubItems.Add(iconProp[IconSize.Small].TypeName);
item.SubItems.Add(string.Empty);
lvFileExplorer.Items.Add(item);
TotalFolders++;
}
// Loop through Files inside current folder
foreach (var file in Directory.EnumerateFiles(path))
{
// Get some addition file information like size, name, extension, etc...
var fi = new FileInfo(file);
// Remove system directories
if ((fi.Attributes & FileAttributes.System) == FileAttributes.System)
continue;
var iconProp = IconManager.AddEx(fi.Extension, IconManager.IconsSizeSupported);
var item = new ListViewItem(fi.Name)
{
Tag = fi.FullName,
ImageIndex = iconProp[IconSize.Small].ItemIndex
};
item.SubItems.Add(fi.LastWriteTime.ToString(CultureInfo.CurrentCulture));
item.SubItems.Add(iconProp.IconsInfo[IconSize.Small].TypeName);
item.SubItems.Add(string.Format(" {0:##.##} {1}",
Utilities.FormatByteSize(fi.Length), Utilities.GetSizeNameFromBytes(fi.Length, false)));
lvFileExplorer.Items.Add(item);
TotalFilesSize += fi.Length;
TotalFiles++;
}
// Lets make some status and retrieve total folders, files and their total size
string textToSet = string.Empty;
if (TotalFolders > 0)
textToSet += string.Format("{0} {1}", TotalFolders,
Utilities.ConvertPlural(TotalFolders, "Folder"));
if (TotalFiles > 0)
{
if (textToSet != "Total:")
textToSet += " &";
textToSet += string.Format(" {0:##.##} {1} in {2} {3}",
Utilities.FormatByteSize(TotalFilesSize), Utilities.GetSizeNameFromBytes
(TotalFilesSize, false), TotalFiles, Utilities.ConvertPlural(TotalFiles, "File"));
}
if (textToSet == "Total:")
textToSet = "Empty";
tbAddress.Text = CurrentPath;
lbTotal.Text = textToSet;
}
catch (Exception ex)
{
MessageBox.Show(string.Format("Error on trying access: {0}\n\n{1}", path, ex.Message),
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
lvFileExplorer.EndUpdate();
Cursor = Cursors.Default;
RebuildNavigationHistory();
}
}
ListView
only has an "ImageList
" (should be 16 x 16px) and "LargeImageList
". If you want to show "ExtraLarge
" icons introduced in XP, and "Jumbo
" from Vista or above, you have to change "LargeImageList
" to the desired size, like:
/*
* "fileExplorerList" is our ListView
* View:
* 0 = LargeIcons
* 1 = Details
* 2 = Small Icons
* 3 = List
* 4 = Title
* End View Enumeration
* 5 = ExtraLarge
* 6 = Jumbo
*/
private void ChangeListViewV(uint index)
{
// If view is bigger than 4 means user wants ExtraLarge or Jumbo
// To show that sizes View must be set to: View.LargeIcon
// Also we have to change Large ImageList to the desired one
if (index > 4)
{
// we change ImageList because ListView only have ImageList and LargeImageList
switch (index)
{
case 5:
fileExplorerList.LargeImageList =
iconManager.ImageList[IconReader.IconSize.ExtraLarge];
break;
case 6:
fileExplorerList.LargeImageList =
iconManager.ImageList[IconReader.IconSize.Jumbo];
break;
}
fileExplorerList.View = View.LargeIcon;
return;
}
// View is under normal (small or large)
// Get back to normal
fileExplorerList.LargeImageList = iconManager.ImageList[IconReader.IconSize.Large];
fileExplorerList.View = (View)index;
}
How can you get rid of the added icons? It can be done like so:
// I dont need .txt icon anymore, and i will not use it from ImageList
iconManager.Remove(".txt", true);
// I dont need .wav icon anymore, but i still use it from ImageList
iconManager.Remove(".wav", false);
// IconSize Small is to small and Jumbo is too big for what i want
iconManager.Remove(".exe", IconReader.IconSize.Small |
IconReader.IconSize.Jumbo, true);
You need not hard-code with the IconManager
class. Here is an example:
string name = ".dll";
// Bad Way:
IconProperties iconProp = iconManager.IconList[name];
if(!iconProp.IsValid(name, IconReader.IconSize.Small))
{
OSIcon.WinAPI.Shell32.SHFILEINFO shfi = new Shell32.SHFILEINFO();
iconManager.AddEx(name, IconReader.IconSize.Small, ref shfi);
}
if(!iconProp.IsValid(name, IconReader.IconSize.Jumbo))
{
OSIcon.WinAPI.Shell32.SHFILEINFO shfi = new Shell32.SHFILEINFO();
iconManager.AddEx(name, IconReader.IconSize.Jumbo, ref shfi);
}
// Good Way:
IconProperties iconProp = iconManager.AddEx(name, IconReader.IconSize.Small | IconReader.IconSize.Jumbo);
History
V3.0
- Rewrite the code for better performance and usage
- Added a
FileExplorer
control that behaves like the Windows explorer - Added a strong key to the library
- Library is now compiled with .NET Framework 4.0
V2.0
- Added
About
class - Added better commentaries
- Added more samples
- Updated sample application to use new icon sizes
- Updated sample application to use the new library
IconProperties class
- Added the "
Remove
" function, to remove an icon from a specified size- Supports multi sizes flags (
IconReader.IconSize.Small
|IconReader.IconSize.Large
) - Returns a
Dictionary<IconReader.IconSize, int>
with removed icons, whereint
is the icon index on theImageList
- Supports multi sizes flags (
- Added three "
IsValid
" functionsbool IsValidEx(IconReader.IconSize size)
, same as "IsValid(IconReader.IconSize size)
", but also checks if the icon is notNULL
bool IsValid()
, checks if that instance contains an iconbool IsValid(IconReader.IconSize size)
, checks if an icon of a specified size exists in that instance
- Changed "
IconsInfo
" type fromstruct
toDictionary<IconReader.IconSize, Shell32.SHFILEINFO>
- Changed "
IconsIndex
" type fromstruct
toDictionary<IconReader.IconSize, int>
- Changed "
Icons
" type fromstruct
toDictionary<IconReader.IconSize, Icon>
- Implemented a "
Tag
" object Disposable
class- "
IconProperties
" is now a class, was astruct
before
IconManager class
- Fixed the "
AddEx
" function to allow adding more icons of different sizes - Added commentaries
- Added two "
Remove
" functions, allows removing icons from the cache and from the ImageListbool Remove(string path, bool removeIconFromList)
, removes all iconsbool Remove(string path, IconReader.IconSize iconSize, bool removeIconFromList)
, removes icons of a specified size only
- Added
private
"Add
" function, common actions when adding icons to list (to remove redundancy) - Added "
IsValidEx
" function, same as "IsValid
", but returns the matched "IconProperties
"; otherwise returns a new instance - Added two new constructors:
public IconManager(bool createSmallIconList, bool createLargeIconList, bool createExtraLargeIconList, bool createJumboIconList)
public IconManager(bool createSmallIconList, bool createLargeIconList, bool createExtraLargeIconList, bool createJumboIconList, bool optimizeToOS)
- Replaced "
ImageListSmall
" and "ImageListLarge
"ImageLists
with "IImageList
"Dictionary<IconReader.IconSize, ImageList>
- Added "
IconSizeAllSupported
" readonly variable, contains all icon sizes supported by the current OS - Added "
IconManager.IconSizeAll
" constant, contains all icon sizes (Small | Large | ExtraLarge | Jumbo)
IconReader class
- Changed all functions that contain a "
IconReader.IconSize
" to support new icon sizes (ExtraLarge
,Jumbo
) - Added the "
ExtractIconFromResource
" function, extracts an icon by name from the assembly - Added the "
ExtractIconsFromFile
" function, extracts all icons from a file; returns "Icon[]
" - Added the "
ExtractIconFromFileEx
" function, identical toExtractIconFromFile
, but supports bigger sizes and icon information - Added two new icon sizes to "
IconReader.IconSize
"IconReader.Iconsize.ExtraLarge
(48x48 px.), XP or above supportedIconReader.Iconsize.Jumbo
(256x256 px.), Vista or above supported
- Renamed function "
ExtractIcon
" to "ExtractIconFromFile
"
About class
- Added the "
ProjectAuthor
" constant, my name - Added the "
ProjecWWW
" constant, this page URL
V1.0.01
- Modified to correct egregious formatting and spelling errors - JSOP - 01/03/2010
V1.0
- First release