2009-01-20 129 views
36

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

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

这是C#/ .net,如果它很重要。

+1

的时候,你选择了等待的时间让我认为我的建议不完全是你想到的。你有没有起作用? – Tomalak 2009-01-23 10:53:55

+1

我刚才没有时间去测试它。对它的快速测试似乎奏效,并且我发送了一个Outlook会议邀请函到一个启用了POP3的帐户以获得“原始转储”。这两位对我来说足够好,因为我只需要发送会议,但不关心回复 – 2009-01-23 13:42:29

+1

无论如何,您的回答非常有帮助,非常感谢! – 2009-01-23 13:43:31

回答

47

发送会议请求到Outlook(有它识别)的方式是这样的:

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

如需帮助了解ics文件格式的详细信息和特性,请务必访问iCalendar Specification Excerpts by Masahide Kanzaki。它们在黑暗中是一道亮光,远胜于通过RFC 2445啃咬你的方式。但是,再一次,也许有一个方便的.NET库存在。

3

下面的代码会以这样的方式发送会议请求Outlook将呈现接受/拒绝按钮。

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

另请注意,您需要更换CREATED,DTSTART,DTEND,DTSTAMP,最后修改。这些是UTC日期/时间。

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); 
    } 

这里假设你有你的配置文件配置本地SMTP服务器:

<system.net> 
    <mailSettings> 
     <smtp deliveryMethod="Network" from="[email protected]"> 
     <network defaultCredentials="true" host="smtp.example.local" /> 
     </smtp> 
    </mailSettings> 
    </system.net> 
5

iCalendar是一个伟大的通用解决方案,以及DDay.iCal库是做到这一点的好方法从.NET,但我相信Exchange Web Services(EWS)是在原始问题(Exchange,C#/。NET)的上下文中更好的解决方案。

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

the docs,这里是如何使用EWS托管API来创建一个会议,并请求发送到受邀者:

// 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("[email protected]"); 
appointment.RequiredAttendees.Add("[email protected]"); 
appointment.OptionalAttendees.Add("[email protected]"); 

// Send the meeting request to all attendees and save a copy in the Sent Items folder. 
appointment.Save(SendInvitationsMode.SendToAllAndSaveCopy); 
3

您可以使用iCal Standard (RFC 5545)

您发送的邮件会议请求到Outlook不能以这种方式发送待办事项。 您可以发送“预约”,但这些会在outlook中显示为必须“盲目”接受的.ics附件。

会议请求出现在outlook中,预览效果不错,可以接受或拒绝。 发送程序可能会在发送后修改或取消会议。

它easieset创建与DDay.iCal .Net Library

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

的代码创建一个电子邮件与:

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

的代码显示了如何添加:

  • 说明文字为HTML,看起来前景更好
  • 优先级,能见度(公共/私有/保密)
  • 可选的组织者(会在Outlook中,而不是邮件发件人显示)
  • 可选出席者
  • 可选闹钟
  • 可选附件参加会议。将在Outlook的日历上显示

一些重要的细节:

  • 邮件发送者(或可选的组织者)和电子邮件的接收方必须是不同的,以使前景这项工作
  • 中的.ics和方法
  • 方法在Mime.ContentType必须匹配
  • 会议必须位于未来在Outlook这项工作
  • 请在.ics部分必须是MIME邮件的最后alternateView部分

关于途观的具体细节解释.ics文件详见[MS-OXCICAL]: iCalendar to Appointment Object Conversion Algorithm

我们将使用这些组件:

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

对于DDay.iCal其足够的下载DDay.iCal binary Files。如果您想添加一些功能,最好查看DDay.iCal源代码,因为文档已过时,并且源代码包含非常完整的测试,可以体验其所有功能。

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 = "[email protected]"; 
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("[email protected]"); 
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("[email protected]"); 
//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:[email protected]"); 
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; 
} 

其最简单的配置SmtpClient在配置文件中是这样的:

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