Antecedentes:¿Cómo se formatea una tarjeta SD utilizando la API de almacenamiento a través de Windows Mobile 6
Estoy intentando crear una utilidad que permitirá a nuestros clientes para dar formato fácilmente una tarjeta SD (en realidad mini-SD) directamente en un dispositivo con Windows Mobile 6 (Intermec CK3). Esto sería preferible a una herramienta de terceros como FlashFormat o tener que proporcionar lectores de tarjetas a los clientes (lo que requeriría que extraigan la batería, extraigan la tarjeta mini-SD que está sujeta por una carcasa de metal endeble, y luego ejecutar la utilidad de formateo de Windows a través del control de gestión de archivos). La mayoría de nuestros clientes no son muy conocedores de la tecnología, por lo que una utilidad que se puede ejecutar automáticamente o con un par de clics sería ideal.
He intentado lo siguiente hasta el momento:
- Mirado this cuestión. Las respuestas aquí no parecen funcionar para Windows Mobile (por ejemplo, no hay soporte WMI o utilidad format.com).
- Probado utilizando CreateFile y DeviceIoControlCE. Este parecía prometedor, pero la tarjeta SD nunca parece formatear realmente. Por lo que pude ver, fue porque primero era necesario desmontar la tarjeta.
- Probado usando CreatFile y FormatVolumeEx (junto con las otras variantes, FormatVolume y FormateVolumeUI). El resultado parecía ser similar en el sentido de que no podía formatear la tarjeta a menos que primero se desmontara.
Después de hacer algunas búsquedas en un funcionamiento en this thread (respuesta cerca del fondo por paraGOD) y this blog, decidí ir por un nuevo camino de utilizar el Store Manager API, que tiene las funciones que FindFirstStore, FindNextStore, OpenStore, DismountStore y pronto.
Estoy intentando hacer esto en C#, así que creé las estructuras de soporte necesarias para representar los typdefs utilizados en la API. Aquí está una muestra de uno:
using System.Runtime.InteropServices;
// Try to match the struct typedef exactly (all caps, exact type names).
using DWORD = System.UInt32;
using TCHAR = System.String;
namespace SDFormatter
{
// http://msdn.microsoft.com/en-us/library/ee490035(v=WinEmbedded.60).aspx
// STORAGEDEVICEINFO (Storage Manager)
[StructLayout(LayoutKind.Sequential)]
public struct StorageDeviceInfo
{
public DWORD cbSize;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public TCHAR szProfile;
public DWORD dwDeviceClass;
public DWORD dwDeviceType;
public DWORD dwDeviceFlags;
}
}
Luego he creado una clase estática gestor de almacenamiento para contener todas las funciones de administrador de almacenamiento (que se supone que deben estar disponibles en coredll para Windows Mobile 6 ... o eso creía yo) :
using System.Runtime.InteropServices;
// Try to match the Coredll functions exactly (all caps, exact type names, etc.).
using BOOL = System.Boolean;
using BYTE = System.Byte;
using DWORD = System.UInt32;
using HANDLE = System.IntPtr;
using LPCE_VOLUME_INFO = System.IntPtr;
using LPCSTR = System.String;
using LPCTSTR = System.String;
using LPCWSTR = System.String;
using PPARTINFO = System.IntPtr;
using PSTOREINFO = System.IntPtr;
using SECTORNUM = System.UInt64;
// ReSharper disable InconsistentNaming
namespace SDFormatter
{
// http://msdn.microsoft.com/en-us/library/ee490420(v=WinEmbedded.60).aspx
public static class StorageManager
{
[DllImport("Coredll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool CeGetVolumeInfo(LPCWSTR pszRootPath, CE_VOLUME_INFO_LEVEL InfoLevel,
LPCE_VOLUME_INFO lpVolumeInfo);
[DllImport("Coredll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool CreatePartition(HANDLE hStore, LPCTSTR szPartitionName, SECTORNUM snNumSectors);
[DllImport("Coredll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool CreatePartitionEx(HANDLE hStore, LPCTSTR szPartitionName, BYTE bPartType,
SECTORNUM snNumSectors);
[DllImport("Coredll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool DeletePartition(HANDLE hStore, LPCTSTR szPartitionName);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern bool DismountPartition(HANDLE hPartition);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern bool DismountStore(HANDLE hStore);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern bool FindClosePartition(HANDLE hSearch);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern bool FindCloseStore(HANDLE hSearch);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern HANDLE FindFirstPartition(HANDLE hStore, PPARTINFO pPartInfo);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern HANDLE FindFirstStore(PSTOREINFO pStoreInfo);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern bool FindNextPartition(HANDLE hSearch, PPARTINFO pPartInfo);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern bool FindNextStore(HANDLE hSearch, PSTOREINFO pStoreInfo);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern bool FormatPartition(HANDLE hPartition);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern bool FormatPartitionEx(HANDLE hPartition, BYTE bPartType, BOOL bAuto);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern bool FormatStore(HANDLE hStore);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern bool GetPartitionInfo(HANDLE hPartition, PPARTINFO pPartInfo);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern bool GetStoreInfo(HANDLE hStore, PSTOREINFO pStoreInfo);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern bool MountPartition(HANDLE hPartition);
[DllImport("Coredll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern HANDLE OpenPartition(HANDLE hStore, LPCTSTR szPartitionName);
[DllImport("Coredll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern HANDLE OpenStore(LPCSTR szDeviceName);
[DllImport("Coredll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool RenamePartition(HANDLE hPartition, LPCTSTR szNewName);
[DllImport("Coredll.dll", SetLastError = true)]
public static extern bool SetPartitionAttributes(HANDLE hPartition, DWORD dwAttrs);
// http://msdn.microsoft.com/en-us/library/ee490442(v=winembedded.60).aspx
[DllImport("Coredll.dll", SetLastError = true)]
public static extern bool CloseHandle(HANDLE hObject);
}
public enum CE_VOLUME_INFO_LEVEL
{
CeVolumeInfoLevelStandard = 0
}
}
// ReSharper restore InconsistentNaming
así que fui a probar algunas de estas funciones, tales como una simple enumeración través de las tiendas a través de las funciones y FindFirstStore FindNextStore y entonces consigo la temida, no puede encontrar 'FindFirstStore' punto de entrada en una DLL de PInvoke 'Coredll.dll' error (en e salida del depurador También recibo Se produjo una primera excepción de tipo 'System.MissingMethodException' en SDFormatter.exe, lo cual tiene sentido). Algunas investigaciones más insinuaron que en Windows Mobile, estas funciones no están expuestas, a pesar de que son parte de Coredll. Sin embargo, son parte de Windows CE 6 y se puede acceder a través del creador de plataforma.
Así que aquí son las principales preguntas que tengo:
- ¿Puedo acceder a la API de almacenamiento a través de C# en Windows Mobile 6 de alguna forma?
- Si no es así, ¿puedo escribir una utilidad a través de C++ administrado (no sé mucho, pero voy a tropezar si es necesario), pero sin tener que usar el creador de plataformas (no es gratis)?
- Si solo es posible a través del creador de plataformas, ¿eso significa que estoy atascado construyendo mi propio SDK o tendré que pedirle a Intermec que me exponga la funcionalidad?
También estoy dispuesto a hacer esto de otra manera (preferiblemente a través de C#) si alguien tiene alguna sugerencia. Estaba pensando que tal vez el cliente podría montar el dispositivo en la cuna y ejecutar una utilidad de escritorio. No estoy seguro de si esto es posible y no puede confiar en ActiveSync (no queremos admitir otra herramienta más, por lo que enviamos datos hacia y desde la tarjeta SD a través de un adaptador de red conectado a la base usando conectores para hablar entre programa de servidor personalizado y nuestra aplicación móvil).
Gracias
me encontré con este hilo de 2009 del grupo de noticias que podrían ser relevantes: http://www.pocketpcjunkies.com/Uwe/Forum.aspx/wince-pb/21443/StoreApi-Lib-not-exported-in-the-SDK-and-linking-di-rect-doesn – PaulH