Меню сайта
Категории раздела
Разное
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Вторник, 14.05.2024, 20:14
Приветствую Вас Гость

Каталог статей

Главная » Статьи » Статьи » Разное

c# - Использование Shell (для получения списка файлов/папок)

c# - Использование Shell (для получения списка файлов/папок)



Использование Shell?! Прекрасный вопрос. Рекомендуется использовать системные функции. Это немного сложнее, потому что придется описывать необходимые системные интерфейсы, функции и структуры, которые в .NET не описаны. Но зато результат будет мощным и универсальным. В системе много функций работы с файловой системой, но какие из них нам понадобятся? Я помогу вам разобраться.

Если тебе нужно просто получить список файлов в директории, то лучше воспользоваться классом Directory. Совместно с File он предоставит тебе базовые возможности для работы с файловой системой. Но этого не всегда достаточно, и если нужно что-то большее - хорошие системные иконки, снимки файлов и т.д., то придётся опускаться на системный уровень, о чем мы и поговорим в этой статье.

Создайте новый проект и поместите на форму компонент ListView. В него мы будет загружать имена файлов и папок, которые найдем на рабочем столе. Теперь мы должны описать два интерфейса, которые нам понадобяться: IShellFolder и IEnumIDList. Создайте новый файл для интерфейса IShellFolder. Чтобы сделать это щелкните правой кнопкой по имени проекта в окне Solution Explorer и выберите меню New Item из меню Add. Перед вами откроется окно Add New:

Shell c#

Выберите иконку Interface в списке Templates и введите имя нового интерфейса IShellFolder в поле Name:

Shell VisualStudio

Сохраните новый файл под именем IShellFolder. Содержимое файла должно быть таким (можете скопировать его из браузера):

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Runtime.InteropServices;  
  6.    
  7. namespace ShellExample  
  8. {  
  9.     [ComImport]  
  10.     [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]  
  11.     [Guid("000214E6-0000-0000-C000-000000000046")]  
  12.     public interface IShellFolder  
  13.     {  
  14.         [PreserveSig]  
  15.         Int32 ParseDisplayName(IntPtr hwnd,  
  16.             IntPtr pbc,  
  17.             [MarshalAs(UnmanagedType.LPWStr)]  
  18.             string pszDisplayName,  
  19.             ref uint pchEaten,  
  20.             out IntPtr ppidl,  
  21.             ref ShellAPI.SFGAO pdwAttributes);  
  22.   
  23.    
  24.         [PreserveSig]  
  25.         Int32 EnumObjects(IntPtr hwnd,  
  26.             ShellAPI.SHCONTF grfFlags,  
  27.             out IntPtr enumIDList);  
  28.   
  29.    
  30.         [PreserveSig]  
  31.         Int32 BindToObject(IntPtr pidl,  
  32.             IntPtr pbc,  
  33.             ref Guid riid,  
  34.             out IntPtr ppv);  
  35.   
  36.   
  37.         [PreserveSig]  
  38.         Int32 BindToStorage(IntPtr pidl,  
  39.             IntPtr pbc,  
  40.             ref Guid riid,  
  41.             out IntPtr ppv);  
  42.   
  43.   
  44.         [PreserveSig]  
  45.         Int32 CompareIDs(IntPtr lParam,  
  46.             IntPtr pidl1,  
  47.             IntPtr pidl2);  
  48.   
  49.    
  50.         [PreserveSig]  
  51.         Int32 CreateViewObject(IntPtr hwndOwner,  
  52.             Guid riid,  
  53.             out IntPtr ppv);  
  54.   
  55.    
  56.         [PreserveSig]  
  57.         Int32 GetAttributesOf(uint cidl,  
  58.             [MarshalAs(UnmanagedType.LPArray)]  
  59.             IntPtr[] apidl,  
  60.             ref ShellAPI.SFGAO rgfInOut);  
  61.   
  62.    
  63.         [PreserveSig]  
  64.         Int32 GetUIObjectOf(IntPtr hwndOwner,  
  65.             uint cidl,  
  66.             [MarshalAs(UnmanagedType.LPArray)]  
  67.             IntPtr[] apidl,  
  68.             ref Guid riid,  
  69.             IntPtr rgfReserved,  
  70.             out IntPtr ppv);  
  71.   
  72.    
  73.         [PreserveSig()]  
  74.         Int32 GetDisplayNameOf(IntPtr pidl,  
  75.             ShellAPI.SHGNO uFlags,  
  76.             IntPtr lpName);  
  77.   
  78.    
  79.         [PreserveSig]  
  80.         Int32 SetNameOf(IntPtr hwnd,  
  81.             IntPtr pidl,  
  82.             [MarshalAs(UnmanagedType.LPWStr)]  
  83.             string pszName,  
  84.             ShellAPI.SHGNO uFlags,  
  85.             out IntPtr ppidlOut);  
  86.     }  
  87. }  

