32位与64位版本类型的条件编译的首选方法

Abe*_*bel 5 .net c# pinvoke interop marshalling

我需要某个任务来枚举系统中的所有句柄.到目前为止,我发现的最好的方法是使用underdocumented NtQuerySystemInformationwith SystemHandleInformationclass参数.

到现在为止还挺好.但是,在64位Windows上以32位模式运行它,所需的结构如下:

// 32-bit version
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct SYSTEM_HANDLE_INFORMATION
{
    public uint ProcessID;               
    public byte ObjectTypeNumber;       
    public byte Flags;                  
    public ushort Handle;               
    public uint Object_Pointer;       
    public UInt32 GrantedAccess;        
}
Run Code Online (Sandbox Code Playgroud)

而对于64位Windows(x64,我没有测试Itanium,我希望没有什么不同......),结构如下:

// 64-bit version
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct SYSTEM_HANDLE_INFORMATION
{
    public int Reserved;            // unknown, no documentation found
    public uint ProcessID;               
    public byte ObjectTypeNumber;       
    public byte Flags;                  
    public ushort Handle;               
    public long Object_Pointer;       
    public UInt32 GrantedAccess;        
}
Run Code Online (Sandbox Code Playgroud)

现在,我应该改变Object_PointerIntPtr.我希望我能做同样的事情ProcessId,有一个参考说这实际上是一个HANDLE实际上是64位的值.但是,Reserved总是为零,所以我不能IntPtr以相同的方式合并它.

这可能不是发生这种情况的唯一情况.我正在寻找处理这些差异的最佳实践方法:

  • #if WIN32除非我想维护单独的二进制文件,否则使用常量like (在IntPtr的引用源内部使用)将不起作用.
  • 我可以编写两个不同的函数和两个不同的结构,创建一个包装器并if IntPtr.Size ==4在代码中使用.这适用于外部函数,但不适用于类型.
  • 我可以超载,GetType但我不确定它在哪里引导(可能有助于编组?).
  • 还要别的吗?

这些都不是理想的,但到目前为止,唯一万无一失的方法似乎就是用if IsWin64()声明给我的系统加油.我希望听到比我更好的方法.

lep*_*pie 2

鉴于 IntPtr 的大小不同,为什么不尝试以下操作:

[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct SYSTEM_HANDLE_INFORMATION
{
    public IntPtr ProcessID;               // mask with 0xffffffff
    public byte ObjectTypeNumber;       
    public byte Flags;                  
    public ushort Handle;               
    public IntPtr Object_Pointer;          // again good for 32/64bit
    public UInt32 GrantedAccess;        
}
Run Code Online (Sandbox Code Playgroud)

这应该适用于未更改的 32 位和 64 位。