16

バックグラウンド:

お客様が SD カード (実際にはミニ SD) を Windows Mobile 6 デバイス (Intermec CK3) で直接簡単にフォーマットできるようにするユーティリティを作成しようとしています。これは、 FlashFormatなどのサード パーティ製ツールや、顧客にカード リーダーを提供する必要がある (バッテリーを取り外し、薄い金属製のハウジングに保持されている mini-SD カードを引き出してから、ファイル管理コントロールを介して Windows フォーマット ユーティリティを実行します)。ほとんどのお客様は技術に精通していないため、自動的に、または数回クリックするだけで実行できるユーティリティが理想的です。

これまでに次のことを試しました。

  • この質問を見ました。ここでの回答は、Windows Mobile では機能しないようです (たとえば、WMI サポートや format.com ユーティリティがありません)。
  • CreateFileDeviceIoControlCEを使用してみました。これは有望に思えましたが、SD カードが実際にフォーマットされることはありませんでした。私が知る限り、最初にカードを取り外す必要があったためです。
  • CreatFileFormatVolumeExを使用してみました (他のバリアントであるFormatVolumeFormatVolumeUI と共に)。カードを最初に取り外さないとフォーマットできないという点で、結果は同様のようでした。

このスレッド(paraGOD による一番下の回答) とこのブログを検索した後、 FindFirstStoreFindNextStoreOpenStoreDismountStoreなどの機能を持つStore Manager APIを使用する新しいパスをたどることにしました。 .

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

次に、すべてのストレージ マネージャー機能を保持するための静的ストレージ マネージャー クラスを作成しました (Windows Mobile 6 の coredll で利用できるはずです... またはそう思いました)。

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 関数を介してストアを単に列挙するなど、これらの関数のいくつかをテストするために行ったところ、恐ろしい「Can't find an Entry Point 'FindFirstStore' in a PInvoke DLL 'Coredll.dll'」エラーが発生しました(デバッガーの出力では、A first chance exception of type 'System.MissingMethodException' occured in SDFormatter.exeも取得します。これは理にかなっています)。Windows Mobile では、Coredll の一部であるにもかかわらず、これらの関数が公開されていないことがいくつかの調査で示唆されました。ただし、これらは Windows CE 6 の一部であり、プラットフォーム ビルダーからアクセスできます。

だからここに私が持っている主な質問があります:

  • Windows Mobile 6 で C# 経由で Storage Manager API にアクセスするにはどうすればよいですか?
  • そうでない場合、プラットフォーム ビルダーを使用せずに (無料ではない)、マネージ C++ を使用してユーティリティを作成できますか?
  • プラットフォーム ビルダーを介してのみ可能である場合、それは私が独自の SDK の構築に行き詰まっていることを意味するのでしょうか、それとも Intermec に機能を公開するよう依頼する必要があるのでしょうか?

また、提案があれば、これを完全に別の方法で(できればC#を介して)行うこともできます。私は、顧客にデバイスをクレードルにマウントしてもらい、デスクトップ ユーティリティを実行してもらうことを考えていました。これが可能かどうかは不明で、ActiveSync に依存することはできません (さらに別のツールをサポートしたくないため、ソケットを使用してクレードルに接続されたネットワーク アダプターを介して SD カードとの間でデータをやり取りします)。カスタム サーバー プログラムと当社のモバイル アプリケーション)。

ありがとう

4

2 に答える 2

2

まったく同じ要件がありましたが、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);
}
于 2012-02-04T10:55:37.330 に答える
0

FindFirstStoreは Windows Mobile 5.0 以降のデバイスのパブリック API で利用できるため、プラットフォーム ビルダーのような手の込んだものは必要ありません。

FindFirstStore が CE6 で coredll.dll にのみ移動したことをどこかで読んだと思います (どこで見たのか思い出せません)。そのため、Windows Mobile 6 デバイスには、おそらく別の場所からエクスポートされたものがあります。(おそらくstoreapi.dll?)

このコードで C++ プロジェクトを作成してみて、うまくいくかどうかを確認してください。

#pragma comment( lib, "storeapi.lib" )

int _tmain( int /*argc*/, _TCHAR* /*argv*/[] )
{
    STOREINFO si = { 0 };
    si.cbSize = sizeof( STOREINFO );

    HANDLE ffs = ::FindFirstStore( &si );
    if( INVALID_HANDLE_VALUE != ffs )
    {
        ::FindCloseStore( ffs );
    }
    return 0;
}
于 2011-08-29T19:20:26.630 に答える