如何在outlook中识别特定的约会项目

本文关键字:约会 项目 识别 outlook | 更新日期: 2023-09-27 18:00:57

我们面临的问题是,我们需要在outlook中识别特定的约会,即使它是定期约会。但由于GlobalAppointmentID对于整个重复出现的系列来说是唯一的,我们不知道该怎么做。

据我所知,当一个约会是定期约会时,它没有特定的唯一ID。因此,我们认为我们通过将Ticks中的Start Time添加到GlobalAppointmentID来生成自己的ID,但我们需要/希望将此新ID保存在约会对象中(因为StartTime可能会更改(。

我的问题是:有没有一种方法可以识别特定的约会?如果没有,我如何在特定的约会中保存一个值,这个值对每个收件人来说都是随时可访问和最新的?

//编辑:更具体一点:我们有一个outlook插件,可以将文件上传到我们的服务器,该插件必须映射到特定的约会(以及所有收件人(。对于正常的单次会议,我们只需要GlobalAppointmentID。如果是定期约会,则仍需要将其映射到一个特定的"会议"。大多数时候,本次会议/任命不包含任何时间或其他方面的例外情况。所以我需要在C#中得到这个特定的ID。

如何在outlook中识别特定的约会项目

这是旧的,但它仍然会出现在搜索中,所以我将尝试改进答案,因为我们公司刚刚经历过这一点。

正如Dmitry所写,定期约会的发生是不存在的,除非用户在发生时更改了某些内容,这些事件才会成为例外。这也意味着他们没有独立的ID。

但每一个例外都有一个原始日期,如果没有改变的话,它会在什么时候发生。对于每一个非特殊事件,该日期只是事件的开始日期。

代表

您可以使用全局约会id和原始日期的组合来获得唯一标识约会的id,即使是约会:

    public struct AppointmentId : IEquatable<AppointmentId>
    {
        private readonly string GlobalAppointmentId;
        private readonly LocalDate? OriginalDate;
        public AppointmentId(string globalAppointmentId)
        {
            this.GlobalAppointmentId = globalAppointmentId;
            this.OriginalDate = null;
        }
        public AppointmentId(string globalAppointmentId, LocalDate originalDate)
        {
            this.GlobalAppointmentId = globalAppointmentId;
            this.OriginalDate = originalDate;
        }
        public bool Equals(AppointmentId other)
        {
            return this.GlobalAppointmentId.Equals(other.GlobalAppointmentId, StringComparison.Ordinal) &&
                this.OriginalDate == other.OriginalDate;
        }
        public override bool Equals(object obj) =>
            obj is AppointmentId other && this.Equals(other);
        public override int GetHashCode()
        {
            unchecked
            {
                int hash = 62207;
                hash += 3 * this.GlobalAppointmentId.GetHashCode();
                hash += (5 * this.OriginalDate?.GetHashCode() ?? 0);
                return hash;
            }
        }
        public override string ToString()
        {
            if (this.GlobalAppointmentId == null) return "<None>";
            if (this.OriginalDate == null)
            {
                return $"{this.GlobalAppointmentId}";
            }
            return $"{OriginalDate.Value)} / {GlobalAppointmentId}";
        }
        public static bool operator ==(AppointmentId x, AppointmentId y) => x.Equals(y);
        public static bool operator !=(AppointmentId x, AppointmentId y) => !(x == y);
    }

在这里,我使用NodaTime中的LocalDate来表示没有时间组件的原始日期。

访问

可以轻松访问全局约会id。如前所述,并非例外的事件的原始日期只是约会开始的日期部分。

当您只有AppointmentItem而没有RecurrencePattern中的Exception对象时,例外情况会更麻烦,因为原始日期不直接可用。但你可以通过PropertyAccessor:获得

        public static LocalDate GetOriginalDate(this AppointmentItem appointment)
        {
            // The original date is stored in a property called ExceptionReplaceTime but this
            // property is not exposed in the OOM so we need to use PropertyAccessor
            // See: https://learn.microsoft.com/en-us/office/client-developer/outlook/mapi/pidlidexceptionreplacetime-canonical-property
            using (var props = appointment.PropertyAccessor.AsOwnedResource())
            {
                var p = props.Resource.GetProperty("http://schemas.microsoft.com/mapi/id/{00062002-0000-0000-C000-000000000046}/82280040");
                DateTime exceptionReplaceTime = (DateTime)p;
                return props.Resource.UTCToLocalTime(exceptionReplaceTime).ToLocalDate();
            }
        }

请记住,定期约会的实例实际上并不存在(想想没有结束日期的约会(。如果您有一个异常(作为主约会的附件存储(,它有两个id——主约会id和实例id,后者从主id派生并嵌入异常日期。

查看OutlookSpy的约会(我是它的作者-点击IMessage按钮(,然后查看http://msdn.microsoft.com/en-us/library/ee157690(v=exchg.80(.aspx获取预约id格式。