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 - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегистатьи IT, си шарп, внешние устройства, WPD




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




Только крести
Гистограмма на Java
Сменил ли C# C++?