2016-09-14 5 views
0

Ich versuche, die Symbole von Dateien und Ordnern im Ordner system32 zu erhalten, aber "System.ArgumentException" in System.Drawing.dll auf verschiedenen Dateien zu erhalten.Holen Sie sich alle Symbole aus einem Ordner system32. System.ArgumentException

erstelle ich eine Klasse:

[StructLayout(LayoutKind.Sequential)] 
public struct SHFILEINFO 
{ 
    public IntPtr hIcon; 
    public IntPtr iIcon; 
    public uint dwAttributes; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
    public string szDisplayName; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] 
    public string szTypeName; 
} 

class Win32 
{ 
    public const uint SHGFI_ICON = 0x100; 
    //public const uint SHGFI_LARGEICON = 0x0; // 'Large icon 
    public const uint SHGFI_SMALLICON = 0x1; // 'Small icon 

    [DllImport("shell32.dll")] 
    public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags); 
    [DllImport("gdi32.dll", SetLastError = true)] 
    public static extern bool DeleteObject(IntPtr hObject); 
} 

Und erhalten icon:

private Icon GetIcon(string filePatch) 
{ 
    Icon icon; 
    SHFILEINFO shinfo = new SHFILEINFO(); 

    IntPtr hIconSmall = Win32.SHGetFileInfo(filePatch, 0, ref shinfo, /*(uint)Marshal.SizeOf(shinfo)*/ 80, Win32.SHGFI_ICON | Win32.SHGFI_SMALLICON); 

    if (hIconSmall == IntPtr.Zero) 
    { 
     icon = iconUnknown; 
    } 
    else 
    { 
     icon = Icon.FromHandle(shinfo.hIcon); 
     //"System.ArgumentException" in System.Drawing.dll 
    } 

    Win32.DeleteObject(shinfo.hIcon); 

    return (icon); 
} 

Ich weiß, ich brauche DeleteObject, aber dies scheint nicht aufzutreten. Was mache ich falsch?

PS: Und in Eigenschaften Projekt prüfe ich Any CPU

+0

Ich sehe dass Sie überprüfen, ob die Datei jetzt ist. Ich habe einen Dateiexplorer über Socket gemacht. Ich weiß, dass ich damit ein Problem hatte, dass die Erweiterung nicht bekannt war. Ich nicht die Lösung, aber ich kann Ihnen den Code, der für mich funktioniert –

+0

@TimonPost Fehler auf verschiedenen Dateien, scheint nicht zu arbeiten DeleteObject. Wenn ich das Icon mit nur einer einzigen Datei bekomme, die gerade den Fehler verursacht hat, funktioniert alles. Und ich denke, es wäre nützlich, Ihren Code zu sehen. – DartAlex

Antwort

0
// I got a form with a virtual listview and a icon list 
// there may be some mistakes I had to edit it together 

public class DirContent // directory content like one file or one folder 
{ 
    public string Name; 
    public string Path; 
    public string Modyfied; 
    public string Extention; 
    public string Size; 
} 

public class DirectoryContent //this contains a list with mulyble files and folders and the previous folder and selected folder 
{ 
    public List<DirContent> dirContent = new List<DirContent>(); 
    public string previousDirectory; 
    public string selectedDirectory; 
} 

public partial class Form1 : Form 
{ 
    static Dictionary<string, int> IconDictornary = new Dictionary<string, int>(); //this is a Dictionary to keep track of the loaded files; 
    static DirContent directoryContent = // file to load the icon for 

    public Form1() 
    { 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     Icon icon = Icon.ExtractAssociatedIcon(@"path/to/file/file.png"); 
     icons.Images.Add("empty", icon); // add empty file icon to imageList of form; (index 1) (index 0 = folder icon) i set that in imagelist propperites 
    } 

