无法使用 MAPI 删除电子邮件



我在C#中创建了Outlook 2019加载项,并尝试使用MAPI中的DeleteMessages方法删除单个电子邮件。然而,我总是得到E_INVALIDARG作为结果(看看下面的代码(。

我检查了以下文章:https://www.codeproject.com/Articles/455823/Managed-MAPI-Part-1-Logon-MAPI-Session-and-Retriev,做了一些自己的更改,得到了下面的代码(只有IMAPIFolderHRESULT需要的代码,假设我只支持x64(。

public interface IMAPIFolder
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
HRESULT DeleteMessages(IntPtr lpMsgList, uint ulUIParam, IntPtr lpProgress, uint ulFlags);
}
public enum HRESULT
{
E_INVALIDARG = 0x80070057
}
public class EntryID
{
private byte[] id_;

public EntryID(byte[] id) 
{
id_ = id;
}
public static EntryID GetEntryID(string entryID)
{
if (string.IsNullOrEmpty(entryID))
return null;
int count = entryID.Length / 2;
StringBuilder s = new StringBuilder(entryID);
byte[] bytes = new byte[count];
for (int i = 0; i < count; i++)
{
if ((2 * i + 2) > s.Length)
return null;
string s1 = s.ToString(2 * i, 2);
if (!Byte.TryParse(s1, System.Globalization.NumberStyles.HexNumber, null as IFormatProvider, out bytes[i]))
return null;
}
return new EntryID(bytes);
}
}

到目前为止,我已经尝试过调用DeleteMessages的代码片段(项目是MailItem对象(:

1.=================

string mailItemEntryId = ((MailItem)item).EntryID
byte[] msgEntryId = EntryID.GetEntryID(mailItemEntryId).AsByteArray;
int idLen = msgEntryId.Length;
IntPtr pMsgCom = Marshal.AllocCoTaskMem(16);
Marshal.WriteInt64(pMsgCom, 1L);
IntPtr pArrayCom = Marshal.AllocCoTaskMem(16);
Marshal.WriteInt64(pMsgCom, 8, (long)pArrayCom);
Marshal.WriteInt64(pArrayCom, (long)idLen);
IntPtr entryBytesCom = Marshal.AllocCoTaskMem(idLen);
Marshal.WriteInt64(pArrayCom, 8, (long)entryBytesCom);
Marshal.Copy(msgEntryId, 0, entryBytesCom, idLen);
var mapifolder = (IMAPIFolder)((MAPIFolder)mailItem.Parent).MAPIOBJECT
var result = mapifolder.DeleteMessages(pMsgCom, 0, IntPtr.Zero, 0);

2.=================

string mailItemEntryId = ((MailItem)item).EntryID
byte[] msgEntryId = EntryID.GetEntryID(mailItemEntryId).AsByteArray;
int idLen = msgEntryId.Length;
IntPtr pMsgCom = Marshal.AllocCoTaskMem(12);
Marshal.WriteInt32(pMsgCom, 1);
IntPtr pArrayCom = Marshal.AllocCoTaskMem(12);
Marshal.WriteInt64(pMsgCom, 4, (long)pArrayCom);
Marshal.WriteInt32(pArrayCom, idLen);
IntPtr entryBytesCom = Marshal.AllocCoTaskMem(idLen);
Marshal.WriteInt64(pArrayCom, 4, (long)entryBytesCom);
Marshal.Copy(msgEntryId, 0, entryBytesCom, idLen);
var mapifolder = (IMAPIFolder)((MAPIFolder)mailItem.Parent).MAPIOBJECT
var result = mapifolder.DeleteMessages(pMsgCom, 0, IntPtr.Zero, 0);

3.================

string mailItemEntryId = ((MailItem)item).EntryID
byte[] msgEntryId = EntryID.GetEntryID(mailItemEntryId).AsByteArray;
int idLen = msgEntryId.Length;
IntPtr pMsgCom = Marshal.AllocCoTaskMem(16);
Marshal.WriteInt32(pMsgCom, 1);
IntPtr pArrayCom = Marshal.AllocCoTaskMem(16);
Marshal.WriteInt64(pMsgCom, 8, (long)pArrayCom);
Marshal.WriteInt32(pArrayCom, idLen);
IntPtr entryBytesCom = Marshal.AllocCoTaskMem(idLen);
Marshal.WriteInt64(pArrayCom, 8, (long)entryBytesCom);
Marshal.Copy(msgEntryId, 0, entryBytesCom, idLen);
var mapifolder = (IMAPIFolder)((MAPIFolder)mailItem.Parent).MAPIOBJECT
var result = mapifolder.DeleteMessages(pMsgCom, 0, IntPtr.Zero, 0);

4.=================

[StructLayout(LayoutKind.Sequential)]
public struct SBinary
{
public uint cb;
public IntPtr lpb;
public static SBinary SBinaryCreate(byte[] data)
{
SBinary b;
b.cb = (uint)data.Length;
b.lpb = Marshal.AllocHGlobal((int)b.cb);
for (int i = 0; i < b.cb; i++)
{
Marshal.WriteByte(b.lpb, i, data[i]);
}
return b;
}
}
[StructLayout(LayoutKind.Sequential)]
internal struct SBinaryArray
{
public uint cValues;
public IntPtr lpbin;
public static SBinaryArray SBinaryArrayCreate(uint length, IntPtr buffer)
{
SBinaryArray b;
b.cValues = length;
b.lpbin = buffer;
return b;
}
}
string mailItemEntryId = ((MailItem)item).EntryID
byte[] msgEntryId = EntryID.GetEntryID(mailItemEntryId).AsByteArray;
SBinary messageBin = SBinary.SBinaryCreate(msgEntryId);
IntPtr messageBinPtr = Marshal.AllocHGlobal(Marshal.SizeOf(messageBin));
Marshal.StructureToPtr(messageBin, messageBinPtr, false);
SBinaryArray messageBinArray = SBinaryArray.SBinaryArrayCreate(1, messageBinPtr);
IntPtr messageBinArrayPtr = Marshal.AllocHGlobal(Marshal.SizeOf(messageBinArray));
Marshal.StructureToPtr(messageBinArray, messageBinArrayPtr, false);
var mapifolder = (IMAPIFolder)((MAPIFolder)mailItem.Parent).MAPIOBJECT
var result = mapifolder.DeleteMessages(messageBinArrayPtr, 0, IntPtr.Zero, 0);

我还尝试使用OpenEntry(来自MAPISession(,然后使用Marshal.GetObjectForIUnknown来获得IMAPIFolder对象。结果与CCD_ 11相同,得到CCD_。知道DeleteMessages为什么返回E_INVALIDARG吗?

DeleteMesagesSBinaryArray。它的第一个元素(cValues(总是4个字节,而不是8个字节(您使用的是WriteInt64(。接下来是指向条目id的指针(如果只指定一个条目(。其大小在x86下为4字节,在x64下为8字节。使用IntPtr.Size

最新更新