Поиск пути к карте памяти на WM6 - PullRequest
6 голосов
/ 02 сентября 2008

Существует ли простой способ найти путь к карте памяти на устройстве Windows Mobile когда есть карта памяти и соединение Bluetooth по FTP?

Ответы [ 8 ]

10 голосов
/ 07 сентября 2008

Точка монтирования обычно называется «\ Storage Card», но может быть локализована на другие языки или изменена OEM-изготовителями (некоторые устройства используют «\ SD Card» или другие точки монтирования, а некоторые устройства поддерживают монтирование нескольких носителей). Лучший способ перечислить доступные карты - это использовать FindFirstFlashCard и FindNextFlashCard.

Обе функции заполняют структуру WIN32_FIND_DATA. Наиболее важным полем является cFileName, которое будет содержать путь к точке монтирования карты (например, "\ Storage Card").

Обратите внимание, что внутренняя память устройства также будет перечисляться этими функциями. Если вы заботитесь только о внешних томах, игнорируйте случай, когда cFileName является пустой строкой ("").

Для использования этих функций требуется #include и ссылка с note_prj.lib. Оба включены в Windows Mobile SDK для WM 2000 и более поздних версий.

5 голосов
/ 30 марта 2009

Я обнаружил, что использование API-интерфейсов FindFirstFlashCard / FindNextFlashCard более надежно, чем перечисление каталогов и проверка временного флага (который возвращает, например, общие папки Bluetooth).

В следующем примере приложения показано, как их использовать, и необходимые операторы P / Invoke.

using System;
using System.Runtime.InteropServices;

namespace RemovableStorageTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string removableDirectory = GetRemovableStorageDirectory();
            if (removableDirectory != null)
            {
                Console.WriteLine(removableDirectory);
            }
            else
            {
                Console.WriteLine("No removable drive found");
            }
        }

        public static string GetRemovableStorageDirectory()
        {
            string removableStorageDirectory = null;

            WIN32_FIND_DATA findData = new WIN32_FIND_DATA();
            IntPtr handle = IntPtr.Zero;

            handle = FindFirstFlashCard(ref findData);

            if (handle != INVALID_HANDLE_VALUE)
            {
                do
                {
                    if (!string.IsNullOrEmpty(findData.cFileName))
                    {
                        removableStorageDirectory = findData.cFileName;
                        break;
                    }
                }
                while (FindNextFlashCard(handle, ref findData));
                FindClose(handle);
            }

            return removableStorageDirectory;
        }

        public static readonly IntPtr INVALID_HANDLE_VALUE = (IntPtr)(-1);

        // The CharSet must match the CharSet of the corresponding PInvoke signature
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct WIN32_FIND_DATA
        {
            public int dwFileAttributes;
            public FILETIME ftCreationTime;
            public FILETIME ftLastAccessTime;
            public FILETIME ftLastWriteTime;
            public int nFileSizeHigh;
            public int nFileSizeLow;
            public int dwOID;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string cFileName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
            public string cAlternateFileName;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct FILETIME
        {
            public int dwLowDateTime;
            public int dwHighDateTime;
        };

        [DllImport("note_prj", EntryPoint = "FindFirstFlashCard")]
        public extern static IntPtr FindFirstFlashCard(ref WIN32_FIND_DATA findData);

        [DllImport("note_prj", EntryPoint = "FindNextFlashCard")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public extern static bool FindNextFlashCard(IntPtr hFlashCard, ref WIN32_FIND_DATA findData);

        [DllImport("coredll")]
        public static extern bool FindClose(IntPtr hFindFile);
    }
}
5 голосов
/ 19 марта 2009

Имейте в виду, что "\ Storage Card" ориентирован на английский язык. Устройство, созданное для другого региона, может иметь другое имя. Имя пути к карте памяти на моем устройстве зависит от того, как я его использую.

Некоторое время назад в формах MSDN я ответил на несколько вопросов о том, как обнаружить карты памяти в файловой системе и как получить емкость карты памяти. Я написал следующее может быть ответом на эти вопросы и подумал, что было бы полезно поделиться. Карты памяти отображаются в файловой системе как временные каталоги. Эта программа проверяет объекты в корневом каталоге устройства, и любые папки, имеющие атрибут temp, считаются положительными.

using System;
using System.IO;
using System.Runtime.InteropServices;

namespace StorageCardInfo
{
    class Program
    {
        const ulong Megabyte = 1048576;
        const ulong Gigabyte = 1073741824;

        [DllImport("CoreDLL")]
        static extern int GetDiskFreeSpaceEx(
        string DirectoryName,
        out ulong lpFreeBytesAvailableToCaller,
        out ulong lpTotalNumberOfBytes,
        out ulong lpTotalNumberOfFreeBytes 
    );

    static void Main(string[] args)
    {
        DirectoryInfo root = new DirectoryInfo("\\");
        DirectoryInfo[] directoryList = root.GetDirectories();
        ulong FreeBytesAvailable;
        ulong TotalCapacity;
        ulong TotalFreeBytes;

        for (int i = 0; i < directoryList.Length; ++i)
        {
            if ((directoryList.Attributes & FileAttributes.Temporary) != 0)
            {
                GetDiskFreeSpaceEx(directoryList.FullName, out FreeBytesAvailable, out TotalCapacity, out TotalFreeBytes);
                Console.Out.WriteLine("Storage card name: {0}", directoryList.FullName);
                Console.Out.WriteLine("Available Bytes : {0}", FreeBytesAvailable);
                Console.Out.WriteLine("Total Capacity : {0}", TotalCapacity);
                Console.Out.WriteLine("Total Free Bytes : {0}", TotalFreeBytes);
            }
        }
    }
}
3 голосов
/ 13 сентября 2012

Я объединил ряд приведенных выше решений, в частности код qwlice, чтобы найти SD-карты на ряде устройств. Это решение находит только карты SD (исключая все внутренние «карты памяти», которые есть у некоторых устройств) без использования собственных вызовов dll.

Код выполняет поиск ключа, содержащего «SD», в ключе HKEY_LOCAL_MACHINE \ System \ StorageManager \ Profiles \, так как на некоторых устройствах имя слегка меняется, находит каталог монтирования по умолчанию и затем ищет временные каталоги, которые начинаются с этого. Это означает, что он найдет \ StorageCard2, \ StorageCard3 и т. Д.

Я использовал это на ряде устройств Intermec и Motorola / Symbol, и у меня не было никаких проблем. Вот код ниже:

public class StorageCardFinder
{
    public static List<string> GetMountDirs()
    {
        //get default sd card folder name
        string key = @"HKEY_LOCAL_MACHINE\System\StorageManager\Profiles";
        RegistryKey profiles = Registry.LocalMachine.OpenSubKey(@"System\StorageManager\Profiles");
        string sdprofilename = profiles.GetSubKeyNames().FirstOrDefault(k => k.Contains("SD"));
        if (sdprofilename == null)
            return new List<string>();

        key += "\\" + sdprofilename;
        string storageCardBaseName = Registry.GetValue(key, "Folder", "Storage Card") as String;
        if (storageCardBaseName == null)
            return new List<string>();

        //find storage card
        List<string> cardDirectories = GetFlashCardMountDirs();

        List<string> storageCards = new List<string>();
        foreach (string flashCard in GetFlashCardMountDirs())
        {
            string path = flashCard.Trim();
            if (path.StartsWith(storageCardBaseName))
            {
                storageCards.Add("\\" + path);
            }
        }
        return storageCards;
    }

    private static List<string> GetFlashCardMountDirs()
    {
        DirectoryInfo root = new DirectoryInfo("\\");
        return root.GetDirectories().Where(d => (d.Attributes & FileAttributes.Temporary) != 0)
                                    .Select(d => d.Name).ToList();
    }
}
3 голосов
/ 01 сентября 2011

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

Основное отличие состоит в том, что я ищу в каталогах монтирования всех флеш-карт и сохраняю те, которые соответствуют имени карты памяти по умолчанию, которое я читаю из реестра Windows.

Это решает проблему, которая возникает на интеллектуальных устройствах Motorola, где имеется несколько флэш-карт и только один считыватель SD-карт, имя монтирования которого можно изменить по умолчанию с помощью числового суффикса (т. Е. В английских системах WM: 'Карта памяти ',' Карта памяти2 'и т. Д.). Я тестировал его на некоторых моделях Motorola (MC75, MC75A, MC90, MC65) с английским языком WM 6.5.

Это решение должно хорошо работать с различными языками Windows Mobile, но я не знаю, может ли оно работать с теми, которые меняют имя по умолчанию для карт памяти. Все зависит от того, обновляет ли производитель устройства реестр Windows с новым именем по умолчанию.

Было бы здорово, если бы вы могли протестировать его на разных WM или устройствах. Обратная связь приветствуется.

   //
   // the storage card is a flash drive mounted as a directory in the root folder 
   // of the smart device
   //
   // on english windows mobile systems the storage card is mounted in the directory "/Storage Card", 
   // if that directory already exists then it's mounted in "/Storage Card2" and so on
   //
   // the regional name of the mount base dir of the storage card can be found in
   // the registry at [HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory\Folder]
   //  
   // in order to find the path of the storage card we look for the flash drive that starts 
   // with the base name
   //

   public class StorageCard
   {
      private StorageCard()
      {
      }

      public static List<string> GetMountDirs()
      {
         string key = @"HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory";
         string storageCardBaseName = Registry.GetValue(key, "Folder", "Storage Card") as String;
         List<string> storageCards = new List<string>();
         foreach (string flashCard in GetFlashCardMountDirs())
         {
            string path = flashCard.Trim();
            if (path.StartsWith(storageCardBaseName))
            {
               storageCards.Add(path);
            }
         }
         return storageCards;
      }

      private static List<string> GetFlashCardMountDirs()
      {
         List<string> storages = new List<string>();

         WIN32_FIND_DATA findData = new WIN32_FIND_DATA();
         IntPtr handle = IntPtr.Zero;

         handle = FindFirstFlashCard(ref findData);

         if (handle != INVALID_HANDLE_VALUE)
         {
            do
            {
               if (!string.IsNullOrEmpty(findData.cFileName))
               {
                  storages.Add(findData.cFileName);
                  storages.Add(findData.cAlternateFileName);
               }
            }
            while (FindNextFlashCard(handle, ref findData));
            FindClose(handle);
         }

         return storages;
      }

      private static readonly IntPtr INVALID_HANDLE_VALUE = (IntPtr)(-1);    

      [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
      private struct WIN32_FIND_DATA
      {
         public int dwFileAttributes;
         public FILETIME ftCreationTime;
         public FILETIME ftLastAccessTime;
         public FILETIME ftLastWriteTime;
         public int nFileSizeHigh;
         public int nFileSizeLow;
         public int dwOID;
         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
         public string cFileName;
         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
         public string cAlternateFileName;
      }

      [StructLayout(LayoutKind.Sequential)]
      private struct FILETIME
      {
         public int dwLowDateTime;
         public int dwHighDateTime;
      };

      [DllImport("note_prj", EntryPoint = "FindFirstFlashCard")]
      private extern static IntPtr FindFirstFlashCard(ref WIN32_FIND_DATA findData);

      [DllImport("note_prj", EntryPoint = "FindNextFlashCard")]
      [return: MarshalAs(UnmanagedType.Bool)]
      private extern static bool FindNextFlashCard(IntPtr hFlashCard, ref WIN32_FIND_DATA findData);

      [DllImport("coredll")]
      private static extern bool FindClose(IntPtr hFindFile);
   }
3 голосов
/ 08 января 2010

Невозможно добавить комментарий к обсуждению TreeUK и ctacke ниже:

Это не гарантируется, чтобы найти Карта памяти - многие устройства монтируются встроенная вспышка таким же образом, и это появится в этом списке, а также. - ctacke 8 мая в 18: 23
Это имеет у меня хорошо работали на HTC и Psion устройства. Какие устройства вы знаете это не работает? Будет стоить видя, есть ли другой атрибут вы можете сделать скидку на встроенную вспышку память с. - TreeUK 9 мая в 22: 29

Чтобы дать представление о Motorola MC75 (раньше это был SymboL), я использовал этот фрагмент (нативного) кода:

    WIN32_FIND_DATA cardinfo;
HANDLE  card = FindFirstFlashCard(&cardinfo);
if (card != INVALID_HANDLE_VALUE)
{
    TCHAR existFile[MAX_PATH];

    wprintf(_T("found : %s\n"), cardinfo.cFileName);

    while(FindNextFlashCard(card, &cardinfo))
    {
        wprintf(_T("found : %s\n"), cardinfo.cFileName);
    }
}
FindClose(card);

Отладочный вывод:

cardinfo.dwFileAttributes   0x00000110  unsigned long int
cardinfo.cFileName          "Application"   wchar_t[260]

cardinfo.dwFileAttributes   0x00000110  unsigned long int
cardinfo.cFileName          "Cache Disk"    wchar_t[260]

cardinfo.dwFileAttributes   0x00000110  unsigned long int
cardinfo.cFileName          "Storage Card"  wchar_t[260]

«Приложение» и «Кэш-диск» являются внутренними флэш-накопителями. «Карта памяти» - съемная SD-карта. Все помечены как FlashDrive (который они есть), но только «Карта памяти» является съемным.

3 голосов
/ 08 мая 2009

Существует чистый способ C # сделать это без собственных вызовов.

Взято из здесь .

//codesnippet:06EE3DE0-D469-44DD-A15F-D8AF629E4E03
public string GetStorageCardFolder()
{
   string storageCardFolder = string.Empty;
   foreach (string directory in Directory.GetDirectories("\\"))
   {
       DirectoryInfo dirInfo = new DirectoryInfo(directory);

       //Storage cards have temporary attributes do a bitwise check.
        //http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=612136&SiteID=1
        if ((dirInfo.Attributes & FileAttributes.Temporary) == FileAttributes.Temporary)
            storageCardFolder = directory;
    }

    return storageCardFolder;
}
1 голос
/ 03 сентября 2008

В Windows CE 5 (которая является основой для Windows Mobile 6) карты памяти монтируются в корневой файловой системе как «Карта памяти \», «Карта памяти2» и т. Д.

Чтобы выяснить, смонтирован ли он, вызовите GetFileAttributes (или, как мне кажется, удаленную версию CeGetFileAttributes), указав полный путь ("\ Storage Card \"). Если он возвращает INVALID_FILE_ATTRIBUTES, то он не монтируется, в противном случае проверьте, чтобы убедиться, что это каталог, прежде чем возвращать true.

...