【问题标题】:SetupDiEnumDriverInfo always return with Error 259 (No more Data available)SetupDiEnumDriverInfo 总是返回错误 259(没有更多可用数据)
【发布时间】:2013-06-27 13:34:34
【问题描述】:

我正在尝试使用 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;
   }
}

可以假定参数正常的地方(正如我所说,setup 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 几乎没有阅读任何东西,而且它变得非常累......

非常感谢任何帮助,非常感谢!

【问题讨论】:

  • 您是否尝试过在DllImport 上设置charset=CharSet.Unicode 标志?
  • 我试过AutoAnsiUnicode,都没有解决我的问题。不过感谢您的意见!
  • 您需要将 cbSize 设置为 SP_DRVINFO_DATA 结构的大小。
  • 好收获!我调整了!但是,这仍然不能解决问题。非常感谢!

标签: c# c++ windows winapi driver


【解决方案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 中提取数据。

【讨论】:

  • 谢谢,这肯定是我的代码有问题的一件事!但是,它并没有解决我的问题。不过,感谢您的努力!
  • 枚举是否可能为空?您是否尝试过一个小型非托管控制台应用程序进行测试?
  • 我针对 DevCon 工具进行测试——我相信他们使用相同的 API,而且我知道对于我正在测试的设备,肯定有多个驱动程序实例可用。
  • 看来你的结构也有问题,我已经根据 MSDN 更新了答案
  • 我相信你混淆了 SP_DEVINFO_DATA 和 SP_DRVINFO_DATA
【解决方案2】:

这个结构有几个问题,最烦人的是必须指定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 也是一个不错的主意。

【讨论】:

    【解决方案3】:

    以下是在 x64 和 x86 上都适用的 API 和结构定义。我还添加了 SetupDiGetDriverInfoDetail,很有可能您也需要它。

    API:

    DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
           public static extern bool SetupDiGetDriverInfoDetail(
           IntPtr DeviceInfoSet,
           ref SP_DEVINFO_DATA DeviceInfoData,
           ref SP_DRVINFO_DATA DriverInfoData,
           ref SP_DRVINFO_DETAIL_DATA DriverInfoDetailData,
           Int32 DriverInfoDetailDataSize,
           ref Int32 RequiredSize);
    
    [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
            public static extern bool SetupDiEnumDriverInfo( 
            IntPtr DeviceInfoSet,  
            ref SP_DEVINFO_DATA DeviceInfoData,  
            int DriverType,  
            int MemberIndex,                                          
            ref SP_DRVINFO_DATA DriverInfoData); 
    

    结构:

    #if !WIN64
     [StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Unicode)]
    #else  
     [StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Unicode)]
    #endif
            public struct SP_DRVINFO_DATA 
            { 
                public int cbSize; 
                public uint 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 System.Runtime.InteropServices.ComTypes.FILETIME DriverDate; 
                public ulong DriverVersion; 
           }
    
    
    #if !WIN64
     [StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Unicode)]
    #else  
     [StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Unicode)]
    #endif
            public struct SP_DRVINFO_DETAIL_DATA
            {
                public Int32 cbSize;
                public System.Runtime.InteropServices.ComTypes.FILETIME InfDate;
                public Int32 CompatIDsOffset;
                public Int32 CompatIDsLength;
                public IntPtr Reserved;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
                public String SectionName;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
                public String InfFileName;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
                public String DrvDescription;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)]
                public String HardwareID;
            };
    

    【讨论】:

      猜你喜欢
      • 2014-12-22
      • 1970-01-01
      • 2011-01-28
      • 2011-06-21
      • 2012-02-26
      • 2014-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多