2016-09-14 2 views
0

Я пытаюсь получить значки файлов и папок в папке system32, но получаю "System.ArgumentException" in System.Drawing.dll в разных файлах.Получить все значки из папки system32. System.ArgumentException

создать класс:

[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); 
} 

и получить значок:

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); 
} 

Я знаю, что нужно DeleteObject, но это, кажется, не происходит. Что я делаю не так?

PS: А в проекте свойств проверить Any CPU

+0

Я вижу что вы проверяете, есть ли файл сейчас. Я сделал проводник файлов через сокет. Я знаю, что у меня была проблема с этим, что расширение не было известно. У меня нет решения, но я могу дать вам код, который сработал для меня –

+0

@TimonPost Ошибка в разных файлах, похоже, не работает DeleteObject. Если я получаю значок только с одним файлом, который только что вызвал ошибку, все работает. И я думаю, было бы полезно увидеть ваш код. – DartAlex

ответ

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 
    } 

} 

метод, который я использовал, чтобы получить значки:

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, чтобы быть включены:

 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

Спасибо за помощь, мне нужно время, чтобы проверить, применить и обобщить решение, я обязательно расскажу о результатах и ​​ценю ответ. – DartAlex

+0

Не торопитесь, и если у вас есть вопросы, просто комментируйте. Все это редактируется вместе, но я надеюсь, что вы найдете решение –

Смежные вопросы