You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# Outlook插件:无需发送,直接将新邮件保存至已发送文件夹

嘿,这个需求我之前帮人解决过,其实用Outlook的开发API就能轻松实现——不用真的执行发送操作,就能把新建的邮件直接存到已发送文件夹里。下面分两种主流插件开发场景给你讲清楚具体实现:

核心思路

不管用哪种技术,核心逻辑都是:先创建邮件草稿,然后手动标记它为「已发送状态」的属性,最后将它移动到已发送文件夹。这样Outlook就会把它识别为已发送的邮件,而不会触发真实的发送流程。


场景1:Office JavaScript API(网页/跨平台插件)

这是现代Outlook插件的主流开发方式,支持网页版、桌面客户端和移动端。

完整代码示例

async function createSavedSentEmail() {
  const outlook = Office.context.mailbox;

  // 第一步:创建新邮件草稿
  await Office.context.mailbox.item.addAsync(
    {
      subject: "测试已保存邮件",
      body: { content: "这是直接存到已发送文件夹的邮件内容", contentType: Office.MailboxEnums.BodyType.Html },
      toRecipients: [{ emailAddress: { address: "test@example.com", name: "测试用户" } }]
    },
    async (result) => {
      if (result.status !== Office.AsyncResultStatus.Succeeded) {
        console.error("创建草稿失败:", result.error.message);
        return;
      }

      const newMailItem = result.value;
      
      // 第二步:标记邮件为已发送状态
      await newMailItem.loadCustomPropertiesAsync(async (propsResult) => {
        const customProps = propsResult.value;
        // 设置关键属性,让Outlook识别为已发送邮件
        customProps.set("IsSubmitted", true);
        customProps.set("SentOn", new Date().toISOString());
        await customProps.saveAsync();
      });

      // 第三步:获取已发送文件夹并移动邮件
      outlook.getFolderAsync(Office.MailboxEnums.DefaultFolder.SentItems, async (folderResult) => {
        if (folderResult.status !== Office.AsyncResultStatus.Succeeded) {
          console.error("获取已发送文件夹失败:", folderResult.error.message);
          return;
        }

        await newMailItem.moveAsync(folderResult.value.id, { isCopy: false }, (moveResult) => {
          if (moveResult.status === Office.AsyncResultStatus.Succeeded) {
            console.log("邮件已成功保存到已发送文件夹!");
          } else {
            console.error("移动邮件失败:", moveResult.error.message);
          }
        });
      });
    }
  );
}

关键注意点

  • 权限配置:你的插件manifest.xml里必须声明ReadWriteMailbox权限,否则无法修改邮件属性和移动文件夹。
  • 属性作用:IsSubmitted和SentOn是让Outlook将邮件识别为已发送的核心属性,缺一不可。
  • 兼容性:支持Outlook 2016及以上桌面版本、网页版Outlook,移动端可能需要测试验证。

场景2:VSTO(.NET桌面插件)

如果是开发Windows桌面专属的Outlook插件,用VSTO会更直接。

完整代码示例(C#)

using Outlook = Microsoft.Office.Interop.Outlook;

public void CreateSavedSentEmail()
{
    Outlook.Application outlookApp = new Outlook.Application();
    Outlook.MailItem mailItem = (Outlook.MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);

    // 设置邮件基础内容
    mailItem.Subject = "VSTO测试已保存邮件";
    mailItem.Body = "这是通过VSTO直接存到已发送文件夹的邮件";
    mailItem.To = "test@example.com";

    // 标记为已发送状态
    mailItem.Sent = true;
    mailItem.SentOn = DateTime.Now;
    mailItem.Submitted = true;

    // 移动到已发送文件夹
    Outlook.Folder sentFolder = (Outlook.Folder)outlookApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
    mailItem.Move(sentFolder);

    // 释放COM对象(避免内存泄漏)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(mailItem);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(sentFolder);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(outlookApp);
}

关键注意点

  • COM对象释放:VSTO基于COM交互,必须手动释放创建的对象,否则会导致Outlook进程残留。
  • 直接属性设置:VSTO里可以直接修改Sent和Submitted属性,不需要通过自定义属性中转,比JS更简洁。

如果在配置权限、调试属性或者文件夹操作时遇到问题,随时提出来,我再帮你细化解决!

内容的提问来源于stack exchange,提问作者Tuấn Anh Phạm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:22:22