문제

스토리지 카드와 Bluetooth FTP 연결이있을 때 Windows 모바일 장치에서 스토리지 카드의 경로를 쉽게 찾을 수있는 방법이 있습니까?

도움이 되었습니까?

해결책

"\Storage Card"는 영어 기반이라는 점에 유의하세요.다른 지역용으로 만들어진 장치는 다른 이름을 가질 수 있습니다.내 장치의 저장소 카드 경로 이름은 장치를 사용하는 방법에 따라 다릅니다.

얼마 전 MSDN 양식에서 파일 시스템에서 저장소 카드를 검색하는 방법과 저장소 카드의 용량을 얻는 방법에 대한 몇 가지 질문에 응답했습니다.나는 다음과 같은 질문에 대한 답변을 썼고 공유하는 것이 도움이 될 것이라고 생각했습니다.저장소 카드는 파일 시스템에 임시 디렉터리로 표시됩니다.이 프로그램은 장치의 루트에 있는 개체를 검사하고 임시 속성이 있는 모든 폴더는 긍정적인 일치로 간주됩니다.

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

다른 팁

마운트 지점은 일반적으로 "\Storage Card"이지만 다른 언어로 지역화되거나 OEM에 의해 수정될 수 있습니다(일부 장치는 "\SD 카드" 또는 다른 마운트 지점을 사용하고 일부 장치는 여러 저장소 미디어 마운트를 지원합니다).사용 가능한 카드를 열거하는 가장 좋은 방법은 FindFirstFlashCard 및 FindNextFlashCard를 사용하는 것입니다.

두 함수 모두 WIN32_FIND_DATA 구조를 채웁니다.가장 중요한 필드는 cFileName이며, 여기에는 카드 마운트 지점에 대한 경로가 포함됩니다(예:"\저장소 카드").

장치의 내부 메모리도 이러한 함수로 열거됩니다.외부 볼륨에만 관심이 있는 경우 cFileName이 빈 문자열("")인 경우를 무시하세요.

이러한 기능을 사용하려면 <projects.h>를 #include하고 note_prj.lib와 연결해야 합니다.둘 다 WM 2000 이상용 Windows Mobile SDK에 포함되어 있습니다.

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

기본 호출 없이 이를 수행하는 순수한 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;
}

아래의 TreeUK 및 ctacke 토론에 댓글을 추가할 수 없습니다.

이것은 스토리지 카드를 찾는 것이 보장되지 않습니다. 많은 장치가 같은 방식으로 내장 플래시를 마운트합니다.이 목록에도 나타납니다.- Ctacke 5 월 8 일 18:23
이것은 HTC 및 PSION 장치에서 나에게 잘 작동했습니다.이것이 작동하지 않는다는 것을 알고 있습니까?플래시 메모리에서 빌드를 할인 할 수있는 또 다른 속성이 있는지 확인할 가치가 있습니다.– TreeUK 5월 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 카드입니다.모두 플래시드라이브(그렇습니다)로 표시되어 있지만 "저장 카드"만 제거 가능합니다.

다양한 장치에서 SD 카드를 찾기 위해 위의 여러 솔루션, 특히 qwlice의 코드를 결합했습니다.이 솔루션은 기본 dll 호출을 사용하지 않고 SD 카드만 찾습니다(따라서 일부 장치에 있는 모든 내부 "저장 카드" 제외).

이름이 일부 장치에서 약간 다르기 때문에 코드는 HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\ 키에서 "SD"가 포함된 키를 검색하고 기본 마운트 디렉터리를 찾은 다음 이것으로 시작하는 임시 디렉터리를 찾습니다.즉, \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();
    }
}

여기에 저장소 카드의 마운트 디렉터리를 가져오는 데 사용하는 코드를 게시합니다.플래시 카드 경로를 얻는 부분은 몇 가지 변경 사항을 포함하여 Sily의 게시물에서 복사되었습니다.

주요 차이점은 모든 플래시 카드의 마운트 디렉토리를 검색하고 Windows 레지스트리에서 읽은 기본 저장소 카드 이름과 일치하는 디렉토리를 유지한다는 것입니다.

이는 여러 개의 플래시 카드가 있고 마운트 디렉토리 이름이 숫자 접미사(예:영어로 WM 시스템:'저장 카드', '저장 카드2' 등).WM 6.5 English를 사용하여 일부 모토로라 모델(MC75, MC75A, MC90, MC65)에서 테스트했습니다.

이 솔루션은 다른 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);
   }

Windows CE 5(Windows Mobile 6의 기반)에서 저장소 카드는 루트 파일 시스템에 "Storage Card\", "Storage Card2\" 등으로 마운트됩니다.

마운트되었는지 확인하려면 전체 경로("\Storage Card\")를 전달하는 GetFileAttributes(또는 제가 생각하는 원격 버전 CeGetFileAttributes)를 호출하세요.INVALID_FILE_ATTRIBUTES를 반환하면 마운트되지 않은 것입니다. 그렇지 않으면 true를 반환하기 전에 디렉터리인지 확인하세요.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top