Теперь создайте еще один файл интерфейса с именем IEnumIDList. Его код должен быть таким:

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Runtime.InteropServices;  
  6.   
  7. namespace ShellExample  
  8. {  
  9.     [ComImportAttribute()]  
  10.     [InterfaceTypeAttribute(ComInterfaceType  
  11.         .InterfaceIsIUnknown)]  
  12.     [Guid("000214F2-0000-0000-C000-000000000046")]  
  13.     public interface IEnumIDList  
  14.     {  
  15.         [PreserveSig()]  
  16.         Int32 Next(int celt,  
  17.             out IntPtr rgelt,  
  18.             out int pceltFetched);  
  19.   
  20.         [PreserveSig()]  
  21.         Int32 Skip(int celt);  
  22.   
  23.         [PreserveSig()]  
  24.         Int32 Reset();  
  25.   
  26.         [PreserveSig()]  
  27.         Int32 Clone(out IEnumIDList ppenum);  
  28.     }  
  29. }  

Теперь у нас есть необходимые интерфейсы, но нужны еще функции и структуры. Давайте создадим файл ShellAPI.cs в котором и опишем необходимые функции. Чтобы сделать это, щелкните правой кнопкой мыши по имени проекта в окне Solution Explorer, как мы это делали для создания интерфейсов. Выберите New Item из меню Add. Снова появиться окно Add New Item. Теперь выберите иконку Class в списке Templates и напишите имя класса ShellAPI в поле Name. Код нового файла должен быть таким:

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Runtime.InteropServices;  
  6.   
  7.   
  8. namespace ShellExample  
  9. {  
  10.     public class ShellAPI  
  11.     {  
  12.         public const int S_OK = 0;  
  13.         public const int S_FALSE = 1;  
  14.         public const int MAX_PATH = 260;  
  15.   
  16.         public static int cbFileInfo =   
  17.             Marshal.SizeOf(typeof(SHFILEINFO));  
  18.   
  19.   
  20.         [Flags]  
  21.         public enum SHCONTF  
  22.         {  
  23.             FOLDERS = 0x0020,  
  24.             NONFOLDERS = 0x0040,  
  25.             INCLUDEHIDDEN = 0x0080,  
  26.             INIT_ON_FIRST_NEXT = 0x0100,  
  27.             NETPRINTERSRCH = 0x0200,  
  28.             SHAREABLE = 0x0400,  
  29.             STORAGE = 0x0800,  
  30.         }  
  31.   
  32.   
  33.         [Flags]  
  34.         public enum SHGNO  
  35.         {  
  36.             NORMAL = 0x0000,  
  37.             INFOLDER = 0x0001,  
  38.             FOREDITING = 0x1000,  
  39.             FORADDRESSBAR = 0x4000,  
  40.             FORPARSING = 0x8000  
  41.         }  
  42.   
  43.    
  44.         [Flags]  
  45.         public enum SHGFI : uint  
  46.         {  
  47.             ADDOVERLAYS = 0x20,  
  48.             ATTR_SPECIFIED = 0x20000,  
  49.             ATTRIBUTES = 0x800,  
  50.             DISPLAYNAME = 0x200,  
  51.             EXETYPE = 0x2000,  
  52.             ICON = 0x100,  
  53.             ICONLOCATION = 0x1000,  
  54.             LARGEICON = 0,  
  55.             LINKOVERLAY = 0x8000,  
  56.             OPENICON = 2,  
  57.             OVERLAYINDEX = 0x40,  
  58.             PIDL = 8,  
  59.             SELECTED = 0x10000,  
  60.             SHELLICONSIZE = 4,  
  61.             SMALLICON = 1,  
  62.             SYSICONINDEX = 0x4000,  
  63.             TYPENAME = 0x400,  
  64.             USEFILEATTRIBUTES = 0x10  
  65.         }  
  66.   
  67.   
  68.         [Flags]  
  69.         public enum SFGAO : uint  
  70.         {  
  71.             BROWSABLE = 0x8000000,  
  72.             CANCOPY = 1,  
  73.             CANDELETE = 0x20,  
  74.             CANLINK = 4,  
  75.             CANMONIKER = 0x400000,  
  76.             CANMOVE = 2,  
  77.             CANRENAME = 0x10,  
  78.             CAPABILITYMASK = 0x177,  
  79.             COMPRESSED = 0x4000000,  
  80.             CONTENTSMASK = 0x80000000,  
  81.             DISPLAYATTRMASK = 0xfc000,  
  82.             DROPTARGET = 0x100,  
  83.             ENCRYPTED = 0x2000,  
  84.             FILESYSANCESTOR = 0x10000000,  
  85.             FILESYSTEM = 0x40000000,  
  86.             FOLDER = 0x20000000,  
  87.             GHOSTED = 0x8000,  
  88.             HASPROPSHEET = 0x40,  
  89.             HASSTORAGE = 0x400000,  
  90.             HASSUBFOLDER = 0x80000000,  
  91.             HIDDEN = 0x80000,  
  92.             ISSLOW = 0x4000,  
  93.             LINK = 0x10000,  
  94.             NEWCONTENT = 0x200000,  
  95.             NONENUMERATED = 0x100000,  
  96.             READONLY = 0x40000,  
  97.             REMOVABLE = 0x2000000,  
  98.             SHARE = 0x20000,  
  99.             STORAGE = 8,  
  100.             STORAGEANCESTOR = 0x800000,  
  101.             STORAGECAPMASK = 0x70c50008,  
  102.             STREAM = 0x400000,  
  103.             VALIDATE = 0x1000000  
  104.         }  
  105.   
  106.   
  107.         [Flags]  
  108.         public enum FILE_ATTRIBUTE  
  109.         {  
  110.             READONLY = 0x00000001,  
  111.             HIDDEN = 0x00000002,  
  112.             SYSTEM = 0x00000004,  
  113.             DIRECTORY = 0x00000010,  
  114.             ARCHIVE = 0x00000020,  
  115.             DEVICE = 0x00000040,  
  116.             NORMAL = 0x00000080,  
  117.             TEMPORARY = 0x00000100,  
  118.             SPARSE_FILE = 0x00000200,  
  119.             REPARSE_POINT = 0x00000400,  
  120.             COMPRESSED = 0x00000800,  
  121.             OFFLINE = 0x00001000,  
  122.             NOT_CONTENT_INDEXED = 0x00002000,  
  123.             ENCRYPTED = 0x00004000  
  124.         }  
  125.   
  126.   
  127.         [StructLayout(LayoutKind.Sequential,  
  128.             CharSet = CharSet.Auto)]  
  129.         public struct SHFILEINFO  
  130.         {  
  131.             public IntPtr hIcon;  
  132.             public int iIcon;  
  133.             public SFGAO dwAttributes;  
  134.   
  135.             [MarshalAs(UnmanagedType.ByValTStr,  
  136.                SizeConst = MAX_PATH)]  
  137.             public string szDisplayName;  
  138.             [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]  
  139.             public string szTypeName;  
  140.         }  
  141.   
  142.   
  143.         [DllImport("shell32.dll")]  
  144.         public static extern Int32 SHGetDesktopFolder(  
  145.             out IntPtr ppshf);  
  146.   
  147.         [DllImport("shell32", EntryPoint = "SHGetFileInfo",  
  148.             ExactSpelling = false, CharSet = CharSet.Auto,  
  149.             SetLastError = true)]  
  150.   
  151.         public static extern IntPtr SHGetFileInfo(  
  152.             string pszPath,  
  153.             FILE_ATTRIBUTE dwFileAttributes,  
  154.             ref SHFILEINFO sfi,  
  155.             int cbFileInfo,  
  156.             SHGFI uFlags);  
  157.   
  158.    
  159.   
  160.         [DllImport("shell32", EntryPoint = "SHGetFileInfo",  
  161.             ExactSpelling = false, CharSet = CharSet.Auto,  
  162.             SetLastError = true)]  
  163.   
  164.         public static extern IntPtr SHGetFileInfo(  
  165.             IntPtr ppidl,  
  166.             FILE_ATTRIBUTE dwFileAttributes,  
  167.             ref SHFILEINFO sfi,  
  168.             int cbFileInfo,  
  169.             SHGFI uFlags);  
  170.     }  
  171. }  

