#region Win32 Klassen
using System;
using System.Runtime.InteropServices;
using System.Drawing;
using MimetypeHelper.Properties;
/// <summary> Summary description for NativeIcon.</summary>
public class NativeIcon
{
#region WIN32
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern int SHGetFileInfo(
string pszPath,
int dwFileAttributes,
out SHFILEINFO psfi,
uint cbfileInfo,
SHGFI uFlags);
/// <summary>Maximal Length of unmanaged Windows-Path-strings</summary>
private const int MAX_PATH = 260;
/// <summary>Maximal Length of unmanaged Typename</summary>
private const int MAX_TYPE = 80;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct SHFILEINFO
{
public SHFILEINFO(bool b)
{
hIcon = IntPtr.Zero;
iIcon = 0;
dwAttributes = 0;
szDisplayName = "";
szTypeName = "";
}
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_TYPE)]
public string szTypeName;
};
private NativeIcon()
{
}
[Flags]
enum SHGFI : int
{
/// <summary>get icon</summary>
Icon = 0x000000100,
/// <summary>get display name</summary>
DisplayName = 0x000000200,
/// <summary>get type name</summary>
TypeName = 0x000000400,
/// <summary>get attributes</summary>
Attributes = 0x000000800,
/// <summary>get icon location</summary>
IconLocation = 0x000001000,
/// <summary>return exe type</summary>
ExeType = 0x000002000,
/// <summary>get system icon index</summary>
SysIconIndex = 0x000004000,
/// <summary>put a link overlay on icon</summary>
LinkOverlay = 0x000008000,
/// <summary>show icon in selected state</summary>
Selected = 0x000010000,
/// <summary>get only specified attributes</summary>
Attr_Specified = 0x000020000,
/// <summary>get large icon</summary>
LargeIcon = 0x000000000,
/// <summary>get small icon</summary>
SmallIcon = 0x000000001,
/// <summary>get open icon</summary>
OpenIcon = 0x000000002,
/// <summary>get shell size icon</summary>
ShellIconSize = 0x000000004,
/// <summary>pszPath is a pidl</summary>
PIDL = 0x000000008,
/// <summary>use passed dwFileAttribute</summary>
UseFileAttributes = 0x000000010,
/// <summary>apply the appropriate overlays</summary>
AddOverlays = 0x000000020,
/// <summary>Get the index of the overlay in the upper 8 bits of the iIcon</summary>
OverlayIndex = 0x000000040,
}
#endregion
/// <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)
{
try
{
SHFILEINFO info = new SHFILEINFO(true);
int cbFileInfo = Marshal.SizeOf(info);
SHGFI flags;
if (bSmall)
flags = SHGFI.Icon | SHGFI.SmallIcon | SHGFI.UseFileAttributes;
else
flags = SHGFI.Icon | SHGFI.LargeIcon | SHGFI.UseFileAttributes;
SHGetFileInfo(strPath, 0, out info, (uint)cbFileInfo, flags);
return Icon.FromHandle(info.hIcon);
}
catch (Exception)
{
// dann ist bei der Extrahierung was schief gegangen und wir geben das Default Icon zurück ..
return Resources.undefined;
}
}
}
#endregion
#region Dateityp Klasse
namespace MimetypeHelper
{
/// <summary>
/// Diese Klasse stellt einen Dateityp dar.
/// Sie besitzt die Eigenschaften der Erweiterung, die 'Content Type' Beschreibung und das zugehörige Icon im Format 32x32 Pixel.
/// (C) Patrick Sperneder 2008
/// </summary>
public class mimetype
{
#region Member
private System.Drawing.Icon ico;
private string mime;
private string extension;
#endregion
#region Konstruktor
public mimetype(System.Drawing.Icon i, string m, string ext)
{
this.ico = i;
this.mime = m;
this.extension = ext;
}
#endregion
#region Props
public System.Drawing.Icon MimeIcon { get { return this.ico; } }
public string MimeTypeString { get { return this.mime; } }
public string Extension { get { return this.extension; } }
#endregion
}
}
#endregion
#region Dateitypen Manager Klasse
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using MimetypeHelper.Properties;
namespace MimetypeHelper
{
/// <summary>
/// Diese Klasse liest aus der Registry alle registrierten Dateitypen die eine Inhaltsbeschreibung haben
/// und ermittelt deren Icons und stellt dies in einer generischen Liste zur Verfügung.
/// TODO : Das Laden der Icons aus der erstellten Textliste (aus Performance Gründen ) , ist qualitativ nicht zufriedenstellend.
/// Derzeit wird bei jeder Instanzierung dieser Klasse, die Dateitypen neu erstellt. (Bug#TODO#1710)
/// (C) Sperneder Patrick 2008.
/// Wenn Ihr die Klasse gut findet, wäre ich für ein paar Punkte dankbar.
/// </summary>
public class MimetypePool
{
#region Member
private const string MIME_RESSOURCE_FILE = "MIME.TYPES";
private List<mimetype> types;
#endregion
#region Konstruktor
public MimetypePool()
{
if (!IsMimeListStored())
{
this.types = GetMimetypes();
// nachdem wir sie jetzt aufwändig erzeugt haben,
// ersparen wir uns das beim nächsten mal und speichern sie lokal ab.
StoreMimeList();
}
else
{
// die icons sehen einfach nicht schön aus !
//this.types = RestoreMimeList();
this.types = GetMimetypes();
}
}
#endregion
#region Speichern Laden der Liste
/// <summary>
/// Überprüft ob die Liste vorhanden ist oder nicht.
/// </summary>
/// <returns></returns>
private bool IsMimeListStored()
{
if (File.Exists(MIME_RESSOURCE_FILE))
return true;
else
return false;
}
/// <summary>
/// Speichert die Mimeliste im Pfad der Anwendung ab, um neues erstellen zu vermeiden.
/// </summary>
private void StoreMimeList()
{
StringBuilder flbuild = new StringBuilder();
foreach (mimetype m in this.types)
{
flbuild.AppendLine(IconToBase64String(m.MimeIcon) + ";" + m.MimeTypeString + ";" + m.Extension);
}
File.WriteAllText(MIME_RESSOURCE_FILE, flbuild.ToString());
}
/// <summary>
/// Erstellt aus der Datei eine neue MIMEListe im Pfad der Anwendung..
/// </summary>
/// <returns></returns>
private List<mimetype> RestoreMimeList()
{
try
{
List<mimetype> m = new List<mimetype>();
string[] lines = File.ReadAllLines(MIME_RESSOURCE_FILE);
foreach (string line in lines)
{
string[] pcs = line.Split(new char[] { ';' });
m.Add(new mimetype(IconFromBase64String(pcs[0]), pcs[1], pcs[2]));
}
return m;
}
catch (Exception)
{
return GetDefaultListOnError();
}
}
/// <summary>
/// Sollte bei der Ermittlung der Dateitypen etwas schief gelaufen sein,
/// so wird diese liste mit den Dateitypen und deren icons zurückgegeben.
/// (Zwar nicht vollständig, aber ausreichend im Fehlerfall)
/// </summary>
/// <returns></returns>
private List<mimetype> GetDefaultListOnError()
{
List<mimetype> m = new List<mimetype>();
m.Add(new mimetype(Resources.doc, "Microsoft Word Document", ".doc"));
m.Add(new mimetype(Resources.jpg, "JPG image", ".jpg"));
m.Add(new mimetype(Resources.zip, "Compressed archive", ".zip"));
// ...
return m;
}
#endregion
#region Erzeugen der Liste
/// <summary>
/// Erstellt die generische Liste mit den Dateitypen auf dem Rechner.
/// </summary>
/// <returns></returns>
private List<mimetype> GetMimetypes()
{
List<mimetype> ret = new List<mimetype>();
try
{
//alle vorhandenen Dateitypen durchsuchen.
foreach (string key in Registry.ClassesRoot.GetSubKeyNames())
{
// nur extensions ...
if (key.StartsWith("."))
{
// nur wenn der Datei auch ein Icon zugeordnet ist.
if (HasAssociatedIcon(GetExtensionDefaultValue(key)))
{
ret.Add(new mimetype(NativeIcon.GetIcon(key, false), GetExtensionDisplayDescription(GetExtensionDefaultValue(key)), key));
}
}
}
return ret;
}
catch (Exception)
{
return GetDefaultListOnError();
}
}
/// <summary>
/// Gibt den Wert des (Default) Wertes eines Registry Schlüssels zurück.
/// </summary>
/// <param name="Extension">Die Extension mit führendem Punkt. z.B .txt ...</param>
/// <returns>Die Beschreb</returns>
private string GetExtensionDefaultValue(string Extension)
{
string def = (string)Registry.ClassesRoot.OpenSubKey(Extension).GetValue("");
if (def == null || def == string.Empty)
return "n";
else
return def;
}
/// <summary>
/// Gibt zurück ob dieser Endung ein Icon zugeordnet ist oder nicht.
/// </summary>
/// <param name="ExtensionDefaultValue">Der Standard Wert der Erweiterung</param>
/// <returns></returns>
private bool HasAssociatedIcon(string ExtensionDefaultValue)
{
try
{
if (ExtensionDefaultValue == "n")
return false;
// Überprüfen ob der Schlüssel überhaupt vorhanden ist ..
if (Registry.ClassesRoot.OpenSubKey(ExtensionDefaultValue) != null)
{
if (Registry.ClassesRoot.OpenSubKey(ExtensionDefaultValue).OpenSubKey("defaulticon") == null)
return false;
else
return true;
}
else
return false;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// Gibt die Klartext-Beschreibung der Extension zurück. für z.b (.txt) Word Textdokument ...)
/// </summary>
/// <param name="ExtensionDefaultValue">Der Defaultwert eines extension Schlüssel</param>
/// <returns></returns>
private string GetExtensionDisplayDescription(string ExtensionDefaultValue)
{
if (ExtensionDefaultValue == "n")
return "n";
string desc = (string)Registry.ClassesRoot.OpenSubKey(ExtensionDefaultValue).GetValue("");
if (desc == null || desc == string.Empty)
{
return "keine Beschreibung";
}
else
{
return desc;
}
}
#endregion
#region Zusatzfunktionen
public Icon IconFromBase64String(string base64)
{
MemoryStream memory = new MemoryStream(Convert.FromBase64String(base64));
Icon result = new Icon(memory, new Size(32, 32));
memory.Close();
return result;
}
public string IconToBase64String(Icon image)
{
MemoryStream memory = new MemoryStream();
image.Save(memory);
string base64 = Convert.ToBase64String(memory.ToArray());
memory.Close();
return base64;
}
#endregion
#region Methoden
/// <summary>
/// Gibt das Objekt das der Dateinamenserweiterung entspricht zurück.
/// </summary>
/// <param name="Extension">Die Dateinamenserweiterung der Datei inklusive führenedem Punkt. z.B .txt</param>
/// <returns>Bei Erfolg das Objekt, andernfalls nix.</returns>
public mimetype GetTypeByExtension(string Extension)
{
Extension = Extension.ToLower();
for (int i = this.types.Count - 1; i >= 0; i--)
{
if (types[i].Extension == Extension)
{
return types[i];
}
}
// wenn wir nichts finden, geben wir einen unbekannten Dateitypen zurück
return new mimetype(Resources.undefined, "unbekannte Datei", "???");
}
/// <summary>
/// Gibt das Symbol für einen Ordner zurück
/// </summary>
/// <returns></returns>
public mimetype GetFolder()
{
return new mimetype(Resources.folder, "Ordner", "keine");
}
/// <summary>
/// Gibt das Symbol für einen Link zurück
/// </summary>
/// <returns></returns>
public mimetype GetLink()
{
return new mimetype(Resources.link , "Link", "Verknüpfung");
}
#endregion
#region Eigenschaften
/// <summary>
/// Gibt alle Dateitypen die eine Beschreibung haben zurück. (andernfalls eine standardliste)
/// </summary>
public List<mimetype> MimeTypes { get { return this.types; } }
#endregion
}
}
#endregion