Background:Come si formatta una scheda SD utilizzando l'API Storage Manager tramite Windows Mobile 6
Sto cercando di creare un programma di utilità che permetterà ai nostri clienti di formato facilmente una scheda SD (in realtà mini-SD) direttamente su un dispositivo Windows Mobile 6 (Intermec CK3). Ciò sarebbe preferibile a uno strumento di terze parti come FlashFormat o a fornire lettori di schede ai clienti (che richiederebbero loro di rimuovere la batteria, estrarre la scheda mini-SD che è contenuta da un involucro di metallo sottile, quindi eseguire l'utilità di formattazione di Windows tramite il controllo di gestione dei file). La maggior parte dei nostri clienti non sono molto esperti di tecnologia, quindi un'utilità che può essere eseguita automaticamente o con un paio di clic sarebbe l'ideale.
Ho provato la seguente finora:
- Guardato this domanda. Le risposte qui non sembrano funzionare per Windows Mobile (ad esempio nessun supporto WMI o utility format.com).
- Provato usando CreateFile e DeviceIoControlCE. Questo sembrava promettente, ma la scheda SD non sembrerebbe mai realmente formattata. Da quello che ho potuto dire, è stato perché la carta doveva essere smontata prima.
- Provato con CreatFile e FormatVolumeEx (insieme con le altre varianti, FormatVolume e FormateVolumeUI). Il risultato sembrava essere simile in quanto non potevo formattare la scheda a meno che non fosse prima smontata.
Dopo aver fatto qualche ricerca di una esecuzione in this thread (risposta nei pressi di fondo da paraGOD) e this blog, ho deciso di andare giù un nuovo percorso di usare la Store Manager API, che ha funzioni come FindFirstStore, FindNextStore, OpenStore, DismountStore e presto.
Sto provando a farlo in C#, quindi ho creato le strutture di supporto necessarie per rappresentare i typdefs utilizzati nell'API. Ecco un esempio 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;
}
}
Poi ho creato una classe di storage manager statica per contenere tutte le funzioni storage manager (che dovrebbero essere disponibili nel coredll per Windows Mobile 6 ... o almeno così pensavo) :
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
Così sono andato a provare alcune di queste funzioni, come ad esempio semplicemente enumerazione attraverso i negozi tramite le funzioni FindFirstStore e FindNextStore e poi ho temuto, Impossibile trovare 'FindFirstStore' un punto di ingresso in un errore "Coredll.dll" PInvoke DLL (in th output di debugger ottengo anche Una prima eccezione di tipo "System.MissingMethodException" si è verificata in SDFormatter.exe, il che ha senso). Altre ricerche hanno fatto capire che in Windows Mobile queste funzioni non sono esposte, anche se fanno parte di Coredll. Sono tuttavia parte di Windows CE 6 e sono accessibili tramite il programma di sviluppo della piattaforma.
Così qui sono le principali domande che ho:
- Posso accedere all'API Storage Manager tramite C# in Windows Mobile 6 in qualche modo?
- In caso contrario, posso scrivere un programma di utilità tramite C++ gestito (non so molto, ma lo troverò se necessario), ma senza dover utilizzare il costruttore di piattaforme (non è gratuito)?
- Se è possibile solo tramite il generatore di piattaforme, vuol dire che sono bloccato a costruire il mio SDK o dovrò chiedere a Intermec di esporre la funzionalità per me?
Sono anche aperto a farlo in un altro modo completamente (preferibilmente tramite C#) se qualcuno ha suggerimenti. Stavo pensando che forse il cliente avrebbe potuto montare il dispositivo nella base e gestire un'utility desktop. Non sono sicuro se ciò è possibile e non può fare affidamento su ActiveSync (non vogliamo supportare ancora un altro strumento, quindi inviamo i dati da e verso la scheda SD tramite un adattatore di rete collegato alla base tramite prese per parlare tra i nostri programma server personalizzato e la nostra applicazione mobile).
Grazie
mi sono imbattuto in questo 2009 discussione newsgroup che potrebbero essere rilevanti: http://www.pocketpcjunkies.com/Uwe/Forum.aspx/wince-pb/21443/StoreApi-Lib-not-exported-in-the-SDK-and-linking-di-rect-doesn – PaulH