我缺少的有关使用MAPI发送到Outlook 2013的东西有什么特别之处?

时间:2019-02-12 00:39:34

标签: outlook mfc mapi

我正在与Visual Studio 2008一起使用Simple MAPI接口,以从应用程序发送电子邮件和附件。与Thunderbird和Outlook 6配合使用效果很好,但Outlook 2013却给我带来种种麻烦。

有两个关键问题:

1)电子邮件转到Outlook的发件箱,但在发送时又回弹(或我认为这是内部的),并显示消息“您的电子邮件帐户均无法发送给该收件人。”

  • 如果我使用正确的电子邮件地址在Outlook中撰写新邮件,则可以正常工作。我尝试了两个不同的出站SMTP帐户,这些帐户我都知道可以工作,也可以手动工作,但是使用IMAP时它们会卡住。我使用的IMAP代码没有始发者数据,因此已经破解了它,以使其正常工作(我发布的代码有点原始,因为我仍在尝试找出答案)

2)Outlook将显示“程序正在尝试代表您发送电子邮件”。

  • 我已将Outlook Trust Center的访问权限设置为“从不警告活动”,如在线帮助中所述,但问题仍然存在。我忍不住想这些可能有关吗?

我想知道Outlook 2013是否需要比我提供的更多的数据,或者我是否做出了一些曲折的假设。

注意:这些测试是在三台不同的计算机上进行的-我的主要Win 10开发计算机上的Thunderbird,XP虚拟机上的Outlook 6,另一台Windows 10计算机上的Outlook 2013。

关于代码的注释:我正在使用CPtrArrays存储调用函数传递的数据。在设置收件人时,您会看到GetAt()。

谢谢!

MapiRecipDesc sender[1];
MapiRecipDesc recipient[50];
MapiFileDesc fileDesc[20];

sender[0].ulRecipClass = MAPI_ORIG;
sender[0].lpszAddress = "me@me.net";
sender[0].lpszName = "Me";
sender[0].lpEntryID = 0;
sender[0].ulEIDSize = 0;
sender[0].ulReserved = 0;

iToCount = 0;
iIndex = 0;
while (iIndex < m_paTo.GetCount()) {
    recipient[iToCount].ulRecipClass = MAPI_TO;
    recipient[iToCount].lpszAddress = (char *) m_paTo.GetAt(iToCount);
    recipient[iToCount].lpszName = (char *) m_paTo.GetAt(iToCount);
    recipient[iToCount].lpEntryID = 0;
    recipient[iToCount].ulEIDSize = 0;
    recipient[iToCount].ulReserved = 0;
    iIndex++;
    iToCount++;
}

iIndex = 0;
while (iIndex < m_paCC.GetCount()) {
    recipient[iToCount].ulRecipClass = MAPI_CC;
    recipient[iToCount].lpszAddress = (char *) m_paCC.GetAt(iIndex);
    recipient[iToCount].lpszName = (char *) m_paCC.GetAt(iIndex);
    recipient[iToCount].lpEntryID = 0;
    recipient[iToCount].ulEIDSize = 0;
    recipient[iToCount].ulReserved = 0;
    iIndex++;
    iToCount++;
}

iIndex = 0;
while (iIndex < m_paBCC.GetCount()) {
    recipient[iToCount].ulRecipClass = MAPI_BCC;
    recipient[iToCount].lpszAddress = (char *) m_paBCC.GetAt(iIndex);
    recipient[iToCount].lpszName = (char *) m_paBCC.GetAt(iIndex);
    recipient[iToCount].lpEntryID = 0;
    recipient[iToCount].ulEIDSize = 0;
    recipient[iToCount].ulReserved = 0;
    iIndex++;
    iToCount++;
}

