gpt4 book ai didi

c# - 如何通过 Windows Mobile 6 使用存储管理器 API 格式化 SD 卡

转载 作者:可可西里 更新时间:2023-11-01 03:11:21 28 4
gpt4 key购买 nike

背景:

我正在尝试创建一个实用程序,使我们的客户能够直接在 Windows Mobile 6 设备 (Intermec CK3) 上轻松格式化 SD 卡(实际上是 mini-SD)。这将优于第三方工具,例如 FlashFormat或者必须向客户提供读卡器(这将要求他们取出电池,拉出由脆弱的金属外壳固定的迷你 SD 卡,然后通过文件管理控件运行 Windows 格式化实用程序)。我们的大多数客户都不是很精通技术,因此可以自动运行或只需单击几下即可运行的实用程序是理想的选择。

到目前为止,我已经尝试了以下方法:

  • 查看了 this题。此处的答案似乎不适用于 Windows Mobile(例如,不支持 WMI 或 format.com 实用程序)。
  • 尝试使用 CreateFileDeviceIoControlCE .这看起来很有希望,但 SD 卡似乎永远不会真正格式化。据我所知,这是因为需要先卸下卡。
  • 尝试使用 CreatFileFormatVolumeEx (连同其他变体,FormatVolumeFormateVolumeUI )。结果似乎是相似的,除非先卸载卡,否则我无法格式化卡。

在做了一些搜索之后遇到了 this thread (由 paraGOD 在底部附近回答)和 this blog , 我决定走一条使用 Store Manager API 的新道路,具有FindFirstStore等功能, FindNextStore , OpenStore , DismountStore等等。

我试图在 C# 中执行此操作,因此我创建了必要的支持结构来表示 API 中使用的 typdef。这是一个示例:

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

然后我创建了一个静态存储管理器类来保存所有存储管理器功能(这些功能应该在 coredll for windows mobile 6 中可用......我认为是这样的):

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

所以我去测试了其中的一些函数,例如通过 FindFirstStore 和 FindNextStore 函数简单地枚举商店然后我得到了可怕的,找不到入口点“FindFirstStore” PInvoke DLL 'Coredll.dll' 错误(在调试器输出中我也得到 A first chance exception of type 'System.MissingMethodException' occurred in SDFormatter.exe,这是有道理的)。一些更多的研究表明,在 Windows Mobile 中,这些功能没有公开,即使它们是 Coredll 的一部分。然而,它们是 Windows CE 6 的一部分,可以通过平台构建器访问。

所以这里是我的主要问题:

  • 我可以通过 C# 在 Windows Mobile 6 中访问存储管理器 API 吗?
  • 如果没有,我可以通过托管 C++ 编写一个实用程序吗(我不太了解,但如果需要我会偶然发现),但不必使用平台构建器(它不是免费的)?<
  • 如果只能通过平台构建器实现,这是否意味着我要么无法构建自己的 SDK,要么必须请求 Intermec 为我公开该功能?

如果有人有建议,我也愿意完全采用另一种方式(最好通过 C#)。我在想也许让客户将设备安装在支架上并运行桌面实用程序。不确定这是否可能并且它不能依赖 ActiveSync(我们不想支持另一种工具,所以我们通过连接到底座的网络适配器使用套接字在 SD 卡之间发送数据自定义服务器程序和我们的移动应用程序)。

谢谢

最佳答案

我们有完全相同的要求,但在 Windows CE 上。我们的解决方案是创建一个小型 C++ 应用程序,然后从 C# 代码调用它。这是 C++ 应用程序最重要的部分:

#include <windows.h>
#include <Storemgr.h>

int _tmain( int /*argc*/, _TCHAR* /*argv*/[] )
{
WCHAR szDisk[] = L"DSK0";

hDsk = OpenStore(szDisk);
if(hDsk == INVALID_HANDLE_VALUE)
// ERROR : Opening Store

if (!GetStoreInfo(hDsk, &si))
// ERROR : Getting Store Info

if(!DismountStore(hDsk))
// ERROR : Dismounting Store

if(!FormatStore(hDsk))
// ERROR : Formatting Store

CloseHandle(hDsk);
}

关于c# - 如何通过 Windows Mobile 6 使用存储管理器 API 格式化 SD 卡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7176539/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com