我尝试在64位架构上从SetupDiEnumDeviceInterfaces中调用Window API函数C#。我导入函数并声明其他结构。
[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern bool SetupDiEnumDeviceInterfaces(
IntPtr deviceInfoSet,
SP_DEVINFO_DATA deviceInfoData,
ref Guid interfaceClassGuid,
int memberIndex,
SP_DEVICE_INTERFACE_DATA deviceInterfaceData);
[StructLayout(LayoutKind.Sequential)]
internal class SP_DEVINFO_DATA
{
internal int cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
internal Guid classGuid = Guid.Empty; // temp
internal int devInst = 0; // dumy
internal int reserved = 0;
}
[StructLayout(LayoutKind.Sequential, Pack = 2)]
internal struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
internal int cbSize;
internal short devicePath;
}然后,我按如下方式调用此函数:
int index = 0;
Guid _classGuid = Guid.Empty;
IntPtr _deviceInfoSet = IntPtr.Zero;
Native.SP_DEVICE_INTERFACE_DATA interfaceData = new Native.SP_DEVICE_INTERFACE_DATA();
if (!Native.SetupDiEnumDeviceInterfaces(_deviceInfoSet, null, ref _classGuid, index, interfaceData))
{
int error = Marshal.GetLastWin32Error();
if (error != Native.ERROR_NO_MORE_ITEMS)
throw new Win32Exception(error);
break;
}如果在32位架构上运行,那么一切都很好。
如果在64位架构上运行,那么SetupDiEnumDeviceInterfaces返回false,最后一次win错误等于1784。原因是在struct interfaceData字段中,cbSize没有64位体系结构的有效值(作为int别名Int32)。
来自官方文件
一个指向调用方分配缓冲区的指针,该缓冲区在成功返回时包含一个完整的DeviceInterfaceData结构,该结构标识满足搜索参数的接口。调用方必须在调用此函数之前将DeviceInterfaceData.cbSize设置为SP_DEVICE_INTERFACE_DATA。
尝试替换Int64类型的int(别名Int64)类型,用于字段: cbSize、devInt、保留。
如何将Guid类替换为64位体系结构?
如果我尝试简单地替换long类型的Guid:
[StructLayout(LayoutKind.Sequential)]
internal class SP_DEVICE_INTERFACE_DATA
{
internal Int64 cbSize = Marshal.SizeOf(typeof(SP_DEVICE_INTERFACE_DATA));
internal long interfaceClassGuid = 0; // temp
internal Int64 flags = 1;
internal Int64 reserved = 0;
}有了这样的结构定义,所有的功能都可以使用,但我失去了使用guid特殊类的方便。在类定义中,Guid还使用int类型,因此在64位体系结构上不会计算合适的大小。
发布于 2015-01-31 16:49:23
您可以尝试设置您的
[StructLayout(LayoutKind.Sequential, Pack = 2)]
internal struct SP_DEVICE_INTERFACE_DETAIL_DATA至:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct SP_DEVICE_INTERFACE_DETAIL_DATA据我所读,Pack =8表示32位,Pack =1表示64位。
发布于 2014-11-10 19:35:20
问题不是您的GUID声明;SetupDiEnumDeviceInterfaces在64位平台上失败的原因是您没有在每个SP_DEVINFO_DATA和SP_DEVICE_INTERFACE_DATA上为reserved字段使用正确的数据类型。
SP_DEVINFO_DATA和SP_DEVICE_INTERFACE_DATA的结构定义表明,reserved字段被声明为UINT_PTR,这是一个指针类型。这些应该在您的P/Invoke类型中声明为IntPtr。
(而且,您的所有int字段都应该定义为uint,因为这些字段映射到DWORD本机类型。)
[StructLayout(LayoutKind.Sequential)]
internal class SP_DEVINFO_DATA
{
internal uint cbSize = (uint)Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
internal Guid classGuid;
internal uint devInst;
internal IntPtr reserved;
}
[StructLayout(LayoutKind.Sequential, Pack = 2)]
internal struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
internal uint cbSize;
internal short devicePath;
}
[StructLayout(LayoutKind.Sequential)]
internal class SP_DEVICE_INTERFACE_DATA
{
internal uint cbSize = (uint)Marshal.SizeOf(typeof(SP_DEVICE_INTERFACE_DATA));
internal Guid interfaceClassGuid;
internal uint flags;
internal IntPtr reserved;
}https://stackoverflow.com/questions/26851236
复制相似问题