CDONTS 是什么?它和 CDO、MAPI、Outlook 对象模型有什么区别

CDONTS 是 Windows NT 4.0 和早期 IIS 时代随系统提供的一个 SMTP 发信组件,全称 Collaboration Data Objects for Windows NT Server。它只做一件事:让 ASP 或 VB 脚本通过本机 SMTP 服务把邮件投递出去。如果你现在还在维护 2000 年代前后的老代码,看到 CreateObject("CDONTS.NewMail") 就属于它;如果是在新项目里选型,直接用 System.Net.Mail 或 CDO.Message,不要再用 CDONTS。

CDONTS 到底能做什么

CDONTS 的接口非常窄,核心就是创建一个 NewMail 对象,设置几个属性,然后调用 Send。

Set mail = CreateObject("CDONTS.NewMail")
mail.From = "[email protected]"
mail.To = "[email protected]"
mail.Subject = "测试"
mail.Body = "正文"
mail.Send

输入是收件人、发件人、主题、正文,动作是 Send,预期结果是邮件被交给本机 SMTP 服务并排队投递。它不支持附件以外的复杂 MIME 结构,不支持现代认证,也不直接操作邮箱里的邮件——它只负责“发出去”。

失败排查通常集中在两处:

  • SMTP 服务未启动或未安装:CDONTS 依赖本机 SMTP 虚拟服务器,服务停了就会报错。
  • 权限不足:运行脚本的账户(如 IIS 匿名账户 IUSR)需要对 SMTP 投递目录有写权限,否则邮件进不了队列。

CDONTS 和 CDO 不是同一套库

这是最容易混淆的地方。名字里都有 “CDO”,但面向的场景完全不同。

维度 CDONTS CDO 1.21(CDO for Exchange)
全称 Collaboration Data Objects for NTS Collaboration Data Objects 1.21
主要用途 通过 SMTP 发信 访问 Exchange/MAPI 邮箱、日历、联系人等协作数据
依赖 本机 SMTP 服务 MAPI 子系统、Exchange 或 Outlook
典型对象 CDONTS.NewMail CDO.Message、CDO.Session
是否操作邮箱内容 否,只投递 是,可读写邮件和文件夹

简单说:CDONTS 是“发信工具”,CDO 1.21 是“协作数据访问库”。两者可以都用来发邮件,但 CDO 的能力范围大得多,也更贴近 MAPI。

和 MAPI、Outlook 对象模型的分工

把这几层放在一起看,关系会清楚很多:

  • MAPI:底层消息接口,是 Outlook、Exchange 客户端和 CDO 共同依赖的基础。
  • Outlook 对象模型:在 MAPI 之上做的一层自动化接口,通过 Outlook.Application 操作,必须装有 Outlook 客户端。
  • CDO 1.21:直接基于 MAPI,可以不启动 Outlook 就访问 Exchange 数据。
  • CDONTS:完全不走 MAPI,也不依赖 Outlook,只对接本机 SMTP。

所以 CDONTS 的定位很特殊:它是这几者里唯一“不碰邮箱、只发信”的组件。这也是它在纯发信场景下曾经流行的原因——不需要装 Outlook,也不需要连 Exchange。

现在还能用吗,该换成什么

CDONTS 从 Windows Server 2003 之后就不再随系统提供了,新系统上 CreateObject("CDONTS.NewMail") 通常会直接失败。迁移时按需求选替代:

  • 只是发简单邮件:用 .NET 的 System.Net.Mail.SmtpClient,或脚本里用 CDO.Message(CDO for Windows 2000/2003 的 SMTP 版本,注意和 CDO 1.21 区分)。
  • 需要访问 Exchange 邮箱、日历、联系人:用 CDO 1.21,或更现代的 Exchange Web Services(EWS)、Microsoft Graph。
  • 需要在 Outlook 内自动化,且要绕开 Outlook 对象模型的限制:可考虑第三方 MAPI 库,例如 dimastr.com 上列出的 Outlook Redemption,它定位为“用任意语言调用 Extended MAPI”,作为 Outlook 对象模型缺失功能的实用替代。

迁移时最需要注意的是:CDONTS 的 Send 是同步投递到本机 SMTP,而新方案大多需要显式配置 SMTP 服务器地址、端口和认证。老代码里那些默认本机投递的假设,换库后往往要补上配置才能跑通。

dimastr.com