BrowseForFolder и MTP-устройства


Начал работу над одним новым интересным проектом – созданием программы на заказ для приема фотографий в печать для одной фотостудии. Программа как программа – ничего не предвещало сложностей; если вкратце, то необходимо просто написать продвинутый копировщик файлов с настройками.

И вот, первая неожиданность заключалась в том, что .NET FolderBrowserDialog не собирался работать с портативными устройствами (MTP). Флешки и некоторые телефоны нормально определялись, но вот мой ZTE BLADE A5 PRO не работает с этим компонентом. Точнее, показывать он все нормально показывал, но вот выбора папки не происходило- не работает кнопка OK. А нам надо именно выбрать папку и потом уже в ней работать с изображениями.



Ну что ж, тогда попробуем использовать shell32.dll. Эта библиотека содержит BrowseForFolder, который способен обрабатывать Portable Devices. Чтобы использовать его, просто добавьте ссылку на COM-компонент «Microsoft Shell Controls and Automation» и включите пространство имен Shell32:

using Shell32;
Теперь вы можете вызвать BrowseForFolder с помощью этого фрагмента:

Shell shell = new Shell();
Folder folder = shell.BrowseForFolder((int)0, "Выбор папки", 0, 0);
if (folder != null) { 
//Что-то делаем
}
Обратите внимание, что папка представляет собой COM-объект, поэтому вы не можете использовать его как .Net Directory. Но вы можете получить путь из него, выбрав его в FolderItem:

FolderItem fi = (folder as Folder3).Self;
string path2 = fi.Path;
MessageBox.Show(path2); 
Например, для моего ZTE, Данный путь выглядит так:

::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_19d2&pid_0307#900501755192#{6ac27878-a6fa-4155-ba85-f98f491d4f33}
Интересно, что выбор папки на жестком диске приводит к нормальному пути, например: «C:\book». В первом случае я не нашел возможности использовать этот «Путь» для получения .Net Directory. Вот почему мне пришлось использовать Shell32.Folder для копирования / перемещения.

Теперь вы можете перебирать файлы с помощью folder.Items (), но снова объекты FolderItem в этом списке являются COM-объектами, и я не нашел способа конвертировать их в .Net-файл.

Я использовал другой подход: COM-Folder-Object имеет две удобные функции: CopyHere и MoveHere.

Итак, все, что нам нужно сделать, это вызвать CopyHere на COM-папку с помощью FolderItems из исходной папки. Вот фрагмент для этого:

public static void CopyFiles(Folder srcFolder, Folder dstFolder)
        {
            foreach (FolderItem currFolderItem in srcFolder.Items())
            {
                dstFolder.CopyHere(currFolderItem, 0);
            }
        } 
Если у вас есть обычный FolderPath и нужно, чтобы он был преобразован в COM-Folder-Object, используйте этот фрагмент:

public static Folder Path2Folder(string path)
{
    // Создание папки при необходимости
    Directory.CreateDirectory(path);
    // Создание объекта ShellObject
    Shell shell = new ShellClass();
    // Преобразование в папку оболочки  
return shell.NameSpace(path);
}
Вот и все, теперь все файлы копируются (или перемещаются) из любого телефона или другого устройства на компьютер в выбранный каталог. И после этого вы можете использовать класс .Net DirectoryInfo для доступа к файлам с .Net.

Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегистатьи IT, си шарп, .net




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




Урок 12. Оператор switch в Java
Статичная страница на HTML с обработкой AJAX, PHP
Перебор всех дней в году на PHP