OSIcon






4.84/5 (22投票s)
处理和检索系统图标的库。
注意:如果您使用 Visual Studio,请使用 Packet Manager NuGet 获取库:OSIcon
如果您想获取最新源代码、贡献、派生或提出问题,请访问github OSIcon 项目。
目录
引言
此库可以从扩展名和文件中检索图标,并提供附加信息,例如文件类型(硬盘、文件夹、PHP 脚本文件等)。该库还提供一个用于缓存图标的类,并创建一个包含所添加图标的 ImageList
。
Using the Code
库中的类
WinAPI
命名空间(包含所有 Win API 调用)Shell32 static
类(所有 Shell32.dll 的 API 调用)- DwmApi static类(所有 Dmwapi.dll 的 API 调用)
User32 static
类(所有 User32.dll 的 API 调用)Comctl32 static
类(所有 Comctl32.dll 的 API 调用)IShellFolder
接口
-
控件
FileExplorer
一个行为类似于 Windows 资源管理器的控件
- Utilities static类(辅助函数)
IconReader static
类(读取、处理图标)IconManager
类(带有缓存功能、自动创建ImageList
的IconReader
包装器)WindowsThumbnail
类用于检索任务栏上的 Windows 缩略图About static
类(存储有关库、作者、网页等的一些常量)
使用 IconReader 类
使用“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);
现在,如果您想从 shell32.dll 等资源文件中提取图标,可以这样做:“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);
在 Windows 资源管理器、FileZilla 等中,我们可以看到文件类型(文件夹、PHP 脚本、动态链接库等)。要检索该信息,我们需要使用一些 API 调用。使用 OSIcon,这非常简单:“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));
我们还可以从注册表检索文件扩展名并提取它们的图标,使用:“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);
使用“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]);
}
使用 IconManager 类
有时,我们需要显示文件,并且有数百个相同类型的文件,例如 .php;在这种情况下,您可以重用从第一个 PHP 文件获得的图标。(请参阅 FileExplorer 控件)
IconProperties
类IconsInfo
(存储图标信息和索引)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
该类已初始化并可供使用;现在,我们创建一个函数来显示“我的电脑”和路径内容
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
仅有一个“ImageList
”(应为 16 x 16px)和“LargeImageList
”。如果您想显示 XP 中引入的“ExtraLarge
”图标和 Vista 或更高版本中的“Jumbo
”图标,您必须将“LargeImageList
”更改为所需的大小,例如
/*
* "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;
}
如何摆脱添加的图标?可以这样做
// 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);
您无需使用 IconManager
类进行硬编码。这是一个示例
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);
历史
V3.0
- 重写代码以提高性能和可用性
- 添加了一个行为类似于 Windows 资源管理器的
FileExplorer
控件 - 为库添加了强密钥
- 库现在使用 .NET Framework 4.0 编译
V2.0
- 添加了
About
类 - 添加了更好的注释
- 添加了更多示例
- 更新了示例应用程序以使用新的图标大小
- 更新了示例应用程序以使用新库
IconProperties 类
- 添加了“
Remove
”函数,用于从指定大小中删除图标- 支持多大小标志(
IconReader.IconSize.Small
|IconReader.IconSize.Large
) - 返回一个包含已删除图标的
Dictionary<IconReader.IconSize, int>
,其中int
是ImageList
中图标的索引
- 支持多大小标志(
- 添加了三个“
IsValid
”函数bool IsValidEx(IconReader.IconSize size)
,与“IsValid(IconReader.IconSize size)
”相同,但还会检查图标是否不为NULL
bool IsValid()
,检查该实例是否包含图标bool IsValid(IconReader.IconSize size)
,检查该实例中是否存在指定大小的图标
- 将“
IconsInfo
”类型从struct
更改为Dictionary<IconReader.IconSize, Shell32.SHFILEINFO>
- 将“
IconsIndex
”类型从struct
更改为Dictionary<IconReader.IconSize, int>
- 将“
Icons
”类型从struct
更改为Dictionary<IconReader.IconSize, Icon>
- 实现了一个“
Tag
”对象 Disposable
类- “
IconProperties
”现在是一个类,以前是一个struct
IconManager 类
- 修复了“
AddEx
”函数,允许添加不同大小的更多图标 - 添加了注释
- 添加了两个“
Remove
”函数,允许从缓存和 ImageList 中删除图标bool Remove(string path, bool removeIconFromList)
,删除所有图标bool Remove(string path, IconReader.IconSize iconSize, bool removeIconFromList)
,仅删除指定大小的图标
- 添加了
private
“Add
”函数,添加图标到列表时的常见操作(以消除冗余) - 添加了“
IsValidEx
”函数,与“IsValid
”相同,但返回匹配的“IconProperties
”;否则返回一个新实例 - 添加了两个新构造函数
public IconManager(bool createSmallIconList, bool createLargeIconList, bool createExtraLargeIconList, bool createJumboIconList)
public IconManager(bool createSmallIconList, bool createLargeIconList, bool createExtraLargeIconList, bool createJumboIconList, bool optimizeToOS)
- 将“
ImageListSmall
”和“ImageListLarge
”ImageLists
替换为“IImageList
”Dictionary<IconReader.IconSize, ImageList>
- 添加了“
IconSizeAllSupported
”只读变量,包含当前操作系统支持的所有图标大小 - 添加了“
IconManager.IconSizeAll
”常量,包含所有图标大小(Small | Large | ExtraLarge | Jumbo)
IconReader 类
- 更改了所有包含“
IconReader.IconSize
”的函数,以支持新的图标大小(ExtraLarge
,Jumbo
) - 添加了“
ExtractIconFromResource
”函数,从程序集中按名称提取图标 - 添加了“
ExtractIconsFromFile
”函数,从文件中提取所有图标;返回“Icon[]
” - 添加了“
ExtractIconFromFileEx
”函数,与ExtractIconFromFile
相同,但支持更大尺寸和图标信息 - 为“
IconReader.IconSize
”添加了两个新图标大小IconReader.Iconsize.ExtraLarge
(48x48 像素),XP 或更高版本支持IconReader.Iconsize.Jumbo
(256x256 像素),Vista 或更高版本支持
- 将函数“
ExtractIcon
”重命名为“ExtractIconFromFile
”
About 类
- 添加了“
ProjectAuthor
”常量,我的名字 - 添加了“
ProjecWWW
”常量,本页网址
V1.0.01
- 修改以纠正严重的格式和拼写错误 - JSOP - 2010年1月3日
V1.0
- 首次发布