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

如何用C#实现Outlook会议请求状态自动同步至SQL数据库

用C#实现Outlook会议状态到SQL数据库的自动同步

核心思路

放弃Active Directory的方式,直接通过Outlook COM Interop或**Exchange Web Services (EWS)**监听会议请求的响应事件,捕获参会者的接受/拒绝状态,再将状态写入SQL数据库。

方法一:使用Outlook COM Interop(本地客户端监听)

适用于本地安装Outlook的场景,直接监听Outlook客户端的日历事件变化。

1. 引入依赖

通过NuGet安装Microsoft.Office.Interop.Outlook包,或在项目中添加对应的COM组件引用。

2. 编写监听与同步代码

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

namespace OutlookMeetingSync
{
    public class MeetingStatusSync
    {
        private Application _outlookApp;
        private Items _calendarItems;

        public void StartMonitoring()
        {
            _outlookApp = new Application();
            var calendarFolder = _outlookApp.Session.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
            _calendarItems = calendarFolder.Items;
            _calendarItems.ItemChange += OnCalendarItemUpdated;
            Console.WriteLine("已启动Outlook日历监听...");
        }

        private void OnCalendarItemUpdated(object item)
        {
            if (item is AppointmentItem meeting && meeting.MeetingStatus == OlMeetingStatus.olMeeting)
            {
                // 仅处理当前用户发起的会议
                if (meeting.Organizer.Address == _outlookApp.Session.CurrentUser.Address)
                {
                    foreach (Recipient attendee in meeting.Recipients)
                    {
                        string status = attendee.MeetingResponseStatus switch
                        {
                            OlMeetingResponseStatus.olResponseAccepted => "已接受",
                            OlMeetingResponseStatus.olResponseDeclined => "已拒绝",
                            OlMeetingResponseStatus.olResponseTentative => "暂定接受",
                            _ => "未响应"
                        };

                        // 同步状态到SQL
                        UpdateSqlDatabase(meeting.Subject, attendee.Name, attendee.Address, status);
                    }
                }
            }
        }

        private void UpdateSqlDatabase(string meetingTitle, string attendeeName, string attendeeEmail, string status)
        {
            // 替换为你的SQL连接字符串
            string connStr = "Data Source=你的SQL服务器;Initial Catalog=你的数据库;Integrated Security=True";
            string sql = @"
                MERGE INTO MeetingAttendeeStatus t
                USING (VALUES (@MeetingTitle, @AttendeeEmail)) s (MeetingTitle, AttendeeEmail)
                ON t.MeetingTitle = s.MeetingTitle AND t.AttendeeEmail = s.AttendeeEmail
                WHEN MATCHED THEN UPDATE SET Status = @Status, UpdateTime = GETDATE()
                WHEN NOT MATCHED THEN INSERT (MeetingTitle, AttendeeName, AttendeeEmail, Status, UpdateTime)
                VALUES (@MeetingTitle, @AttendeeName, @AttendeeEmail, @Status, GETDATE());";

            using (var conn = new System.Data.SqlClient.SqlConnection(connStr))
            {
                conn.Open();
                using (var cmd = new System.Data.SqlClient.SqlCommand(sql, conn))
                {
                    cmd.Parameters.AddWithValue("@MeetingTitle", meetingTitle);
                    cmd.Parameters.AddWithValue("@AttendeeName", attendeeName);
                    cmd.Parameters.AddWithValue("@AttendeeEmail", attendeeEmail);
                    cmd.Parameters.AddWithValue("@Status", status);
                    cmd.ExecuteNonQuery();
                }
            }
        }

        // 停止监听时释放COM对象,避免内存泄漏
        public void StopMonitoring()
        {
            _calendarItems.ItemChange -= OnCalendarItemUpdated;
            Marshal.ReleaseComObject(_calendarItems);
            Marshal.ReleaseComObject(_outlookApp);
        }
    }
}

3. 注意事项

  • 运行程序时需保持Outlook处于打开状态,或通过代码启动Outlook进程。
  • 在Outlook信任中心授予程序访问权限,避免安全拦截。
  • 务必处理COM对象的释放,防止内存泄漏。

方法二:使用Exchange Web Services (EWS)(无本地Outlook场景)

无需依赖本地Outlook客户端,直接连接Exchange服务器监听会议状态变化。

1. 引入依赖

通过NuGet安装Microsoft.Exchange.WebServices包。

2. 编写EWS订阅与同步代码

using Microsoft.Exchange.WebServices.Data;
using System;

namespace EwsMeetingSync
{
    public class EwsMeetingStatusSync
    {
        private ExchangeService _ewsService;
        private StreamingSubscriptionConnection _subscriptionConn;

        public void InitializeEws()
        {
            _ewsService = new ExchangeService(ExchangeVersion.Exchange2016);
            _ewsService.Credentials = new WebCredentials("你的邮箱账号", "你的密码");
            _ewsService.AutodiscoverUrl("你的邮箱地址", RedirectionValidator);

            // 订阅日历文件夹的修改事件
            var subscription = _ewsService.SubscribeToStreamingNotifications(
                new FolderId[] { WellKnownFolderName.Calendar },
                EventType.Modified);

            _subscriptionConn = new StreamingSubscriptionConnection(_ewsService, 30);
            _subscriptionConn.AddSubscription(subscription);
            _subscriptionConn.OnNotificationEvent += OnMeetingStatusChanged;
            _subscriptionConn.Open();
            Console.WriteLine("已通过EWS启动会议状态监听...");
        }

        private bool RedirectionValidator(string redirectUrl)
        {
            // 可添加URL安全验证逻辑,默认返回true
            return true;
        }

        private void OnMeetingStatusChanged(object sender, NotificationEventArgs args)
        {
            foreach (var notification in args.Events)
            {
                if (notification is ItemEvent itemEvent && itemEvent.ItemType == ItemType.Appointment)
                {
                    var meeting = Appointment.Bind(_ewsService, itemEvent.ItemId);
                    if (meeting.IsMeeting && meeting.Organizer.Address == "你的邮箱地址")
                    {
                        foreach (var attendee in meeting.RequiredAttendees)
                        {
                            string status = attendee.ResponseType switch
                            {
                                MeetingResponseType.Accepted => "已接受",
                                MeetingResponseType.Declined => "已拒绝",
                                MeetingResponseType.Tentative => "暂定接受",
                                _ => "未响应"
                            };

                            UpdateSqlDatabase(meeting.Subject, attendee.Name, attendee.Address, status);
                        }
                    }
                }
            }
        }

        // 同步SQL的方法与COM方式一致,可直接复用
        private void UpdateSqlDatabase(string meetingTitle, string attendeeName, string attendeeEmail, string status)
        {
            // 替换为你的SQL逻辑
        }
    }
}

3. 注意事项

  • 确保Exchange服务器开启EWS服务,且账号拥有相应的访问权限。
  • 实现订阅断开后的重连逻辑,避免丢失事件通知。

为什么不用Active Directory?

AD仅用于用户身份管理与权限控制,无法直接获取Outlook会议的实时响应状态。会议状态数据存储在Exchange服务器或本地Outlook客户端中,直接通过Outlook COM或EWS获取才是正确路径。


内容的提问来源于stack exchange,提问作者Akash A

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:23:22