在WM6上查找存储卡路径
有没有一种简单的方法可以在Windows Mobile设备上查找存储卡的路径
什么时候有存储卡和蓝牙ftp连接?
解决方案
回答
在Windows CE 5(这是Windows Mobile 6的基础)上,存储卡将挂载在根文件系统上,如" Storage Card "," Storage Card2 "等。
要查明是否已挂载,请调用完整路径(" \ Storage Card ")传递的GetFileAttributes(或者我相信的远程版本CeGetFileAttributes)。如果返回INVALID_FILE_ATTRIBUTES,则不会挂载它,否则请在返回true之前检查以确保它是目录。
回答
挂载点通常是" \ Storage Card",但可以本地化为其他语言或者由OEM修改(某些设备使用" \ SD卡"或者其他挂载点,而某些设备支持挂载多个存储介质)。枚举可用卡的最佳方法是使用FindFirstFlashCard和FindNextFlashCard。
这两个函数都填充WIN32_FIND_DATA结构。最重要的字段是cFileName,它将包含卡的安装点的路径(例如" \ Storage Card")。
请注意,这些功能也会枚举设备的内部存储器。如果只关心外部卷,请忽略cFileName为空字符串("")的情况。
使用这些功能需要我们#include <projects.h>并链接到note_prj.lib。两者都包含在WM 2000和更高版本的Windows Mobile SDK中。
回答
请记住," \ 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); } } } }
回答
我发现使用FindFirstFlashCard / FindNextFlashCard API比枚举目录和检查临时标志(例如,它将返回蓝牙共享文件夹)更可靠。
下面的示例应用程序演示了如何使用它们以及所需的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); } }
回答
有一个纯Cway无需本地调用即可执行此操作。
从这里拍摄。
//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; }
回答
无法在下面的TreeUK和ctacke讨论中添加评论:
This isn't guaranteed to find a Storage Card - many devices mount built-in flash in teh same way, and it would show up in this list as well. – ctacke May 8 at 18:23 This has worked well for me on HTC and Psion devices. What devices are you aware this doesn't work on? Would be worth seeing if there's another attribute you can discount the build in flash memory with. – TreeUK May 9 at 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(它们是),但是只有"存储卡"是可移动的。