获取共享的Outlook日历事件C#

时间:2018-08-19 14:21:09

标签: c# outlook calendar office-interop

我知道如何在当前用户的Outlook日历中检索事件,例如,以下代码可删除与特定模式匹配的项目:

private void RemoveAppointments()
        {
            Outlook.Application outlook = new Outlook.Application();
            Outlook.MAPIFolder calendarFolder = outlook.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
            Outlook.Items outlookCalendarItems = calendarFolder.Items;
            for (int i = outlookCalendarItems.Count; i > 0; i--)
            {
                if (outlookCalendarItems[i].Subject.Contains("On Call: Regions:") && outlookCalendarItems[i].Start.Year == _year)
                {
                    outlookCalendarItems[i].Delete();
                }
            }
        }

但是,我现在需要能够从Outlook Team中的所有用户读取日历事件(假设共享权限已正确设置)。理想情况下,我需要能够对每个用户进行迭代,但是如果我只是获得所有事件的集合,然后可以按用户查询就足够了。

我可以从哪里开始的任何想法?


注意:这是在Outlook的“日历”窗格中代表团队的方式。修改了敏感细节。

Calendar Section Bar

2 个答案:

答案 0 :(得分:1)

使用Namespace.GetDefaultFolder而不是使用Namespace.GetSharedDefaultFolder,而是传递从Recipient返回的Namespace.CreateRecipient对象。

还请记住,循环遍历文件夹中的所有所有是一个可怕的想法,尤其是当您打开未缓存在本地OST文件中的在线文件夹时。请改用Items.Find/FindNextItems.Restrict

答案 1 :(得分:0)

感谢@Dmitry的his answer帮助我解决了问题。但是,为了使该问题对将来的读者有用,我认为我会对此进行扩展。


假设:

using Microsoft.Office.Interop.Outlook;

,并且引用了COM程序集Microsoft Outlook 16.0 Object Library


第一步是创建一个Outlook.Application对象,该对象充当Outlook功能的接口(您可以将其视为完整Outlook程序的内部实例):

Application app = new Application();

然后,我从与团队相关联的全局地址列表中的分发列表中拉出所有用户。这是通过从Recipient实例的Session属性创建一个Application对象来完成的。

Recipient distList = app.Session.CreateRecipient(yourDistList);

在这里,我们可以提取所有实名和用户名,以显示收件人的AdressEntry.Members属性。要将这两者都放入(string,string)的匿名元组中,我们可以使用此LINQ查询,如果您不喜欢,则可以像平常一样进行迭代:

List<(string,string)> usersData = distList.AddressEntry.Members.Cast<AddressEntry>().Select(entry => (entry.Name,entry.Address)).ToList();

现在,给定特定的用户名,只要日历已与当前用户共享,就可以使用GetSharedDefaultFolder()的{​​{1}}方法访问它:

Session

在这一点上,我发现进行一些过滤以尝试避免最常见的MAPIFolder sharedCalendar = _app.Session.GetSharedDefaultFolder(teamMember, OlDefaultFolders.olFolderCalendar); 很有用,但是我似乎无法确定很多原因,所以我只是COMException然后把它们收起来我知道这不是一个好习惯,但似乎并没有干扰我访问我有权使用的日历。一些(非常)基本的过滤:

catch (COMException)

现在我们必须使用Microsoft Outlook格式构建一个if (sharedCalendar.DefaultMessageClass != "IPM.Appointment" || teamMember.DisplayType != 0) { return null; //Calendar not shared. } 字符串,这可以使用以下语句来完成(其中Filterfrom都是to对象):

DateTime

我们会过滤掉重复发生的事件,否则开始日期和结束日期可能会超出范围而没有内部发生。出于我的目的,无论如何我都不需要重复发生的事件,但是,如果您这样做,则必须将其单独处理。

最后,我们现在可以使用string sFilter = $"[End] > '{from:g}' AND [Start] < '{to:g}' AND [Recurring] = 'No'"; 的{​​{1}}方法收集所需的事件:

Items.Restrict()

这将返回一个MAPIFolder界面,用于我们过滤器中的所有项目。

最后,我们可以迭代每个项目(我以相反的顺序进行迭代,因为我从我的旧应用程序中复制了删除事件的代码,但是在这种情况下这无关紧要)。您可能必须将Items results = sharedCalendar.Items.Restrict(sFilter); 强制转换为Items,具体取决于编译器是否可以推断出这一点。

object

我将每个事件存储为AppointmentItem结构,仅保留我需要的数据:

List<AppData> appointments = new List<AppData>();
for (int i = results.Count; i > 0; i--)
{
    appointments.Add(new AppData(results[i], username));
}

所有这些都会导致一个看起来像这样的类:

AppData