2

win32 API を使用して、C# のデバイスに関連付けられたドライバーに関する情報にアクセスしようとしています。

デバイスを有効/無効にすることができました (したがって、取得しているハンドルは問題ないように見えます) が、SetupDiEnumDriverInfo を呼び出そうとしてもうまくいきません。

これは私が使用しているコードです:

private List<String> ListCompatibleDrivers(IntPtr hDevInfo, SP_DEVINFO_DATA devInfoData)
{
   List<String> result = new List<String>();
   try
   {
      SP_DRVINFO_DATA drvInfo = new SP_DRVINFO_DATA();

      for (int i = 0; SetupDiEnumDriverInfo(hDevInfo, devInfoData, SPDIT_CLASSDRIVER, i, drvInfo); i++)
      {
         result.Add(drvInfo.Description);
      }

      if (result.Count < 1)
      {
         result.Add(Marshal.GetLastWin32Error().ToString());
      }

      return result;
   }
   catch
   {
      throw;
   }
}

パラメータが正常であると想定できる場合 (先ほど述べたように、セットアップ API の他のメソッドがそれらを正常に使用しています)。

これらは、破損している可能性のある構造体と DllImport です。

[StructLayout(LayoutKind.Sequential)]
public class SP_DRVINFO_DATA 
{
   public Int32     cbSize;
   public Int32     driverType;
   public UIntPtr    reserved;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)]
   public String    description;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)]
   public String    mfgName;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)]
   public String    providerName;
   public FILETIME   driverDate;
   public Int64  driverVersion;
};

[DllImport("setupapi.dll", SetLastError = true)]
public static extern bool SetupDiEnumDriverInfo(IntPtr lpInfoSet, SP_DEVINFO_DATA deviceInfoData, UInt32 driverType, Int32 memberIndex, SP_DRVINFO_DATA driverInfoData);

API 呼び出しはすぐに false をMarshal.GetLastWin32Error().ToString()返し259、 を返します。これはERROR_NO_MORE_ITEMSです。

私はそれを理解していません、そして私の希望は高いです.私は最近msdn以外をほとんど読んでいないので、私が見ることができないいくつかの愚かな間違いを犯しているだけで、信じられないほど疲れます.

どんな助けでも大歓迎です、どうもありがとう!

4

3 に答える 3

1

構造体にはいくつかの問題があります。最も厄介なのは、ネイティブ コードが正しいエントリ ポイントを見つけるために pack=4 を指定する必要があることです。
これは機能します:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 4)]
    public struct SP_DRVINFO_DATA
    {
        public int cbSize;
        public int DriverType;
        public UInt32 Reserved;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string Description;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string MfgName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string ProviderName;
        public System.Runtime.InteropServices.ComTypes.FILETIME DriverDate;
        public long DriverVersion;
    }

もちろん、実際に P/Invokes の前に を付けることCharset=Charset.Unicodeも素晴らしいアイデアです。

于 2013-07-02T10:34:59.823 に答える
1

一番上にあるはずの関数シグネチャと一致しないことがわかります。

[DllImport("setupapi.dll", SetLastError = true, charset=Charset.Unicode)]
[return:MarshalAs(UnmanagedType.Bool)]
private static extern bool SetupDiEnumDriverInfo(
       [In] IntPtr lpInfoSet,
       [In, Optional] SP_DEVINFO_DATA deviceInfoData,
       [In] UInt32 driverType,
       [In] Int32 memberIndex,
       [Out] out SP_DRVINFO_DATA driverInfoData);

これは、PInvoke からデータを引き出す必要があることを示しているため、重要です。

于 2013-06-27T13:55:44.600 に答える