最近,使用MAPI32.DLL提供的MAPISendMail发送邮件,在Foxmail可以成功,在Outlook始终不成功,怎么看、反复尝试都没试出代码问题。这时一个细节吸引了我的注意,把程序填充的地址删掉,手动填上去尽然可以发送成功,这样我就怀疑我给MapiRecipDesc填充收件人地址是否有什么问题,检查了代码,很正常呀,XXX@xxx.com,这怎么不行呢?再去MSDN查了一下,https://msdn.microsoft.com/en-us/library/windows/desktop/dd296720(v=vs.85).aspx。原来需要加上SMTP:,比如刚才的正确地址是SMTP:XXX@xxx.com。MSDN原文解释如下:

MapiRecipDesc structure

lpszAddress

Optional pointer to the recipient or sender's address; this address is provider-specific message delivery data. Generally, the messaging system provides such addresses for inbound messages. For outbound messages, the lpszAddress member can point to an address entered by the user for a recipient not in an address book (that is, a custom recipient).

The format of the address is address type:email address. Examples of valid addresses are FAX:206-555-1212 and SMTP:M@X.COM.

fuck!太坑了。

附MAPI发送邮件代码:

#include <MAPI.h>
#include <atlstr.h>
#include <shellapi.h>#define UTILITY_DLL_DECLARRE DECLARE_EXPORT
#define OPERATE_OK                          0
#define OPERATE_FAIL                        -1
#define OPERATE_INPUT_PARAM_ERROR           -2/************************************
* @method:    startProcess
* @brief: 启动进程
* @param: const chConstStringA& strAppPath 可执行程序全路径
* @param: const chConstStringA& strParams 参数
* @param: DWORD& exitCode 应用返回码
* @param: DWORD dwCreationFlag
* @param: bool bWaitProcessFinished 是否等待进程结束
* @return:   extern int
* @retval: 没有找到则返回UC_ERROR_ID
*/
UTILITY_DLL_DECLARRE bool startProcess(const chConstStringA& strAppPath, const chConstStringA& strParams, DWORD& exitCode, DWORD dwCreationFlag = 0, bool bWaitProcessFinished = false);#define SEND_MAIL_LOAD_LIB_FAIL             -3
#define SEND_MAIL_MEMORY_FAIL               -4
#define SEND_MAIL_LOAD_FUNC_FAIL            -5
#define SEND_MAIL_LOGON_FAIL                -6//邮箱附件
struct MailAttachment
{chStringA sFileName;                            ///< 文件名chStringA sFileFullPath;                        ///< 文件全路径
};//邮件接收者类型
enum MailReciptType
{MAIL_TO = 1,                                    ///< 收件人MAIL_CC                                         ///< 抄送者 (copy recipt)
};//邮件接收者信息
struct MailRecipInfo
{chStringA sName;                                ///< 接收者名字    chStringA sAddress;                             ///< 接收者邮箱地址MailReciptType eType;                           ///< 接收者类型
};//邮件信息
struct MailInfo
{chStringA sSubject;                             ///< 主题chStringA sNoteText;                            ///< 正文chStringA sSenderAddr;                          ///< 发送者邮箱地址 (lpOriginator)chObjList<MailRecipInfo> lstRecips;             ///< 接收者(含收件人和抄送者)chObjList<MailAttachment> lstAttachs;           ///< 附件
};/************************************
* @method:   sendMail
* @brief: 发送邮件
* @param: const MailInfo& mailInfo  邮件信息
* @return:   int
* @retval: 操作结果 0--成功;其余值失败
*/
UTILITY_DLL_DECLARRE int sendMail(const MailInfo& mailInfo);bool startProcess(const chConstStringA& strAppPath, const chConstStringA& strParams, DWORD& exitCode, DWORD dwCreationFlag /* = 0*/, bool bWaitProcessFinished /*= false*/)
{STARTUPINFOW si;PROCESS_INFORMATION pi;bool bRet = false;ZeroMemory(&si, sizeof(si));si.cb = sizeof(si);ZeroMemory(&pi, sizeof(pi));chStringA strCmd;strCmd.Format("\"%s\" %s", strAppPath.c_str(), strParams.c_str());chStringW strCmdW = chUTF82W(strCmd);if (CreateProcessW(NULL, strCmdW.data(), NULL, NULL, FALSE, dwCreationFlag, NULL, NULL, &si, &pi) == TRUE){bRet = true;if (bWaitProcessFinished){HANDLE hProcess;CloseHandle(pi.hThread);hProcess = pi.hProcess;//等待进程返回;if (hProcess != 0){exitCode = 0;WaitForSingleObject(hProcess, INFINITE);if (!GetExitCodeProcess(hProcess, &exitCode)){exitCode = 1;}CloseHandle(hProcess);}}}else{chWARNINGx(false, "Fail create process [%s]", strAppPath.c_str());}return bRet;
}int sendMail(const MailInfo& mailInfo)
{int iRet = OPERATE_OK;if (!mailInfo.lstRecips.size()){return OPERATE_INPUT_PARAM_ERROR;}//装入MAPI32.DLL动态库HMODULE hMod = LoadLibrary("MAPI32.DLL");if (hMod == NULL){chWARNINGx(false, "LoadLibrary MAPI32.DLL fail");return SEND_MAIL_LOAD_LIB_FAIL;}//获取邮件相关的函数地址LPMAPILOGON lpMapiLogon = (LPMAPILOGON)::GetProcAddress(hMod, "MAPILogon");LPMAPISENDMAIL lpMapiSendMail = (LPMAPISENDMAIL)::GetProcAddress(hMod, "MAPISendMail");LPMAPILOGOFF lpMapiLogoff = (LPMAPILOGOFF)::GetProcAddress(hMod, "MAPILogoff");if (NULL == lpMapiLogon || NULL == lpMapiSendMail || NULL == lpMapiLogoff){chWARNINGx(false, "Fail get mail proc addr ");FreeLibrary(hMod);return SEND_MAIL_LOAD_FUNC_FAIL;}LHANDLE hMapiSession = 0;ULONG status = 0; status = lpMapiLogon(NULL, NULL, NULL, MAPI_LOGON_UI | MAPI_PASSWORD_UI, NULL, &hMapiSession);if (status != SUCCESS_SUCCESS){chWARNINGx(false, "Fail MAPILogon code:%X", status);FreeLibrary(hMod);return SEND_MAIL_LOGON_FAIL;}//分配内存保存附件信息MapiFileDesc*        pAttachments = NULL;int nAttachments = mailInfo.lstAttachs.size();if (nAttachments > 0){pAttachments = new MapiFileDesc[nAttachments];if (!pAttachments){chWARNINGx(false, "Error allocating memory for pAttachments");FreeLibrary(hMod);return SEND_MAIL_MEMORY_FAIL;}}//添加附件int nIndex = 0;int nValidAttachments = 0;for (const chObjList<MailAttachment>::iterator it = mailInfo.lstAttachs.begin();it != mailInfo.lstAttachs.end() && it.hasData(); ++it, nIndex++){const MailAttachment& attach = *it;if (attach.sFileFullPath.empty()){chWARNINGx(false, "Empty attachment full path,skip");continue;}pAttachments[nIndex].ulReserved = 0;pAttachments[nIndex].flFlags = 0;pAttachments[nIndex].nPosition = 0xFFFFFFFF;pAttachments[nIndex].lpszPathName = (LPSTR)attach.sFileFullPath.c_ptr();pAttachments[nIndex].lpszFileName = (LPSTR)(attach.sFileName.empty() ? attach.sFileFullPath.c_ptr() : attach.sFileName.c_ptr());pAttachments[nIndex].lpFileType = NULL;nValidAttachments++;}//邮件发送者MapiRecipDesc*       pSender = NULL;if (!mailInfo.sSenderAddr.empty()){pSender = new MapiRecipDesc;if (!pSender){chWARNINGx(false, "Error allocating memory for pSender");FreeLibrary(hMod);if (pAttachments){delete[] pAttachments;pAttachments = NULL;}return SEND_MAIL_MEMORY_FAIL;}pSender->ulReserved = 0;pSender->ulRecipClass = MAPI_ORIG;pSender->lpszAddress = (LPSTR)mailInfo.sSenderAddr.c_ptr();pSender->lpszName = (LPSTR)mailInfo.sSenderAddr.c_ptr();pSender->ulEIDSize = 0;pSender->lpEntryID = NULL;}//邮件接收者int nRecips = mailInfo.lstRecips.size();MapiRecipDesc*       pRecipients = new MapiRecipDesc[nRecips];if (!pRecipients){chWARNINGx(false, "Error allocating memory for pRecipients");FreeLibrary(hMod);if (NULL == pAttachments){delete[] pAttachments;pAttachments = NULL;}if (NULL == pSender){delete pSender;pSender = NULL;}return SEND_MAIL_MEMORY_FAIL;}// 设置收件人int nValidRecips = 0;size_t i = 0;for (const chObjList<MailRecipInfo>::iterator recipIt = mailInfo.lstRecips.begin(); recipIt != mailInfo.lstRecips.end() && recipIt.hasData(); ++recipIt, i++){const MailRecipInfo& recipInfo = *recipIt;if (recipInfo.sAddress.empty()){chWARNINGx(false, "Empty recip address,skip");continue;}pRecipients[i].ulReserved = 0;pRecipients[i].ulRecipClass = (recipInfo.eType == MAIL_TO) ? MAPI_TO : MAPI_CC;pRecipients[i].lpszAddress = (LPSTR)recipInfo.sAddress.c_str();pRecipients[i].lpszName = (LPSTR)(recipInfo.sName.empty() ? recipInfo.sAddress.c_str() : recipInfo.sName.c_str());pRecipients[i].ulEIDSize = 0;pRecipients[i].lpEntryID = NULL;nValidRecips++;}//邮件结构信息MapiMessage message;memset(&message, 0, sizeof(message));message.lpszSubject = (LPSTR)mailInfo.sSubject.c_ptr();           //主题message.lpszNoteText = (LPSTR)mailInfo.sNoteText.c_ptr();         //正文内容if (NULL != pSender){message.lpOriginator = pSender;                               //发送者}message.nFileCount = nValidAttachments;                           //附件个数message.lpFiles = nValidAttachments ? pAttachments : NULL;        //附件信息message.nRecipCount = nValidRecips;                               //接收者个数message.lpRecips = nValidRecips ? pRecipients : NULL;             //接收者信息//发送邮件int nError = lpMapiSendMail(hMapiSession, 0, &message, MAPI_DIALOG, 0);if (nError != SUCCESS_SUCCESS){//错误提示信息WARNING_TRACE("SendMail failed:%d", nError);iRet = OPERATE_FAIL;}lpMapiLogoff(hMapiSession, NULL, 0, 0);//释放分配的内存if (pAttachments){delete[] pAttachments;pAttachments = NULL;}if (pSender){delete pSender;pSender = NULL;}if (pRecipients){delete[] pRecipients;pRecipients = NULL;}FreeLibrary(hMod);return iRet;
}


使用MAPI的MAPISendMail发送邮件碰到的巨大的坑相关推荐

  1. firefox 中碰到的一个小坑

    情况描述: 在一个处于正常文档流的div中,里面有一部分文字,还有个有浮动的块, 上代码 HTML: <div class="container">    this i ...

  2. UiPath模拟浏览器登录qq邮箱并发送邮件方法与遇到的坑

    首先简述要用到的组件和流程. 流程: 1.浏览器打开qq邮箱地址https://mail.qq.com 2.在输入框输入账号密码 3.点击登录 4.点击写信 5.输入标题 内容 收件人 点击发送 用到 ...

  3. php面试题遇到的坑,PHP面试题碰到的几个坑。面壁ing

    PHP面试题遇到的几个坑....面壁ing 1.指针悬挂问题 $array = [1, 2, 3]; echo implode(',', $array), "\n"; foreac ...

  4. mapi java_使用 MAPI 实现邮件发送

    使用 MAPI 实现邮件发送 原 作:deltacat 创 建:2004.09.16 最后更新:2004.11.01 版权声明:作者保留版权.转载时敬请保持文档及说明的完整性. 关键字: Visual ...

  5. 利用MAPI实现电子邮件功能

    利用MAPI实现电子邮件功能 在VB.VC中进行面向Internet的开发应用,是近期许多程序员关注的热点. 随着办公自动化应用软件水平的提高和Intranet的流行,越来越多的办公自动化系统中都采用 ...

  6. linux下使用mail定时发送邮件-阿里企业邮箱发送

    一 背景介绍 文章需求: 编写脚本从数仓里提取数据,并将数据表格通过阿里企业邮箱发送给指定人员,这里主要讲下,使用mail命令发送邮件时遇到的一些坑. 个人公众号:放纵的Coder 有疑问请联系我 二 ...

  7. [AX2012]发送广播邮件

    AX 2012可以使用MAPI或者SMTP发送邮件,MAPI是客户端方法,需要outlook的协作,而SMTP则是服务器端方法,要求SMTP允许AOS服务器通过它中继.这里要讲的就是如何通过SMTP发 ...

  8. STM32单片机真的落后?

    一般这样认为的,只能说对单片机这个行业一无所知. 我用STM32做过的产品超过13款,占据了大部分. 我从两个方面来分析下现在STM32到底落不落后,太学术化的东西我不讲,保证小白都能听懂! 1.市场 ...

  9. 老大吩咐的可重入分布式锁,终于完美的实现了~

    重做永远比改造简单 最近在做一个项目,将一个其他公司的实现系统(下文称作旧系统),完整的整合到自己公司的系统(下文称作新系统)中,这其中需要将对方实现的功能完整在自己系统也实现一遍. 旧系统还有一批存 ...

最新文章

  1. Selenium的简单操作
  2. SQL Server 中关于 @@error 的一个小误区
  3. HTML语言怎么晋升,学会提问,对你的职场晋升有很大的帮助
  4. 026-微软Ajax异步组件
  5. java课后习题_【整理】java私塾教程课后习题
  6. 小白入坑 Web 渗透测试必备指南
  7. IIS6.0不支持ASP的解决办法
  8. JavaScript提高:006:ASP.NET使用easyUI TABS标签updatepanel
  9. Linux编程中 #define _XOPEN_SOURCE的作用
  10. C++11常用特性的使用经验总结-概述及目录
  11. fluentmigrator连接mysql_如何利用FluentMigrator实现数据库迁移
  12. 车金融|合同中心系统的前世今生
  13. “白嫖”时代进入最后倒计时,网盘行业到底是怎么由盛及衰的?
  14. hdu11601087
  15. 一键root+android+5.0,360一键rootv5.0.0最新版
  16. python爬取东方财富网资金流向数据(在本地生成csv文件)
  17. \t\t健康生活:20个健康小细节隐藏大危害!
  18. 国产内存真的来了:紫光可提供DDR3、DDR4内存芯片
  19. Android RxJava应用:优雅实现网络请求轮询(无条件)
  20. Python 一键获取全国市县级行政单元Shapefile文件

热门文章

  1. vue中加载loading
  2. 魅族18系列miui14刷入教程
  3. 国防科技大学计算机学院窦强,国防科技大学
  4. 光圈倒闭背后的启示------什么样的直播平台可以存活?
  5. FPGA基础设计(11)Verilog任务、函数、系统任务、系统函数
  6. 以下工具能够翻译日语文字
  7. 整理了60个 Python 实战例子,拿来即用
  8. (Oracle踩坑指南)项目建立连接的各种坑 ORA-12541: TNS: 无监听程序等等
  9. Android Bluetooth(蓝牙) - 概念和框架
  10. php推荐笔记本,2016笔记本买什么牌子好?8款3000左右的笔记本强烈推荐