Windows Portable Devices: получаем список папок и файлов на устройстве
Продолжим нашу работу с подключаемым внешним устройством. В этом материале мы научимся получать список папок и файлов на устройстве с расширениями и выводить их на экран. Для этого мы теперь создадим приложение Windows Forms и добавим в него немного измененные файлы (классы) из прошлого проекта.
PortableDevice:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using PortableDeviceApiLib; using PortableDeviceTypesLib; using _tagpropertykey = PortableDeviceApiLib._tagpropertykey; using IPortableDeviceKeyCollection = PortableDeviceApiLib.IPortableDeviceKeyCollection; using IPortableDeviceValues = PortableDeviceApiLib.IPortableDeviceValues; namespace BrouseFolderMTP { public class PortableDevice { #region Fields private bool _isConnected; private readonly PortableDeviceClass _device; #endregion #region ctor(s) public PortableDevice(string deviceId) { this._device = new PortableDeviceClass(); this.DeviceId = deviceId; } #endregion #region Properties public string DeviceId { get; set; } public string FriendlyName { get { if (!this._isConnected) { throw new InvalidOperationException("Not connected to device."); } // Получение свойств устройства IPortableDeviceContent content; IPortableDeviceProperties properties; this._device.Content(out content); content.Properties(out properties); // Получение значений для свойств IPortableDeviceValues propertyValues; properties.GetValues("DEVICE", null, out propertyValues); // Определение свойства для извлечения var property = new _tagpropertykey(); property.fmtid = new Guid(0x26D4979A, 0xE643, 0x4626, 0x9E, 0x2B, 0x73, 0x6D, 0xC0, 0xC9, 0x2F, 0xDC); property.pid = 12; // Получить понятное имя string propertyValue; propertyValues.GetStringValue(ref property, out propertyValue); return propertyValue; } } #endregion #region Methods public void Connect() { if (this._isConnected) { return; } var clientInfo = (IPortableDeviceValues)new PortableDeviceValuesClass(); this._device.Open(this.DeviceId, clientInfo); this._isConnected = true; } public void Disconnect() { if (!this._isConnected) { return; } this._device.Close(); this._isConnected = false; } public PortableDeviceFolder GetContents() { var root = new PortableDeviceFolder("DEVICE", "DEVICE"); IPortableDeviceContent content; this._device.Content(out content); EnumerateContents(ref content, root); return root; } private static void EnumerateContents(ref IPortableDeviceContent content, PortableDeviceFolder parent) { // Получение свойств объекта IPortableDeviceProperties properties; content.Properties(out properties); // Перечисление элементов, содержащихся в текущем объекте IEnumPortableDeviceObjectIDs objectIds; content.EnumObjects(0, parent.Id, null, out objectIds); uint fetched = 0; do { string objectId; objectIds.Next(1, out objectId, ref fetched); if (fetched > 0) { var currentObject = WrapObject(properties, objectId); parent.Files.Add(currentObject); if (currentObject is PortableDeviceFolder) { EnumerateContents(ref content, (PortableDeviceFolder)currentObject); } } } while (fetched > 0); } private static PortableDeviceObject WrapObject(IPortableDeviceProperties properties, string objectId) { IPortableDeviceKeyCollection keys; properties.GetSupportedProperties(objectId, out keys); IPortableDeviceValues values; properties.GetValues(objectId, keys, out values); // Получить имя объекта string name; var property = new _tagpropertykey(); property.fmtid = new Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C); property.pid = 4; values.GetStringValue(property, out name); // Получить тип объекта Guid contentType; property = new _tagpropertykey(); property.fmtid = new Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C); property.pid = 7; values.GetGuidValue(property, out contentType); var folderType = new Guid(0x27E2E392, 0xA111, 0x48E0, 0xAB, 0x0C, 0xE1, 0x77, 0x05, 0xA0, 0x5F, 0x85); var functionalType = new Guid(0x99ED0160, 0x17FF, 0x4C44, 0x9D, 0x98, 0x1D, 0x7A, 0x6F, 0x94, 0x19, 0x21); if (contentType == folderType || contentType == functionalType) { return new PortableDeviceFolder(objectId, name); } property.pid = 12;//WPD_OBJECT_ORIGINAL_FILE_NAME values.GetStringValue(property, out name); return new PortableDeviceFile(objectId, name); } #endregion } }PortableDeviceCollection
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections.ObjectModel; using PortableDeviceApiLib; namespace BrouseFolderMTP { public class PortableDeviceCollection : Collection<PortableDevice> { private readonly PortableDeviceManager _deviceManager; public PortableDeviceCollection() { this._deviceManager = new PortableDeviceManager(); } public void Refresh() { this._deviceManager.RefreshDeviceList(); // Определение количества подключенных устройств WPD var deviceIds = new string[1]; uint count = 1; this._deviceManager.GetDevices(ref deviceIds[0], ref count); // Извлечение идентификатора устройства для каждого подключенного устройства deviceIds = new string[count]; this._deviceManager.GetDevices(ref deviceIds[0], ref count); foreach (var deviceId in deviceIds) { Add(new PortableDevice(deviceId)); } } } }PortableDeviceFile:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace BrouseFolderMTP { public class PortableDeviceFile : PortableDeviceObject { public PortableDeviceFile(string id, string name) : base(id, name) { } } }PortableDeviceFolder:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace BrouseFolderMTP { public class PortableDeviceFolder : PortableDeviceObject { public PortableDeviceFolder(string id, string name) : base(id, name) { this.Files = new List<PortableDeviceObject>(); } public IList<PortableDeviceObject> Files { get; set; } } }PortableDeviceObject:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace BrouseFolderMTP { public class PortableDeviceObject { protected PortableDeviceObject(string id, string name) { this.Id = id; this.Name = name; } public string Id { get; private set; } public string Name { get; private set; } } }Ну и наша форма. На ней добавьте textbox и кнопку.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace BrouseFolderMTP { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { var collection = new PortableDeviceCollection(); collection.Refresh(); foreach (var device in collection) { device.Connect(); // Console.WriteLine(device.FriendlyName); textBox1.Text += device.DeviceId + Environment.NewLine; var folder = device.GetContents(); foreach (var item in folder.Files) { DisplayObject(item); } device.Disconnect(); } } public void DisplayObject(PortableDeviceObject portableDeviceObject) { Console.WriteLine(portableDeviceObject.Name); if (portableDeviceObject is PortableDeviceFolder) { DisplayFolderContents((PortableDeviceFolder)portableDeviceObject); } } public void DisplayFolderContents(PortableDeviceFolder folder) { var last = (PortableDeviceObject) null; try { last = folder.Files.Last(); } catch (InvalidOperationException iee) { } foreach (var item in folder.Files) { textBox1.Text += item.Name; if (item is PortableDeviceFolder) { textBox1.Text += item.Name + "/"; DisplayFolderContents((PortableDeviceFolder)item); } else { textBox1.Text += Environment.NewLine; } } } } }После нажатия кнопки мы получим вот такой результат:
все папки и файлы устройства в текстбоксе. в следующих статьях мы будем учиться выбирать и копировать файлы.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.
Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.