首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >获取共享Outlook日历事件C#

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

Stack Overflow用户
提问于 2018-08-19 14:21:08
回答 2查看 2.4K关注 0票数 0

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

代码语言:javascript
运行
复制
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团队中的所有用户读取日历事件(假设共享权限已被正确设置)。理想情况下,我需要能够迭代每个用户,但如果我只是获得所有事件的集合,然后可以通过用户进行查询,那也就足够了。

我能从哪里开始呢?

注意:这是使用Outlook的日历窗格来表示团队的方式。敏感的细节被修改了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-20 17:22:11

感谢@Dmitry for his answer,它帮助我解决了我的问题。然而,为了最大限度地提高这个问题对未来读者的效用,我想我会对其进行扩展。

假设:

代码语言:javascript
运行
复制
using Microsoft.Office.Interop.Outlook;

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

第一步是创建一个Outlook.Application对象,该对象充当Outlook函数的接口(您可以将它看作是整个Outlook程序的内部实例):

代码语言:javascript
运行
复制
Application app = new Application();

然后,我从与团队关联的Global列表中的通讯组列表中提取所有用户。这是通过从Recipient实例的Session属性创建Application对象来完成的。

代码语言:javascript
运行
复制
Recipient distList = app.Session.CreateRecipient(yourDistList);

从这里,我们可以提取所有的实名和用户名竞争我们的收件人的AdressEntry.Members属性。要将这两种查询都放入(string,string)的匿名元组中,我们可以使用这个LINQ查询,如果您不喜欢这个查询,可以像普通一样迭代:

代码语言:javascript
运行
复制
List<(string,string)> usersData = distList.AddressEntry.Members.Cast<AddressEntry>().Select(entry => (entry.Name,entry.Address)).ToList();

现在,给定一个特定的用户名,只要日历与curernt用户共享,就可以使用SessionSession方法访问它

代码语言:javascript
运行
复制
MAPIFolder sharedCalendar = _app.Session.GetSharedDefaultFolder(teamMember, OlDefaultFolders.olFolderCalendar);

在这一点上,我发现做一些过滤来试图避免最常见的COMException是有用的,然而,有很多我似乎无法确定原因,所以我只是catch (COMException)并将它们删除。不是很好的实践,我知道,但它似乎没有干扰我访问日历,我有权限。一些(非常)基本的过滤:

代码语言:javascript
运行
复制
if (sharedCalendar.DefaultMessageClass != "IPM.Appointment" || teamMember.DisplayType != 0)
{
    return null; //Calendar not shared.
}

现在我们必须使用Microsoft格式构建一个Filter字符串,这可以使用以下语句(其中fromto都是DateTime对象)完成:

代码语言:javascript
运行
复制
string sFilter = $"[End] > '{from:g}' AND [Start] < '{to:g}' AND [Recurring] = 'No'";

我们过滤掉重复发生的事件,否则开始日期和结束日期可能会超出范围,没有内部事件发生。就我的目的而言,无论如何,我不需要重复发生的事件,但是,如果需要的话,您将不得不单独处理这个问题。

最后,我们现在可以使用Items.Restrict()MAPIFolder方法收集我们需要的事件。

代码语言:javascript
运行
复制
Items results = sharedCalendar.Items.Restrict(sFilter);

这会将Items接口返回到过滤器中的所有项。

最后,我们可以迭代每一项(我按反向顺序迭代,因为我从删除事件的旧应用程序中复制了代码,但在这个上下文中不重要)。您可能必须将object转换为AppointmentItem,具体取决于编译器是否可以推断这一点。

代码语言:javascript
运行
复制
List<AppData> appointments = new List<AppData>();
for (int i = results.Count; i > 0; i--)
{
    appointments.Add(new AppData(results[i], username));
}

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

代码语言:javascript
运行
复制
public struct AppData
{
    public string Subject { get; }
    public DateTime From { get; }      
    public DateTime To { get; }       
    public string Location { get; }      
    public string Categories { get; }      
    public string Username { get; }
    public AppData(AppointmentItem appItem, string username)
    {
        Subject = appItem.Subject;
        From = appItem.Start;
        To = appItem.End;
        Location = appItem.Location;
        Categories = appItem.Categories;
        Username = username;
    }
}

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

代码语言:javascript
运行
复制
public class OutlookCommunicator : IDisposable
{
    private readonly Application _app;

    public OutlookCommunicator()
    {
        _app = new Application();
    }

    /// <summary>
    /// Username of the distribution list according to the GAL.
    /// </summary>
    private const string DistList = "redacted";

    /// <summary>
    /// Fetches a list of all usernames and names within the DistList.
    /// </summary>
    /// <returns>List&lt;string&gt; containing all usernames.</returns>
    public List<(string,string)> GetUsers()
    {
            Recipient warEngineering = _app.Session.CreateRecipient(DistList);
            List<(string,string)> usernames = warEngineering.AddressEntry.Members.Cast<AddressEntry>().Select(entry => (entry.Name,entry.Address)).ToList();
            return usernames;

    }



    /// <summary>
    /// Fetches all calendar events for a user falling within the provided range.
    /// </summary>
    /// <param name="from">Start search date.</param>
    /// <param name="to">End search dat.</param>
    /// <param name="username">User's calendar to search.</param>
    /// <returns></returns>
    public List<AppData> GetEventsInRange(DateTime from, DateTime to, string username)
    {
        List<AppData> appointments = new List<AppData>();
        try
        {

            Recipient teamMember = _app.Session.CreateRecipient(username);
            MAPIFolder sharedCalendar = _app.Session.GetSharedDefaultFolder(teamMember, OlDefaultFolders.olFolderCalendar);
            if (sharedCalendar.DefaultMessageClass != "IPM.Appointment" || teamMember.DisplayType != 0)
            {
                return null; //Calendar not shared.
            }

            string sFilter = $"[End] > '{from:g}' AND [Start] < '{to:g}' AND [Recurring] = 'No'";
            Items results = sharedCalendar.Items.Restrict(sFilter);
            for (int i = results.Count; i > 0; i--)
            {
                appointments.Add(new AppData(results[i], username));
            }

            return appointments;
        }
        catch (COMException)
        {
            return null;
        }
    }

    public void Dispose()
    {
        _app?.Quit();
    }
票数 1
EN

Stack Overflow用户

发布于 2018-08-19 18:10:15

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

还请记住,循环遍历文件夹中的所有项目是一个可怕的想法,特别是当您打开一个未缓存在本地OST文件中的联机文件夹时。使用Items.Find/FindNextItems.Restrict代替。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51918573

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档