1

winCE 6.0 バージョンで ac# アプリケーションを実行しています。実行時に SD カード ドライバをアンロード/リロードする必要があります。FindFirstDevice を呼び出してから DeactivateDevice/ActivateDeviceEX を呼び出してこれを実行しようとしています。私の問題は、FindFirstDevice() 呼び出しが常に失敗することです。2番目のパラメーターをマーシャリングする方法に問題があると思います。誰が私が間違っているのか教えてもらえますか? コードは次のとおりです。

  [DllImport("coredll.dll", SetLastError = true)]
  public static extern int FindFirstDevice(DeviceSearchType
  searchType, IntPtr searchParam, ref DEVMGR_DEVICE_INFORMATION pdi);

  public bool MountSDCardDrive(string mRegPath)
  {
     const int INVALID_HANDLE_VALUE = -1;

     int handle = INVALID_HANDLE_VALUE;
     DeviceSearchType searchType = DeviceSearchType.DeviceSearchByDeviceName;

     DEVMGR_DEVICE_INFORMATION di = new DEVMGR_DEVICE_INFORMATION();
     di.dwSize = (uint)Marshal.SizeOf(typeof(DEVMGR_DEVICE_INFORMATION));

     string searchParamString = "*";
     IntPtr searchParam = Marshal.AllocHGlobal(searchParamString.Length);
     Marshal.StructureToPtr(searchParamString, searchParam, false);

     handle = FindFirstDevice(searchType, searchParam, ref di);
     if (handle == INVALID_HANDLE_VALUE)
     {
        // Failure - print error
        int hFindFirstDeviceError = Marshal.GetLastWin32Error();

        using (StreamWriter bw = new StreamWriter(File.Open(App.chipDebugFile, FileMode.Append)))
        {
           String iua = "DevDriverInterface: error from FindFirstDevice: " + hFindFirstDeviceError.ToString();
           bw.WriteLine(iua);
        }
        return false;
     }

... (rest of code)

Marshal.StructureToPtr(searchParamString, searchParam, false);searchParam = Marshal.StringToBSTR(searchParamString);「18 (これ以上ファイルがありません) ではなくエラー 1168 (ERROR_NOT_FOUND) で終わる」 に変更すると、

私の意図は、これを機能さsearchParamStringせるときに「SDH1」を使用することです。私は現在searchParamString、何かが返されたことを確認し、特定の文字列値を除外するために「*」を使用しています。

助けてくれてありがとう - リン

4

1 に答える 1

1

FindFirstDevice は、FindNextDevice と一緒に使用する必要があります (FindFirstDevice によって返されるハンドルを最初の引数として使用し、別のデバイスが見つかった場合は TRUE を返します)。これは、適切なデバイスを見つけるためにすべてのデバイスを反復処理する必要があるためです。これは、構造内の szLegacyName 値を比較する必要があります。

削除する:

IntPtr searchParam = Marshal.AllocHGlobal(searchParamString.Length);

のみを使用します。

IntPtr searchParam = Marshal.StringToBSTR(searchParamString);

そのメソッドはすでに必要なメモリを割り当てることを提供しているため (後でそのメモリ領域を解放するには、finally ブロックで Marshal.FreeBSTR() を使用することを忘れないでください)。

構造は次のようになります。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
public struct DEVMGR_DEVICE_INFORMATION 
{ 
    public UInt32 dwSize; 
    public IntPtr hDevice; 
    public IntPtr hParentDevice; 

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)] 
    public String szLegacyName; 

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
    public String szDeviceKey; 

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
    public String szDeviceName; 

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
    public String szBusName; 
} 
于 2013-01-18T15:12:28.430 に答える