Теперь у нас есть все необходимое и можно переходить к рассмотрению функций получения списка файлов. Комментарии помогут вам разобраться с кодом:

  1. // получить папку рабочего стола  
  2. IntPtr shellFolderPtr;  
  3.   
  4. ShellAPI.SHGetDesktopFolder(out shellFolderPtr);  
  5.   
  6.   
  7. IShellFolder shellFolder = (IShellFolder)Marshal  
  8.     .GetTypedObjectForIUnknown(shellFolderPtr,  
  9.         typeof(IShellFolder));  
  10.   
  11.    
  12. // очистить содержимое listView1  
  13. listView1.Items.Clear();  
  14.   
  15.   
  16. // мы будем перечислять папки и файлы  
  17. ShellAPI.SHCONTF fileFlag =  
  18.     ShellAPI.SHCONTF.NONFOLDERS | ShellAPI.SHCONTF.FOLDERS;  
  19.   
  20. // если результат равен S_OK, то все прекрасно  
  21. IntPtr fileEnumPtr = IntPtr.Zero;  
  22.   
  23. if(shellFolder.EnumObjects(IntPtr.Zero,  
  24.                   fileFlag, out fileEnumPtr)  
  25.     == ShellAPI.S_OK)  
  26. {  
  27.     IEnumIDList fileEnum =   
  28.         (IEnumIDList)Marshal.GetTypedObjectForIUnknown(  
  29.             fileEnumPtr, typeof(IEnumIDList));  
  30.   
  31.     IntPtr gelt;  
  32.     int celtFetched;  
  33.   
  34.   
  35.     //перечисляем найденные объекты  
  36.     while(fileEnum.Next(1, out gelt, out celtFetched)  
  37.        == ShellAPI.S_OK && celtFetched == 1)  
  38.     {  
  39.         //получить имя текущего объекта  
  40.         ShellAPI.SHFILEINFO info =  
  41.              new ShellAPI.SHFILEINFO();  
  42.   
  43.         ShellAPI.SHGetFileInfo(gelt, 0, ref info,  
  44.              ShellAPI.cbFileInfo,  
  45.   
  46.         ShellAPI.SHGFI.DISPLAYNAME | ShellAPI.SHGFI.TYPENAME);  
  47.   
  48.    
  49.         //добавить его в список  
  50.         listView1.Items.Add(info.szDisplayName);  
  51.     }  
  52. }  

Вот результат:

Использование Shell в c#

Категория: Разное | Добавил: admin (20.12.2011)
Просмотров: 1238
Форма входа
Поиск
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz