Frage

Gibt es eine einfache Möglichkeit, den Pfad der Speicherkarte auf einem Windows Mobile-Gerät zu finden? Wann gibt es eine Speicherkarte und eine Bluetooth-FTP-Verbindung?

War es hilfreich?

Lösung

Beachten Sie, dass „\Storage Card“ auf Englisch ausgerichtet ist.Ein für eine andere Region hergestelltes Gerät hat möglicherweise einen anderen Namen.Der Name des Speicherkartenpfads auf meinem Gerät hängt davon ab, wie ich das Gerät verwende.

Vor einiger Zeit habe ich in den MSDN-Formularen ein paar Fragen dazu beantwortet, wie man die Speicherkarten im Dateisystem erkennt und wie man die Kapazität der Speicherkarte ermittelt.Ich habe geschrieben, dass das Folgende eine Antwort auf diese Fragen sein könnte und dachte, es wäre hilfreich, es zu teilen.Speicherkarten werden im Dateisystem als temporäre Verzeichnisse angezeigt.Dieses Programm untersucht die Objekte im Stammverzeichnis des Geräts und alle Ordner mit dem Attribut temp werden als positive Übereinstimmung betrachtet

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);
            }
        }
    }
}

Andere Tipps

Der Mount-Punkt ist normalerweise „\Storage Card“, kann aber in andere Sprachen lokalisiert oder von OEMs geändert werden (einige Geräte verwenden „\SD Card“ oder andere Mount-Punkte, und einige Geräte unterstützen das Mounten mehrerer Speichermedien).Die beste Möglichkeit, die verfügbaren Karten aufzulisten, ist die Verwendung von FindFirstFlashCard und FindNextFlashCard.

Beide Funktionen füllen eine WIN32_FIND_DATA-Struktur aus.Das wichtigste Feld ist cFileName, das den Pfad zum Mountpunkt der Karte enthält (z. B."\Speicherkarte").

Beachten Sie, dass diese Funktionen auch den internen Speicher des Geräts auflisten.Wenn Sie sich nur für externe Volumes interessieren, ignorieren Sie den Fall, dass cFileName eine leere Zeichenfolge ("") ist.

Für die Verwendung dieser Funktionen müssen Sie <projects.h> #include und mit note_prj.lib verknüpfen.Beide sind in den Windows Mobile SDKs für WM 2000 und höher enthalten.

Ich habe festgestellt, dass die Verwendung der FindFirstFlashCard/FindNextFlashCard-APIs zuverlässiger ist als das Aufzählen von Verzeichnissen und das Überprüfen des temporären Flags (das beispielsweise freigegebene Bluetooth-Ordner zurückgibt).

Die folgende Beispielanwendung demonstriert deren Verwendung und die erforderlichen P/Invoke-Anweisungen.

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);
    }
}

Es gibt eine reine C#-Methode, dies ohne native Aufrufe zu tun.

Genommen von Hier.

//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;
}

Zur TreeUK- und Ctacke-Diskussion unten kann kein Kommentar hinzugefügt werden:

Es ist nicht garantiert, dass Sie eine Speicherkarte - viele Geräte können gemountet werden eingebauten Blitz auf die gleiche Weise, und es würde auch in dieser Liste auftauchen.– 8. Mai um 18:23
Dies hat dazu geführt, dass funktionierte bei mir gut auf HTC und Psion Geräte.Welche Geräte sind Ihnen bekannt? Das funktioniert nicht?Würde sich lohnen Sehen, ob es ein anderes Attribut gibt Sie können den Build-in-Flash rabattieren Speicher mit.– TreeUK 9. Mai um 22:29

Um eine Vorstellung von einem Motorola MC75 (früher SymboL) zu geben, habe ich diesen (nativen) Code verwendet:

    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);

Debug-Ausgabe:

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]

Bei „Anwendung“ und „Cache-Datenträger“ handelt es sich um interne Flash-Laufwerke.Die „Speicherkarte“ ist eine herausnehmbare SD-Karte.Alle sind als FlashDrive gekennzeichnet (was sie auch sind), aber nur „Speicherkarte“ ist entfernbar.

Ich habe eine Reihe der oben genannten Lösungen kombiniert, insbesondere den Code von qwlice, um SD-Karten auf einer Reihe von Geräten zu finden.Diese Lösung findet nur SD-Karten (schließt also alle internen „Speicherkarten“ einiger Geräte aus), ohne native DLL-Aufrufe zu verwenden.

Der Code durchsucht den Schlüssel HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\ nach Schlüsseln, die „SD“ enthalten, da der Name auf einigen Geräten leicht variiert, findet das Standard-Mount-Verzeichnis und sucht dann nach temporären Verzeichnissen, die damit beginnen.Das bedeutet, dass \StorageCard2, \StorageCard3 usw. gefunden werden.

Ich habe es auf einer Reihe von Intermec- und Motorola/Symbol-Geräten verwendet und hatte keine Probleme.Hier ist der Code unten:

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();
    }
}

Ich poste hier den Code, den ich verwende, um die Mount-Verzeichnisse der Speicherkarten zu erhalten.Der Teil, in dem ich die Pfade der Karteikarten erhalte, ist mit ein paar Änderungen aus Sablys Beitrag kopiert.

Der Hauptunterschied besteht darin, dass ich die Mount-Verzeichnisse aller Flash-Karten durchsuche und diejenigen behalte, die mit dem Standard-Speicherkartennamen übereinstimmen, den ich aus der Windows-Registrierung gelesen habe.

Es löst das Problem, das man auf den Smart-Geräten von Motorola hat, wo es mehrere Flash-Karten und nur einen SD-Kartenleser gibt, dessen Mount-Verzeichnisname durch das numerische Suffix (z. B.in englischen WM-Systemen:„Speicherkarte“, „Speicherkarte2“ usw.).Ich habe es auf einigen Motorola-Modellen (MC75, MC75A, MC90, MC65) mit WM 6.5 Englisch getestet.

Diese Lösung sollte gut mit verschiedenen Sprachen von Windows Mobile funktionieren, aber ich weiß nicht, ob sie mit denen umgehen kann, die die Standardname der Speicherkarten.Es hängt alles davon ab, ob der Hersteller des Geräts die Windows-Registrierung mit aktualisiert neu Standardname.

Es wäre großartig, wenn Sie es auf verschiedenen WMs oder Geräten testen könnten.Feedback ist willkommen.

   //
   // 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);
   }

Unter Windows CE 5 (das die Basis für Windows Mobile 6 darstellt) werden die Speicherkarten im Root-Dateisystem als „Storage Card\“, „Storage Card2\“ usw. gemountet.

Um herauszufinden, ob es gemountet ist, rufen Sie GetFileAttributes (oder die Remote-Version CeGetFileAttributes, glaube ich) auf und geben Sie den vollständigen Pfad („\Storage Card\“) ein.Wenn INVALID_FILE_ATTRIBUTES zurückgegeben wird, ist es nicht gemountet. Andernfalls prüfen Sie, ob es sich um ein Verzeichnis handelt, bevor Sie „true“ zurückgeben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top