Hi, I posted this in another forum here and thought that code samples is the right place for it. So - here a library which allows in 2-3 lines of code to either send a regular email or to set an appointment and invite attendees. Will work with Exchange2000
only, and you need CDO 1.21 installed - but if you are developing for exchange you know that already :) using System; using System.Collections.Specialized; using System.Reflection; //COM InterOp Libraries using ADODB; using CDO; namespace Tvuna.ExchangeUtils
{ /// /// This class represents an Exchange2000 server. /// It also serves as the factory for creation of other objects such as messages, appointments, etc. /// public class ExchangeServer { #region Private/Internal Variables /// /// ADODB Connection opened
and bound to the system mailbox /// internal ADODB.Connection ADOConn=null; /// /// initialized CDO.Configuration object /// internal CDO.Configuration CDOConfig=null; #endregion #region Public Properties public string CalendarFolderName="calendar"; public
readonly string ServerName=""; public readonly string Mailbox=""; public readonly string Password=""; public readonly string FullMailboxAddress=""; #endregion #region Public Methods /// /// Constructor for the ExchangeServer object /// /// Name of Exchange
Server /// Mailbox/Account to use /// Password of Mailbox/Account /// full email address (user@domain.com) of Mailbox/Account public ExchangeServer(string ExchangeServerName, string ExchangeMailbox, string ExchangePassword, string ExchangeFullMailboxAddress)
{ ServerName=ExchangeServerName; Mailbox=ExchangeMailbox; Password=ExchangePassword; FullMailboxAddress = ExchangeFullMailboxAddress; ADOConn = new ADODB.ConnectionClass(); ADOConn.Provider="MSDAIPP.DSO.1"; ADOConn.Open("http://" + ServerName + "/exchange/"
+ Mailbox,Mailbox,Password,-1); } /// /// Create, initialize and return a ready-to-send ExchangeAppointment object /// /// Full email address of attendee /// start time of Appointment /// end time of Appointment /// subject /// message text /// ExchangeAppointment
object public ExchangeAppointment CreateAppointment(string AppAttendee, DateTime AppStartTime, DateTime AppEndTime, string AppSubject, string AppText) { ExchangeAppointment newAppointment = new ExchangeAppointment(this,AppAttendee,AppStartTime,AppEndTime,AppSubject,AppText);
return newAppointment; } /// /// Create, initialize and return a ready-to-send ExchangeAppointment object /// /// Full email address of attendee /// start time of Appointment /// length of Appointment in minutes /// subject /// message text /// ExchangeAppointment
object public ExchangeAppointment CreateAppointment(string AppAttendee, DateTime AppStartTime, int AppLengthInMinutes, string AppSubject, string AppText) { ExchangeAppointment newAppointment = new ExchangeAppointment(this,AppAttendee,AppStartTime,AppLengthInMinutes,AppSubject,AppText);
return newAppointment; } /// /// Create and return an ExchangeAppointment object. /// /// An empty ExchangeAppointment object public ExchangeAppointment CreateAppointment() { ExchangeAppointment newAppointment = new ExchangeAppointment(this); return newAppointment;
} /// /// Create, initialize and return a ready-to-send ExchangeMessage object /// /// Recipient /// Message Subject /// Message Text /// ExchangeMessage object public ExchangeMessage CreateMessage(string To, string Subject, string Text) { ExchangeMessage
newMessage = new ExchangeMessage(this,To,Subject,Text); return newMessage; } /// /// Create and return an ExchangeMessage object. /// /// An empty ExchangeMessage object public ExchangeMessage CreateMessage() { ExchangeMessage newMessage = new ExchangeMessage(this);
return newMessage; } #endregion #region Private/Internal Methods /// /// joins a StringCollection into a ';' delimited string /// /// StringCollection /// a ';' delimited string internal string JoinStringCollection(StringCollection SC) { string[] ToListArray
= new string[SC.Count]; SC.CopyTo(ToListArray,0); return string.Join("; ",ToListArray); } /// /// returns an initialized CDO.Configuration object for use by child objects. /// /// CDO.Configuration object internal CDO.Configuration GetConfiguration() { if
(CDOConfig==null) { string MailBoxURL = "HTTP://" + this.ServerName + "/Exchange/" + this.Mailbox + "/"; CDOConfig = new CDO.ConfigurationClass(); CDOConfig.Fields[CdoConfiguration.cdoSendUserReplyEmailAddress].Value =this.FullMailboxAddress; CDOConfig.Fields[CdoConfiguration.cdoSendEmailAddress].Value
=this.FullMailboxAddress; CDOConfig.Fields[CdoConfiguration.cdoSendUserName].Value =this.Mailbox; CDOConfig.Fields[CdoConfiguration.cdoSendPassword].Value =this.Password; CDOConfig.Fields[CdoConfiguration.cdoSendUsingMethod].Value =CdoSendUsing.cdoSendUsingPort;
CDOConfig.Fields[CdoConfiguration.cdoSMTPAccountName].Value =this.Mailbox; CDOConfig.Fields[CdoConfiguration.cdoSMTPAuthenticate].Value =CdoProtocolsAuthentication.cdoNTLM; CDOConfig.Fields[CdoConfiguration.cdoSMTPServer].Value =this.ServerName; CDOConfig.Fields[CdoConfiguration.cdoSMTPServerPort].Value
=25; CDOConfig.Fields[CdoConfiguration.cdoPostEmailAddress].Value =this.FullMailboxAddress; CDOConfig.Fields[CdoConfiguration.cdoPostPassword].Value =this.Password; CDOConfig.Fields[CdoConfiguration.cdoPostUserName].Value =this.Mailbox; CDOConfig.Fields[CdoConfiguration.cdoPostUserReplyEmailAddress].Value
=this.FullMailboxAddress; CDOConfig.Fields[CdoConfiguration.cdoPostUsingMethod].Value =CdoSendUsing.cdoSendUsingPort; CDOConfig.Fields[CdoConfiguration.cdoActiveConnection].Value=this.ADOConn; CDOConfig.Fields[CdoConfiguration.cdoMailboxURL].Value=MailBoxURL;
CDOConfig.Fields.Update(); } return CDOConfig; } #endregion } /// /// This class represents an Appointment in the Exchange server. /// Instances can be created using the CreateAppointment method of the ExchangeServer object /// /// /// ExchangeServer ExchSrv
= new ExchangeServer("myserver","myuser","mypassword","myuser@myserver.com"); /// ExchangeAppointment ExchApp = ExchSrv.CreateAppointment(); /// ExchApp.Attendees.Add("billgates@microsoft.com"); /// ExchApp.Attendees.Add("stevebalmer@microsoft.com"); /// ExchApp.StartTime=DateTime.Now;
/// ExchApp.LengthInMinutes=90; /// ExchApp.Subject="very important meeting"; /// ExchApp.Send(); /// public class ExchangeAppointment { #region Private/Internal Variables internal ExchangeServer _Server; private StringCollection _Attendees = new StringCollection();
private DateTime _StartTime; private DateTime _EndTime; private int _LengthInMinutes; private string _Subject; private string _Location; private string _Text; #endregion #region Public Properties /// /// Collection of Appointment Attendees. /// Should contain
full email addresses (user@domain.com) /// public StringCollection Attendees { get {return _Attendees;} set {_Attendees = value;} } /// /// Start Time of Appointment /// public DateTime StartTime { get {return _StartTime;} set {_StartTime = value;} } /// ///
End Time of Appointment /// this will update the LengthInMinutes as well /// public DateTime EndTime { get {return _EndTime;} set { _EndTime = value; float tmp = ((_EndTime.Ticks - _StartTime.Ticks)/TimeSpan.TicksPerMinute); _LengthInMinutes = Convert.ToInt32(tmp);
} } /// /// Subject of the meeting /// public string Subject { get {return _Subject;} set {_Subject = value;} } /// /// Location of the meeting /// public string Location { get {return _Location;} set {_Location = value;} } /// /// Message body text. /// public
string Text { get {return _Text;} set {_Text = value;} } /// /// Length of appointment in minutes /// this will update the End Time as well /// public int LengthInMinutes { get {return _LengthInMinutes;} set { _LengthInMinutes = value; _EndTime = StartTime.AddMinutes(value);
} } /// /// reference to the ExchangeServer object /// public ExchangeServer Server { get {return _Server;} } #endregion #region Public Methods /// /// "Sends" the appointment. /// This includes saving the appointment to the mailbox's Calendar dir, /// and
sending invitations to all the attendees. /// public void Send() { string MailBoxURL = "HTTP://" + Server.ServerName + "/Exchange/" + Server.Mailbox + "/"; string CalendarURL = MailBoxURL + Server.CalendarFolderName; CDO.Appointment newAppointment = new CDO.AppointmentClass();
// CDO INVITE will fail if sending user is not invited! if (!Attendees.Contains(Server.FullMailboxAddress)) Attendees.Add(Server.FullMailboxAddress); newAppointment.StartTime= this.StartTime; newAppointment.EndTime= this.EndTime; newAppointment.Subject=this.Subject;
newAppointment.Location=this.Location; newAppointment.TextBody=this.Text; foreach(string s in this.Attendees) newAppointment.Attendees.Add(s); //save the appointment to the mailbox's CALENDAR folder newAppointment.DataSource.SaveToContainer( CalendarURL, Server.ADOConn,
ConnectModeEnum.adModeReadWrite, RecordCreateOptionsEnum.adCreateNonCollection, RecordOpenOptionsEnum.adOpenSource, Server.Mailbox, Server.Password ); newAppointment.Configuration=Server.GetConfiguration(); // Send invitations to all the Attendess string ToList
= Server.JoinStringCollection(Attendees); ICalendarMessage InviteMessage = newAppointment.Invite(ToList); InviteMessage.Message.Send(); } #endregion #region Private/Internal Methods internal ExchangeAppointment(ExchangeServer ExchServer) { _Server=ExchServer;
} internal ExchangeAppointment(ExchangeServer ExchServer, string AppAttendee, DateTime AppStartTime, DateTime AppEndTime, string AppSubject, string AppText):this(ExchServer) { Attendees.Add(AppAttendee); StartTime=AppStartTime; EndTime=AppEndTime; Subject=AppSubject;
Text=AppText; } internal ExchangeAppointment(ExchangeServer ExchServer, string AppAttendee, DateTime AppStartTime, int AppLengthInMinutes, string AppSubject, string AppText):this(ExchServer) { Attendees.Add(AppAttendee); StartTime=AppStartTime; EndTime=StartTime.AddMinutes(AppLengthInMinutes);
Subject=AppSubject; Text=AppText; } #endregion } /// /// This class represents an Email message in the Exchange server. /// Instances can be created using the CreateMessage method of the ExchangeServer object /// /// /// ExchangeServer ExchSrv = new ExchangeServer("myserver","myuser","mypassword","myuser@myserver.com");
/// ExchangeMessage ExchMsg = ExchSrv.CreateMessage("billgates@microsoft.com",".NET rocks","now gimme a million bucks"); /// ExchMsg.Send(); /// public class ExchangeMessage { #region Private/Internal Variables internal ExchangeServer _Server=null; private
StringCollection _To = new StringCollection(); private StringCollection _CC = new StringCollection(); private StringCollection _BCC = new StringCollection(); private string _Subject; private string _Text; private bool _isHTML; #endregion #region Public Properties
/// /// Collection of message recipients (TO) /// Should contain full email addresses (user@domain.com) /// public StringCollection To { get {return _To;} set {_To = value;} } /// /// Collection of message recipients (CC) /// Should contain full email addresses
(user@domain.com) /// public StringCollection CC { get {return _CC;} set {_CC = value;} } /// /// Collection of message recipients (BCC) /// Should contain full email addresses (user@domain.com) /// public StringCollection BCC { get {return _BCC;} set {_BCC
= value;} } /// /// Message Subject /// public string Subject { get {return _Subject;} set {_Subject = value;} } /// /// Message body text. /// If isHTML is true, this should contain HTML /// public string Text { get {return _Text;} set {_Text = value;} }
/// /// Is this message in HTML? /// True means that the Text property contains HTML content. /// public bool isHTML { get {return _isHTML;} set {_isHTML = value;} } public ExchangeServer Server { get {return _Server;} } #endregion #region Internal/Private
Methods internal ExchangeMessage(ExchangeServer ExchServer) { _Server = ExchServer; } internal ExchangeMessage(ExchangeServer ExchServer, string MessageTo, string MessageSubject, string MessageText):this(ExchServer) { Text=MessageText; Subject=MessageSubject;
To.Add(MessageTo); } #endregion #region Public Methods /// /// Sends the message. /// public void Send() { string MailBoxURL = "HTTP://" + Server.ServerName + "/Exchange/" + Server.Mailbox + "/"; string CalendarURL = MailBoxURL + Server.CalendarFolderName;
CDO.Message newMessage = new CDO.MessageClass(); newMessage.To = Server.JoinStringCollection(To); newMessage.CC = Server.JoinStringCollection(CC); newMessage.BCC = Server.JoinStringCollection(BCC); newMessage.Subject = this.Subject; if (isHTML) newMessage.HTMLBody=this.Text;
else newMessage.TextBody=this.Text; newMessage.Configuration=Server.GetConfiguration(); newMessage.Send(); } #endregion }
I'm guessing i don't have the "MSDAIPP.DSO.1" provider installed. The web server is a 2003 server.
The other warning i'm getting when compiling your code in visual studio.net 2003.
\\tweety\users$\ohine\visual studio projects\excdo\webcustomcontrol1.cs(23,12): warning CS1595: 'ADODB.Connection' is defined in multiple places; using definition from 'c:\Program Files\Microsoft.NET\Primary Interop Assemblies\adodb.dll'
\\tweety\users$\ohine\visual studio projects\excdo\webcustomcontrol1.cs(52,18): warning CS1595: 'ADODB.ConnectionClass' is defined in multiple places; using definition from 'c:\Program Files\Microsoft.NET\Primary Interop Assemblies\adodb.dll'
\\tweety\users$\ohine\visual studio projects\excdo\webcustomcontrol1.cs(313,5): warning CS1595: 'ADODB.ConnectModeEnum' is defined in multiple places; using definition from 'c:\Program Files\Microsoft.NET\Primary Interop Assemblies\adodb.dll'
\\tweety\users$\ohine\visual studio projects\excdo\webcustomcontrol1.cs(314,5): warning CS1595: 'ADODB.RecordCreateOptionsEnum' is defined in multiple places; using definition from 'c:\Program Files\Microsoft.NET\Primary Interop Assemblies\adodb.dll'
\\tweety\users$\ohine\visual studio projects\excdo\webcustomcontrol1.cs(315,5): warning CS1595: 'ADODB.RecordOpenOptionsEnum' is defined in multiple places; using definition from 'c:\Program Files\Microsoft.NET\Primary Interop Assemblies\adodb.dll'
Any ideas how i can get rid of these warnings? and how to include the provider i'm missing?
Hi, This is indeed a very good post! When I tried to connect to my Exchange server, I got an COM error. I can't get the exact error code. Just want to find out from you how can I get the error code so that I can understand better and give better picture to
the community what problem am I facing here. The error I got is: DefaultDatabase string I don't know what have I done wrong here. Sorry for this as I am very new to Exchange programming. Any suggestion are welcome. Thanks.
Did anyone of you get it working? I noticed on another thread addy mentioning a problem with the com calls not being single threaded, and that you call get the updated code from him, but his profile only holds the ICQ number... :-(
Hi all, Nice to know that a post from over a year ago is still generating interest!! Since then I have changed companies and moved to (literally) the other side of the world. I don't have the relevant code snippets with me, and the only other person who might
have it is on vacation in Thailand. So sorry but you are on your own with this one... However I do vaguely remember that one of the steps needed to make it work under ASP.NET is to tag the page with ASPCOMPAT=TRUE - that forces ASP.NET to lock the page down
into an STA. good luck, and if anyone really cares - my email is addys@yahoo.com
Hi Addy and the rest of you! yes I also figured that aspcompat=true in the page directive was what was missing, now I wonder, because I am using the solution like this: -I have compiled the Exchange Utility class into a assembly -From my VB.NET project I reference
the assembly project then in my page I have turned on aspcompat=true, then my first question is, is the asp compability inherited/ its functionality provided althrough the chain from my page through the assembly? or should I so0mehow in the assembly include
a referece to the compability dll? Secondly, which my be bound to the above question I get an error when I try to create an appointment. Here is the calling code in my VB file: Dim a As ExchangeServer = New ExchangeServer("localhost", "DOMAIN\Administrator",
"password", "administrator@domain") Dim ExchApp As ExchangeAppointment = a.CreateAppointment() ExchApp.Attendees.Add("Administrator@domain") ExchApp.StartTime = DateTime.Now ExchApp.LengthInMinutes = 90 ExchApp.Subject = "very important meeting" ExchApp.Send()
and here is the error: Object or data matching the name, range, or selection criteria was not found within the scope of this operation. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace
for more information about the error and where it originated in the code. Exception Details: System.Runtime.InteropServices.COMException: Object or data matching the name, range, or selection criteria was not found within the scope of this operation. Source
Error: Line 308: Line 309: //save the appointment to the mailbox's CALENDAR folder Line 310: newAppointment.DataSource.SaveToContainer( Line 311: CalendarURL, Line 312: Server.ADOConn, Source File: e:\inetpub\wwwroot\ipp\exchutil\class1.cs Line: 310 Stack
Trace: [COMException (0x80040e19): Object or data matching the name, range, or selection criteria was not found within the scope of this operation. ] CDO.IDataSource.SaveToContainer(String ContainerURL, Object ActiveConnection, ConnectModeEnum Mode, RecordCreateOptionsEnum
CreateOptions, RecordOpenOptionsEnum Options, String UserName, String Password) +0 Tvuna.ExchangeUtils.ExchangeAppointment.Send() in e:\inetpub\wwwroot\ipp\exchutil\class1.cs:310 ipp.WebForm1.Page_Load(Object sender, EventArgs e) in E:\Inetpub\wwwroot\ipp\WebForm1.aspx.vb:32
System.Web.UI.Control.OnLoad(EventArgs e) +67 System.Web.UI.Control.LoadRecursive() +35 System.Web.UI.Page.ProcessRequestMain() +731 Any ideas?? Oh, just one last thing, is this code intended to be run on the exchange server to work or can it be run on a frontend
server?
I don't think it is possible to run this code as is. I have just converted the whole class to VB.NET and get the exact same error, although I have actually made the code work if I just use it in a code-behind.... This snippet is from the msdn/framework sdk,
about com compability: STA components cannot be used from .NET Framework code modules (compiled .NET assemblies); they can be used only from ASP.NET pages. Doesn't it state that placering com calls in a class file is impossible? Well, I'm not a expert, but
a class fiel isn't really compiled, well not until I build my solution.... ???
Addys
Member
55 Points
11 Posts
Creating Appointments in Exchange2000 from .NET
Jul 24, 2002 01:14 PM|LINK
uzi
Participant
1340 Points
268 Posts
Re: Creating Appointments in Exchange2000 from .NET
Jul 13, 2003 01:43 AM|LINK
ADOConn = new ADODB.ConnectionClass(); ADOConn.Provider="MSDAIPP.DSO.1"; ADOConn.Open("http://" + ServerName + "/exchange/" + Mailbox,Mailbox,Password,-1);I'm guessing i don't have the "MSDAIPP.DSO.1" provider installed. The web server is a 2003 server. The other warning i'm getting when compiling your code in visual studio.net 2003. Any ideas how i can get rid of these warnings? and how to include the provider i'm missing?Oliver
Scott Gallow...
Participant
1510 Points
302 Posts
Re: Creating Appointments in Exchange2000 from .NET
Jul 16, 2003 03:57 PM|LINK
ScAndal
Participant
1304 Points
290 Posts
Re: Creating Appointments in Exchange2000 from .NET
Jul 26, 2003 05:08 AM|LINK
.NET Consulting http://www.kineticmedia.net
CH88
Member
60 Points
12 Posts
Re: Creating Appointments in Exchange2000 from .NET
Aug 14, 2003 09:46 AM|LINK
sitedesigner
Member
105 Points
21 Posts
Re: Creating Appointments in Exchange2000 from .NET
Aug 15, 2003 07:44 PM|LINK
Addys
Member
55 Points
11 Posts
Re: Creating Appointments in Exchange2000 from .NET
Aug 15, 2003 08:12 PM|LINK
sitedesigner
Member
105 Points
21 Posts
Re: Creating Appointments in Exchange2000 from .NET
Aug 16, 2003 12:13 PM|LINK
sitedesigner
Member
105 Points
21 Posts
Re: Creating Appointments in Exchange2000 from .NET
Aug 19, 2003 07:23 PM|LINK
CH88
Member
60 Points
12 Posts
Re: Creating Appointments in Exchange2000 from .NET
Nov 24, 2003 06:14 AM|LINK