    public void getFileIcon() // I had a list view and had to cut out some things to show only the usefull stuf 
    { 
     // I had a virtual list view it much better for rendering. The system32 folder contains allot of files. so this is a handy thing 
     int index; 
     if (itemIndex == 0) // i checked if the index of te listview item that has to render == 0; 
     { 
      ListViewItem parrentItem = new ListViewItem("", 0); 
      parrentItem.SubItems.Add(".."); 
      parrentItem.SubItems.Add(""); 
      parrentItem.SubItems.Add(""); 
      listview[itemIndex].Item = parrentItem; 

      // set on index 0 of list view a .. for previous folder 
     } 
     else 
     { 
      if (IconDictornary.ContainsKey(directoryContent[ItemIndex].Extention)) // If the icon already loaded in to IconDictornary get the key that wil be presented by the index of the icon in the icon list; 
      { 
       index = IconDictornary[directoryContent[ItemIndex].Extention]; 
      } 
      else 
      { 
       index = GetIconIndexFromIcon(directoryContent[ItemIndex].Extention); // get File/folder icon 
      } 

      ListViewItem lvi = new ListViewItem("", index); // image index of icon in icon list 
      lvi.SubItems.Add(directoryContent[ItemIndex].Name); 
      lvi.SubItems.Add(directoryContent[ItemIndex].Modyfied); 
      lvi.SubItems.Add(directoryContent[ItemIndex].Size); 
      listview[itemIndex].Item = lvi; 

      // set details for sub items and show it to list view 
     } 
    } 

    private int GetIconIndexGetIcon(string extention) 
    { 
     Icon icon; 
     int index = 0; 
     try 
     { 
      if (extention == ".folder") // i check if the file extention = .folder if yes index = 0; iconlist[0] == folder. as I sayd above 
      { 
       index = 0; 
      } 
      else 
      { 
       icon = Icons.IconFromExtension(extention, Icons.SystemIconSize.Large); // get icon by extention 
       icons.Images.Add(extention, icon); // add to icon list with key, icon 
       index = icons.Images.IndexOfKey(extention); 
       IconDictornary.Add(extention, index); // set loaded file to IconDictornary by extention and index from the icon list 
      } 
     } 
     catch 
     { 
      index = 1; 
     } 
     return index; // return index where to find icon 
    } 

} 

Die Methode, die ich verwendet Symbole zu erhalten:

public static Icon IconFromExtension(string extension, 
              SystemIconSize size)  
    { 
     try 
     { 
      // Add the '.' to the extension if needed 
      if (extension[0] != '.') extension = '.' + extension; 

      //opens the registry for the wanted key. 
      RegistryKey Root = Registry.ClassesRoot; 
      RegistryKey ExtensionKey = Root.OpenSubKey(extension); 
      ExtensionKey.GetValueNames(); 
      RegistryKey ApplicationKey = 
       Root.OpenSubKey(ExtensionKey.GetValue("").ToString()); 

      //gets the name of the file that have the icon. 
      string IconLocation = 
       ApplicationKey.OpenSubKey("DefaultIcon").GetValue("").ToString(); 
      string[] IconPath = IconLocation.Split(','); 

      if (IconPath[1] == null) IconPath[1] = "0"; 
      IntPtr[] Large = new IntPtr[1], Small = new IntPtr[1]; 

      //extracts the icon from the file. 
      ExtractIconEx(IconPath[0], 
       Convert.ToInt16(IconPath[1]), Large, Small, 1); 
      return size == SystemIconSize.Large ? 
       Icon.FromHandle(Large[0]) : Icon.FromHandle(Small[0]); 
     } 
     catch (Exception ex) 
     { 
      return null; 
     } 
    } 

DLL müssen einbezogen werden:

 struct SHFILEINFO 
    { 
     public IntPtr hIcon; 

     public IntPtr iIcon; 

     public uint dwAttributes; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
     public string szDisplayName; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] 
     public string szTypeName; 
    }; 

    [Flags] 
    enum FileInfoFlags : int 
    { 
     SHGFI_ICON = 0x000000100, 
     SHGFI_USEFILEATTRIBUTES = 0x000000010 
    } 

    [DllImport("Shell32", CharSet = CharSet.Auto)] 
    extern static int ExtractIconEx(
     [MarshalAs(UnmanagedType.LPTStr)] 
     string lpszFile, 
     int nIconIndex, 
     IntPtr[] phIconLarge, 
     IntPtr[] phIconSmall, 
     int nIcons); 

    [DllImport("Shell32", CharSet = CharSet.Auto)] 
    extern static IntPtr SHGetFileInfo(
     string pszPath, 
     int dwFileAttributes, 
     out SHFILEINFO psfi, 
     int cbFileInfo, 
     FileInfoFlags uFlags); 
+0

Vielen Dank für Hilfe, ich brauchte Zeit, um die Lösung zu testen, anzuwenden und zusammenzufassen, ich werde unbedingt über die Ergebnisse berichten und die Antwort zu schätzen wissen. – DartAlex

+0

Nehmen Sie sich Zeit und wenn Sie Fragen haben, kommentieren Sie einfach. Es ist alles zusammen bearbeitet, aber ich hoffe, Sie werden eine Lösung finden –

Verwandte Themen