0

所以我正在尝试使用上述属性获取 SMTP 地址属性。但我得到算术溢出。

基本上我在使用:

IUnknown = Marshal.GetIUnknownForObject(recipientAddress.MAPIOBJECT);
HrGetOneProp(IMAPIProperty, PR_EMS_AB_PROXY_ADDRESSES, ref pPropValue);
SPropValue propValue = (SPropValue)Marshal.PtrToStructure(pPropValue, typeof(SPropValue));
IntPtr ptrToConvert = new IntPtr(propValue.Value); //arithmetic overflow
sProperty = Marshal.PtrToStringAnsi(ptrToConvert);               

我创建的结构是:

private struct SPropValue {
public unit ulPropTag
public uint dwAlignPad
public long Value
} 

我认为问题出在结构上:http: //msdn.microsoft.com/en-us/library/bb415341.aspx

问题是,propValue.Value 真的很“长”,不适合 IntPtr,我认为该结构实际​​上是 SPropValue 结构的指针,

所以我不太确定如何使用它以及如何解决这个问题。

任何帮助将不胜感激...

** 编辑 ** 我试图从 c++ 创建一个联合 PV 类,这是联合类:

typedef union _PV
{
short int           i;          /* case PT_I2 */
LONG                l;          /* case PT_LONG */
ULONG               ul;         /* alias for PT_LONG */
float               flt;        /* case PT_R4 */
double              dbl;        /* case PT_DOUBLE */
unsigned short int  b;          /* case PT_BOOLEAN */
CURRENCY            cur;        /* case PT_CURRENCY */
double              at;         /* case PT_APPTIME */
FILETIME            ft;         /* case PT_SYSTIME */  
...
...

所以我创建了这个结构:

      [StructLayout(LayoutKind.Explicit)]
  private struct PV_Union
  {
        [FieldOffset(0)]
        public Int16            i;          /* case PT_I2 */
     [FieldOffset(0)]
         public Int32               l;          /* case PT_LONG */
     [FieldOffset(0)]
         public UInt32              ul;         /* alias for PT_LONG */
 ....

现在我得到垃圾值..

4

2 回答 2

0

所以我设法解决了!我会解释的。值实际上是联合类型,我确实到达了正确的内存区域但读错了。

当我们读取这个内存区域时,我们有以下内容:

  • 代表“值”类型和命令的 uint,我将它分成 2 个 ushorts(第一个 - 高位是返回的类型:PT_MV_TSTRINGS 等于 MV_FLAGS|PT_UNICODE(多值 + unicode 字符串)
  • dwAlignedPad 的单位
  • SWStringArray - 这是实际的“值”,它具有数组长度的 uint,后面是实际字符串数组的 uint(指向数组指针的指针)

所以我创建了以下结构并将 HrGetOneProp 读入:

private struct SMultivalueStructure
  {
     public ushort PropType; // Type of returned value
     public ushort Command; //Command we entered (PR_EMS_PROXY...)
     public uint dwAlignPad; // Reserved - usually 4 bytes of 0
     public uint stringArrayLength; // SWStringArray length
     public uint pStringArrayMemoryAddress; //SWStringArray pointer to string array
  }

所以在元帅之后

SMultivalueStructure propValue = (SMultivalueStructure)Marshal.PtrToStructure(pPropValue, typeof(SMultivalueStructure));

我创建了一个长度正确的指针数组来保存指向字符串的指针:

IntPtr[] pStrings = new IntPtr[propValue.stringArrayLength];

然后我在结构中有字符串数组的内存地址,所以我将指针复制到我刚刚创建的数组中:

Marshal.Copy(new IntPtr(propValue.pStringArrayMemoryAddress), pStrings, 0, (int)propValue.stringArrayLength);

现在我有每个字符串的内存地址数组,现在只需将其编组为字符串:

for (int i = 0; i < pStrings.Length; ++i)
   {
        string smtpTest = Marshal.PtrToStringAnsi(pStrings[i]);
   }

顺便说一句,字符串数组可以是 2 个可能的值:( http://msdn.microsoft.com/en-us/library/bb446176.aspx )

  • PT_MV_STRING8 - SLPSTRArray
  • PT_MV_UNICODE - SWStringArray

所以我添加了一个检查(针对 PropType) - 应该是 MV_FLAG | PT_STRING8 用于 ANSI 字符串,MV_FLAG | PT_UNICODE 用于 unicode,然后使用正确的 MarshalPtrToStringAnsi / Uni

我需要检查的几个问题:

  1. 在 64 位前景中 - 这段代码可以吗?还是我必须以不同的方式处理
  2. 检查每个 Outlook 版本(2003、2007、2010、2010 64 位)
于 2013-08-20T08:10:47.037 回答
0

SPropValue.value 结构是一个联合,这意味着成员相互重叠。

为什么不使用 AddressEntry.PropertyAccessor.GetProperty 来检索属性?

于 2013-08-18T17:11:49.630 回答