我有一个Windows应用程序,它执行一个简单的例程来确定是否存在USB令牌。该方法始终在32位计算机上正常工作,但在64位计算机上进行测试时,我们开始看到意外结果。
我正在调用以下方法
[StructLayout(LayoutKind.Sequential)]
internal struct SP_DEVINFO_DATA
{
public Int32 cbSize;
public Guid ClassGuid;
public Int32 DevInst;
public UIntPtr Reserved;
};
[DllImport("setupapi.dll")]
internal static extern Int32 SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, Int32 MemberIndex, ref SP_DEVINFO_DATA DeviceInterfaceData);
SP_DEVINFO_DATA结构的文档告诉我们 cbSize 是 SP_DEVINFO_DATA结构的大小(以字节为单位)。
如果我们为32位计算机计算cbSize,那么对于64位计算机,它将为28和32。
我已经通过使用不同的cbSize值重新编译在两台机器上对此进行了测试,我想知道的是如何将其计算为运行时?我的应用程序需要在两种架构上运行。
internal static Int32 GetDeviceInfoData(Int32 iMemberIndex)
{
_deviceInfoData = new Win32DeviceMgmt.SP_DEVINFO_DATA
{
cbSize = ?? // 28 When 32-Bit, 32 When 64-Bit,
ClassGuid = Guid.Empty,
DevInst = 0,
Reserved = UIntPtr.Zero
};
return Win32DeviceMgmt.SetupDiEnumDeviceInfo(_deviceInfoSet, iMemberIndex, ref _deviceInfoData);
}
由于
罗汉
答案 0 :(得分:9)
使用Marshal.SizeOf:
_deviceInfoData = new Win32DeviceMgmt.SP_DEVINFO_DATA
{
cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(Win32DeviceMgmt.SP_DEVINFO_DATA);
// etc..
}
答案 1 :(得分:1)
IntPtr
的大小在32和64上发生变化
尝试
cbsize = IntPtr.Size == 4 ? 28 : 32
编辑:更正为IntPtr.Size,但我更喜欢汉斯'System.Runtime.InteropServices.Marshal.SizeOf(typeof(Win32DeviceMgmt.SP_DEVINFO_DATA);
,因为没有神奇的数字。不知道那里有。
答案 2 :(得分:1)
为什么不Environment.Is64BitOperatingSystem
或Environment.Is64BitProcess
。
答案 3 :(得分:0)
看起来像对齐问题。
尝试设置Pack属性。
修改的
我查了一下:http://www.pinvoke.net/default.aspx/Structures/SP_DEVINFO_DATA.html
它说:
在32位平台上,所有SetupApi 结构是1字节包装。在64位 SetupApi结构的平台 8字节打包。 IE为32位 对于64位,SP_DEVINFO_DATA.cbSize = 28 SP_DEVINFO_DATA.cbSize =(28 + 4)= 32.SP_DEVINFO_DATA.cbSize =(28 + 4)= 32。