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

如何在C# VSTO Outlook插件中检测右键发送创建的模态邮件项

检测Outlook MailItem是否来自“发送到->邮件收件人”操作的实现方案

核心思路

Outlook没有直接提供标记该场景的专属属性,但可以通过邮件固有特征和窗口状态间接判断结合的方式,实现可靠的场景识别。

具体实现步骤

1. 识别“发送到->邮件收件人”的邮件特征

通过Windows资源管理器的该操作创建的MailItem,存在几个稳定的特征:

  • 初始Subject(主题)为空字符串
  • 自动附加用户选中的文件,即Attachments.Count >= 1
  • BodyFormat通常为olFormatPlain或olFormatHTML(取决于Outlook默认设置)
  • SentOnBehalfOfName与当前登录的Outlook账户一致,且未被手动修改

2. 间接判断窗口的模态状态

由于Inspector没有直接暴露模态属性,可通过Windows API获取窗口状态来验证:

  • 调用GetWindowLongPtr获取窗口样式,检查是否包含WS_MODALFRAME标志
  • 或通过IsWindowEnabled判断父窗口是否被禁用(模态窗口会自动禁用父窗口)

以下是C#代码示例:

using System;
using System.Runtime.InteropServices;
using Outlook = Microsoft.Office.Interop.Outlook;

public class MailItemSourceDetector
{
    // Windows API声明
    [DllImport("user32.dll")]
    private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
    
    [DllImport("user32.dll")]
    private static extern bool IsWindowEnabled(IntPtr hWnd);
    
    private const int GWL_STYLE = -16;
    private const uint WS_MODALFRAME = 0x00010000;

    // 检测是否为“发送到->邮件收件人”创建的模态邮件
    public bool IsFromSendToMailRecipient(Outlook.MailItem mailItem, Outlook.Inspector inspector)
    {
        // 第一步:验证邮件特征
        bool matchesSendToFeatures = string.IsNullOrEmpty(mailItem.Subject) 
                                     && mailItem.Attachments.Count > 0;

        if (!matchesSendToFeatures)
            return false;

        // 第二步:验证窗口是否为模态
        IntPtr inspectorWindowHandle = new IntPtr(inspector.HWnd);
        long windowStyle = (long)GetWindowLongPtr(inspectorWindowHandle, GWL_STYLE);
        bool isModalWindow = (windowStyle & WS_MODALFRAME) != 0;

        // 可选:通过父窗口状态二次验证(增强准确性)
        // IntPtr parentWindow = GetParent(inspectorWindowHandle);
        // bool isParentDisabled = !IsWindowEnabled(parentWindow);

        return isModalWindow;
    }
}

3. 在VSTO插件中集成检测逻辑

在插件的NewInspector事件中调用检测方法:

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
    this.Application.NewInspector += Application_NewInspector;
}

private void Application_NewInspector(Outlook.Inspector inspector)
{
    if (inspector.CurrentItem is Outlook.MailItem targetMail)
    {
        var detector = new MailItemSourceDetector();
        bool isSendToMail = detector.IsFromSendToMailRecipient(targetMail, inspector);
        if (isSendToMail)
        {
            // 执行插件针对该场景的专属逻辑
            targetMail.Subject = "自动生成的主题";
        }
    }
}

注意事项

  • 建议结合多个特征判断,避免误判(比如用户手动创建空主题带附件的模态邮件)
  • Windows API调用需兼容32位/64位环境,GetWindowLongPtr是跨平台兼容的调用方式
  • 可额外检查CreationTime是否与当前时间接近,进一步过滤非目标场景

内容的提问来源于stack exchange,提问作者Cédric Boivin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 22:27:15