iFileCount = 0;
iIndex = 0;
while (iIndex < m_paAttachments.GetCount()) {
    fileDesc[iFileCount].flFlags = 0;
    fileDesc[iFileCount].lpFileType = 0;
    fileDesc[iFileCount].lpszFileName = (char *) m_paAttachments.GetAt(iIndex);
    fileDesc[iFileCount].lpszPathName = (char *) m_paAttachments.GetAt(iIndex);
    fileDesc[iFileCount].nPosition = -1;
    fileDesc[iFileCount].ulReserved = 0;
    iIndex++;
    iFileCount++;
}



TCHAR szSubject[_MAX_PATH];
TCHAR szMessage[5001];
::StrCpy(szSubject, m_sSubject);
::StrCpy(szMessage, m_sMessage);


MapiMessage message;
::ZeroMemory(&message, sizeof(message));
message.lpszSubject = szSubject;
message.nRecipCount = iToCount;
message.lpRecips = recipient;
message.nFileCount = iFileCount;
message.lpFiles = fileDesc;
message.lpszNoteText = szMessage;
message.flFlags = MAPI_SENT | MAPI_UNREAD;
message.lpszConversationID = "123";
message.lpOriginator = sender;



//int nError = SendMail(0, (ULONG_PTR)hWndParent, &message, MAPI_LOGON_UI|MAPI_DIALOG, 0);
int nError = SendMail(0, (ULONG_PTR)hWndParent, &message, MAPI_LOGON_UI, 0);

if (nError != SUCCESS_SUCCESS && 
    nError != MAPI_USER_ABORT && 
    nError != MAPI_E_LOGIN_FAILURE) {
    CString sMessage;
    CString sTest = recipient[0].lpszAddress;
    sMessage.Format("MapiMail:: SendMail Error code %d Recip count %d: first Recip: %s", nError, message.nRecipCount, sTest);
    AfxMessageBox(sMessage);
    lLog.WriteString(sMessage);
    return false;
}

1 个答案:

答案 0 :(得分:0)

根据Barmak Shemirani的建议,我发布了自己的答案。如果其他人正在寻找此信息,也许我可以通过将其张贴在一个地方来节省一些时间。

1)“您的电子邮件帐户都无法发送给该收件人”。将收件人的电子邮件地址放在收件人结构的 name 字段中的尖括号中,可以解决此问题。将地址字段留空。因此,例如

::StrCpy(szTo, "<address@email.com>");
recipient[iToCount].ulRecipClass = MAPI_TO;
recipient[iToCount].lpszAddress = 0;
recipient[iToCount].lpszName = szTo;
recipient[iToCount].lpEntryID = 0;
recipient[iToCount].ulEIDSize = 0;
recipient[iToCount].ulReserved = 0;

我已经使用Outlook 2013和2016以及Outlook 6,Thunderbird和EM Client对此进行了测试,他们对此都很满意。显然,您也可以输入名称“ PersonName”,但我尚未对此进行测试。

2)Outlook显示“程序正在尝试代表您发送电子邮件”的问题是软件配置问题。大多数网站建议使用信任中心来设置程序访问权限,以允许其他应用程序通过MAPI访问。您必须将此程序设置为以管理员身份运行该程序,但还必须以管理员身份运行Outlook才能使其正常工作

解决方法是编辑注册表并在以下位置添加值为2的DWORD PromptSimpleMAPISend:Computer \ HKEY_CURRENT_USER \ Software \ Policies \ Microsoft \ Office \ x.0 \ Outlook \ Security

3)奖励答案。如果有人想知道MAPI中的HTML,则不支持它。 MAPI显然早于HTML电子邮件的常用用法。

有一种解决方法。您可以将邮件正文保留为空白,而是将邮件以html格式放在文件中,然后将该文件作为MAPI邮件中的第一个附件。我用.html扩展名命名文件。

有点偶然-电子邮件客户端将其选中并在电子邮件正文中显示HTML。您的html文件仍将是附件,后跟任何其他附件。

我已经对Thunderbird,Outlook和EM Client进行了测试。我快速浏览了一个网络电子邮件阅读器,它没有显示html文本(尽管可以阅读附件)。