在没有Outlook的情况下发送Outlook会议请求?

我只是想知道是否可以发送会议请求给没有在服务器上安装Outlook并使用COM Interop(我想避免在服务器上不惜一切代价)的人。

我们在Windows 2003域中有Exchange 2003,所有用户都是域用户。 我想我可以发送'围绕iCal / vCal什么的,但我不知道是否有一个适当的标准方式通过Exchange发送会议请求没有Outlook?

这是C#/。净重要的。

向Outlook发送会议请求(并将其识别)的方式如下所示:

  • 准备一个iCalendar文件,一定要设置这些额外的属性,因为Outlook需要它们:
    • UID
    • SEQUENCE
    • CREATED
    • LAST-MODIFIED
    • DTSTAMP
  • 准备一个multipart/alternative邮件:
    • 第1部分: text/html (或任何你喜欢的) – 这是显示给“普通”的邮件阅读器或作为一个后退,并包含事件的总结在人类可读的forms
    • 第2部分: text/calendar; method=REQUEST text/calendar; method=REQUEST ,保存ics文件的内容(header method参数必须与ics中的方法相匹配)。 注意正确的文本编码,声明一个charset头参数不会受到伤害。
    • 第3部分:可选地,附加.ics文件本身,所以普通的邮件阅读器可以为用户提供点击的东西。 Outlook并不需要附件,因为它只是读取text/calendar部分。
  • 将邮件发送给Outlook用户。 如果你得到了一切正确的邮件显示为会议要求,完成与出席button和自动input在用户日历接受。
  • 设置一些处理响应的东西(他们去会议组织者)。 我还没有能够使自动跟踪用户跟踪Exchange邮箱,因为事件将不存在于组织者日历中。 Outlook需要UID和SEQUENCES来匹配它的期望,但是用你编写的UID很难工作。

有关ics文件格式的细节和特性的帮助,请务必访问Masahide Kanzaki的iCalendar规范摘录 。 它们在黑暗中是一道亮光,比通过RFC 2445啃咬的要好得多。 但是再一次,也许有一个方便的库存在.NET。

请参阅sourceforge上的DDay.iCal C#库:
http://sourceforge.net/projects/dday-ical/

然后阅读这个codeproject文章:
http://www.codeproject.com/Articles/17980/Adding-iCalendar-Support-to-Your-Program-Part-1

并阅读:
将事件与C#导出为iCalendar和vCalendar格式

iCalendar是一个很好的通用解决scheme,DDay.iCal库是一个很好的从.NET这样做的方式,但是我相信Exchange Web服务 (EWS)是原始问题(Exchange,C# /。净)。

如果您使用.NET语言(例如C#),则应使用EWS托pipeAPI包装器,这大大简化了使用EWS的工作。

从文档中 ,下面介绍如何使用EWS托pipeAPI创build会议并将请求发送给被邀请者:

 // Create the appointment. Appointment appointment = new Appointment(service); // Set properties on the appointment. Add two required attendees and one optional attendee. appointment.Subject = "Status Meeting"; appointment.Body = "The purpose of this meeting is to discuss status."; appointment.Start = new DateTime(2009, 3, 1, 9, 0, 0); appointment.End = appointment.Start.AddHours(2); appointment.Location = "Conf Room"; appointment.RequiredAttendees.Add("user1@contoso.com"); appointment.RequiredAttendees.Add("user2@contoso.com"); appointment.OptionalAttendees.Add("user3@contoso.com"); // Send the meeting request to all attendees and save a copy in the Sent Items folder. appointment.Save(SendInvitationsMode.SendToAllAndSaveCopy); 

下面的代码将发送一个会议请求,这样Outlook将呈现接受/拒绝button。

请注意,每个会议的UID必须是唯一的,我使用了一个GUID。

另外请注意,您需要replaceCREATED,DTSTART,DTEND,DTSTAMP,最后修改。 这些是UTCdate/时间。

  var m = new MailMessage(); m.Subject = "Meeting"; m.Body = ""; string iCal = @"BEGIN:VCALENDAR PRODID:-//Microsoft Corporation//Outlook 14.0 MIMEDIR//EN VERSION:2.0 METHOD:PUBLISH X-MS-OLK-FORCEINSPECTOROPEN:TRUE BEGIN:VEVENT CLASS:PUBLIC CREATED:20140423T045933Z DESCRIPTION:desc DTEND:20140430T080000Z DTSTAMP:20140423T045933Z DTSTART:20140430T060000Z LAST-MODIFIED:20140423T045933Z LOCATION:location... PRIORITY:5 SEQUENCE:0 SUMMARY;LANGUAGE=en-us:Summary... TRANSP:OPAQUE UID:D8BFD357-88A7-455C-86BC-C2CECA9AC5C6 X-MICROSOFT-CDO-BUSYSTATUS:BUSY X-MICROSOFT-CDO-IMPORTANCE:1 X-MICROSOFT-DISALLOW-COUNTER:FALSE X-MS-OLK-AUTOFILLLOCATION:FALSE X-MS-OLK-CONFTYPE:0 BEGIN:VALARM TRIGGER:-PT60M ACTION:DISPLAY DESCRIPTION:Reminder END:VALARM END:VEVENT END:VCALENDAR"; using (var iCalView = AlternateView.CreateAlternateViewFromString(iCal, new System.Net.Mime.ContentType("text/calendar"))) { m.AlternateViews.Add(iCalView); var c = new SmtpClient(); // Send message c.Send(m); } 

这假设你有你的configuration文件中configuration的本地SMTP服务器:

  <system.net> <mailSettings> <smtp deliveryMethod="Network" from="no-reply@example.com"> <network defaultCredentials="true" host="smtp.example.local" /> </smtp> </mailSettings> </system.net> 

您可以使用iCal标准(RFC 5545)通过邮件将会议请求发送到Outlook,

你不能以这种方式发送待办事项。 你可以发送“约会”,但这些在“视图”中显示为必须“盲目”接受的.ics附件。

会议要求以良好的预览显示在Outlook中,可以接受或拒绝。 发送程序发送后可能会修改或取消会议。

使用DDay.iCal .Net库创build一个有效的iCal项目是一件容易的事情

下面的代码是一个完整的工作示例。 它使用有效的iCal会议请求构build一个string并通过邮件发送。

该代码创build一个邮件:

  • 纯文本正文为简单的邮件客户端
  • 现代邮件客户端中的diplay的HTML正文
  • 作为AlternateView的iCal会议请求(将显示在Outlook中)
  • iCal会议请求作为附件(可用于Outlook以外的邮件客户端)

代码显示如何添加:

  • 描述文字为HTML,外观更好看
  • 优先级,可视性(公共/私人/机密)
  • 可选的组织者(将显示在Outlook而不是邮件发件人)
  • 可选参加者
  • 可选的报警
  • 会议的可选附件。 将在Outlook的日历中显示

一些重要的细节:

  • 邮件发件人(或可选组织者)和邮件收件人必须不同才能在Outlook中进行此项工作
  • .ics中的方法和Mime.ContentType中的METHOD必须匹配
  • 这次会议必须要在未来才能做到这一点
  • .ics部分必须是MIME邮件中的最后一个alternateView部分

有关解释.ics文件的方式的确切细节在[MS-OXCICAL]中详细介绍:iCalendar到Appointment对象转换algorithm

我们将使用这些程序集:

 using System; using System.IO; using System.Net.Mail; using DDay.iCal; using DDay.iCal.Serialization.iCalendar; 

DDay.iCal足以下载DDay.iCal二进制文件 。 如果你想添加一些function,最好看一下DDay.iCal源代码,因为文档已经过时了,而源代码包含了非常完整的testing,可以体现所有function。

 const string filepath = @"C:\temp\ical.test.ics"; // use PUBLISH for appointments // use REQUEST for meeting requests const string METHOD = "REQUEST"; // Properties of the meeting request // keep guid in sending program to modify or cancel the request later Guid uid = Guid.Parse("2B127C67-73B3-43C5-A804-5666C2CA23C9"); string VisBetreff = "This is the subject of the meeting request"; string TerminVerantwortlicherEmail = "mr.asker@myorg.com"; string bodyPlainText = "This is the simple iCal plain text msg"; string bodyHtml = "This is the simple <b>iCal HTML message</b>"; string location = "Meeting room 101"; // 1: High // 5: Normal // 9: low int priority = 1; //===================================== MailMessage message = new MailMessage(); message.From = new MailAddress("sender@myorg.com"); message.To.Add(new MailAddress(TerminVerantwortlicherEmail)); message.Subject = "[VIS-Termin] " + VisBetreff; // Plain Text Version message.Body = bodyPlainText; // HTML Version string htmlBody = bodyHtml; AlternateView HTMLV = AlternateView.CreateAlternateViewFromString(htmlBody, new System.Net.Mime.ContentType("text/html")); // iCal IICalendar iCal = new iCalendar(); iCal.Method = METHOD; iCal.ProductID = "My Metting Product"; // Create an event and attach it to the iCalendar. Event evt = iCal.Create<Event>(); evt.UID = uid.ToString(); evt.Class = "PUBLIC"; // Needed by Outlook evt.Created = new iCalDateTime(DateTime.Now); evt.DTStamp = new iCalDateTime(DateTime.Now); evt.Transparency = TransparencyType.Transparent; // Set the event start / end times evt.Start = new iCalDateTime(2014, 10, 3, 8, 0, 0); evt.End = new iCalDateTime(2014, 10, 3, 8, 15, 0); evt.Location = location; //var organizer = new Organizer("the.organizer@myCompany.com"); //evt.Organizer = organizer; // Set the longer description of the event, plain text evt.Description = bodyPlainText; // Event description HTML text // X-ALT-DESC;FMTTYPE=text/html var prop = new CalendarProperty("X-ALT-DESC"); prop.AddParameter("FMTTYPE", "text/html"); prop.AddValue(bodyHtml); evt.AddProperty(prop); // Set the one-line summary of the event evt.Summary = VisBetreff; evt.Priority = priority; //--- attendes are optional IAttendee at = new Attendee("mailto:Peter.Black@MyOrg.com"); at.ParticipationStatus = "NEEDS-ACTION"; at.RSVP = true; at.Role = "REQ-PARTICIPANT"; evt.Attendees.Add(at); // Let's also add an alarm on this event so we can be reminded of it later. Alarm alarm = new Alarm(); // Display the alarm somewhere on the screen. alarm.Action = AlarmAction.Display; // This is the text that will be displayed for the alarm. alarm.Summary = "Upcoming meeting: " + VisBetreff; // The alarm is set to occur 30 minutes before the event alarm.Trigger = new Trigger(TimeSpan.FromMinutes(-30)); //--- Attachments string filename = "Test.docx"; // Add an attachment to this event IAttachment attachment = new DDay.iCal.Attachment(); attachment.Data = ReadBinary(@"C:\temp\Test.docx"); attachment.Parameters.Add("X-FILENAME", filename); evt.Attachments.Add(attachment); iCalendarSerializer serializer = new iCalendarSerializer(); serializer.Serialize(iCal, filepath); // the .ics File as a string string iCalStr = serializer.SerializeToString(iCal); // .ics as AlternateView (used by Outlook) // text/calendar part: method=REQUEST System.Net.Mime.ContentType calendarType = new System.Net.Mime.ContentType("text/calendar"); calendarType.Parameters.Add("method", METHOD); AlternateView ICSview = AlternateView.CreateAlternateViewFromString(iCalStr, calendarType); // Compose message.AlternateViews.Add(HTMLV); message.AlternateViews.Add(ICSview); // must be the last part // .ics as Attachment (used by mail clients other than Outlook) Byte[] bytes = System.Text.Encoding.ASCII.GetBytes(iCalStr); var ms = new System.IO.MemoryStream(bytes); var a = new System.Net.Mail.Attachment(ms, "VIS-Termin.ics", "text/calendar"); message.Attachments.Add(a); // Send Mail SmtpClient client = new SmtpClient(); client.Send(message); 

这里的ReadBinary()函数:

 private static byte[] ReadBinary(string fileName) { byte[] binaryData = null; using (FileStream reader = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { binaryData = new byte[reader.Length]; reader.Read(binaryData, 0, (int)reader.Length); } return binaryData; } 

在configuration文件中configurationSmtpClient最简单:

 <configuration> ... <system.net> <mailSettings> <smtp> <network host="mysmtp.server.com" port="25" userName="mySmtpUserName" password="myPassword" /> </smtp> </mailSettings> </system.net> ...