My problem is, I can't access and so iterate Outlook's shared calendars. I've tried several ways but they all take me back to the default calendar (i.e. my account calendar).
I tried to loop in the subfolders, the GetSharedDefaultFolder() method and using different types of objects of the Interop library but I couldn't solve it.
Here are the methods I've tried. To run the program (in particular GetMethod3() and GetMethod5()) you have to set the string "email" with your own email.
using System;
using System.Text;
using Microsoft.Office.Interop.Outlook;
namespace OutlookTest {
class Program {
static void Main(string[] args) {
OutlookSharedCalendar outlookSharedCalendar = new OutlookSharedCalendar();
}
}
public class OutlookSharedCalendar{
Microsoft.Office.Interop.Outlook.Application oApp;
NameSpace oNameSpace = null;
MAPIFolder oMAPIFolder = null;
MAPIFolder objFolder = null;
MAPIFolder objSubFolder = null;
Explorer objExplorer;
AppointmentItem objCalenderItem;
Folders objOutlookFolders;
AddressEntry addrEntry = null;
Items oCalendarItems = null;
string email = "[email protected]";
public OutlookSharedCalendar() {
AppStart();
GetMethod1();
AppEnd();
AppStart();
GetMethod2();
AppEnd();
AppStart();
GetMethod3();
AppEnd();
AppStart();
GetMethod4();
AppEnd();
AppStart();
GetMethod5();
AppEnd();
}
public void GetMethod1() {
oMAPIFolder = oApp.Session.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
oCalendarItems = (Items)oMAPIFolder.Items;
oCalendarItems.IncludeRecurrences = true;
foreach(AppointmentItem item in oCalendarItems) {
if(item.IsRecurring) {
RecurrencePattern oRP = item.GetRecurrencePattern();
DateTime first = new DateTime(2018, 01, 01, item.Start.Hour, item.Start.Minute, 0);
DateTime last = new DateTime(2019, 10, 31);
AppointmentItem recur = null;
for(DateTime cur = first; cur <= last; cur = cur.AddDays(1)) {
recur = oRP.GetOccurrence(cur);
Console.WriteLine(recur.Subject + " - " + cur.ToLongDateString() + " - " + recur.Body);
}
}
else {
Console.WriteLine(item.Subject + " -> " + item.Start.ToLongDateString());
}
}
}
public void GetMethod2() {
int intFolderCtr;
int intSubFolderCtr;
int intAppointmentCtr;
// >> Initialize The Base Objects
objOutlookFolders = oApp.Session.Folders;
// >> Loop Through The PST Files Added n Outlook
for(intFolderCtr = 1; intFolderCtr <= objOutlookFolders.Count; intFolderCtr++) {
objFolder = objOutlookFolders[intFolderCtr];
objExplorer = objFolder.GetExplorer();
// >> Loop Through The Folders In The PST File
for(intSubFolderCtr = 1; intSubFolderCtr <= objExplorer.CurrentFolder.Folders.Count; intSubFolderCtr++) {
objSubFolder = objExplorer.CurrentFolder.Folders[intSubFolderCtr];
// >> Check if Folder Contains Appointment Items
if(objSubFolder.DefaultItemType == OlItemType.olAppointmentItem) {
// >> Loop Through Appointment Items
for(intAppointmentCtr = 1; intAppointmentCtr <= objSubFolder.Items.Count; intAppointmentCtr++) {
// >> Get Teh Calender Item From The Calender Folder
objCalenderItem = objSubFolder.Items[intAppointmentCtr];
// >> Process Appointment Item Accordingly
Console.WriteLine(objCalenderItem.Subject + " - " + objCalenderItem.Start + " - " + objCalenderItem.Body + " - " + objCalenderItem.Location);
}
}
}
}
}
public void GetMethod3() {
DateTime dtFrom = new DateTime(DateTime.Now.Year, 01, 01);
DateTime dtTo = new DateTime(DateTime.Now.Year, 12, 31);
Recipient teamMember = oApp.Session.CreateRecipient(email);
MAPIFolder sharedCalendar = oApp.Session.GetSharedDefaultFolder(teamMember, OlDefaultFolders.olFolderCalendar);
if(sharedCalendar.DefaultMessageClass != "IPM.Appointment" || teamMember.DisplayType != 0) {
return; //Calendar not shared.
}
string restrictCriteria = "[Start]<=\"" + dtTo.ToString("g") + "\"" + " AND [End]>=\"" + dtFrom.ToString("g") + "\"";
Items results = sharedCalendar.Items.Restrict(restrictCriteria);
foreach(AppointmentItem item in results) {
Console.WriteLine(item.Subject + " - " + item.Start + " - " + item.Body + " - " + item.Location);
}
}
public void GetMethod4() {
oMAPIFolder = oApp.Session.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
DateTime dtEnd = new DateTime(DateTime.Now.Year, 12, 31);
DateTime dtStart = new DateTime(DateTime.Now.Year, 01, 01);
string restrictCriteria = "[Start]<=\"" + dtEnd.ToString("g") + "\"" +
" AND [End]>=\"" + dtStart.ToString("g") + "\"";
StringBuilder strBuilder = null;
Items folderItems = null;
Items resultItems = null;
AppointmentItem appItem = null;
int counter = default(int);
object item = null;
strBuilder = new StringBuilder();
folderItems = (Items)oMAPIFolder.Items;
folderItems.IncludeRecurrences = true;
folderItems.Sort("[Start]");
resultItems = folderItems.Restrict(restrictCriteria);
item = resultItems.GetFirst();
do {
if(item != null) {
if(item is AppointmentItem) {
counter++;
appItem = item as AppointmentItem;
Console.WriteLine(appItem.Subject + " -> " + appItem.Start.ToLongDateString());
strBuilder.AppendLine("#" + counter.ToString() +
"\tStart: " + appItem.Start.ToString() +
"\tSubject: " + appItem.Subject +
"\tLocation: " + appItem.Location);
}
item = resultItems.GetNext();
}
}
while(item != null);
}
public void GetMethod5() {
addrEntry = oApp.Session.CurrentUser.AddressEntry;
if(addrEntry.Type == "EX") {
Recipient recip = oApp.Session.CreateRecipient(email);
if(recip.Resolve()) {
Folder folder = oApp.Session.GetSharedDefaultFolder(recip, OlDefaultFolders.olFolderCalendar) as Folder;
foreach(AppointmentItem item in folder.Items) {
Console.WriteLine(item.Subject + " - " + item.Start + " - " + item.Body + " - " + item.Location);
}
}
}
}
public void AppStart() {
// >> Start Outlook
oApp = new Microsoft.Office.Interop.Outlook.Application();
}
public void AppEnd() {
// >> Close Application
oApp.Quit();
// >> Release COM Object
System.Runtime.InteropServices.Marshal.ReleaseComObject(oApp);
oApp = null;
}
}
}
I hope I can get advice on the code or if someone knows a viable alternative to Interop. Thank you all in advance.
The NameSpace.GetSharedDefaultFolder method is used to get a Folder
object that represents the specified default folder for the specified user. For example, with minor changes:
public void GetMethod3() {
DateTime dtFrom = new DateTime(DateTime.Now.Year, 01, 01);
DateTime dtTo = new DateTime(DateTime.Now.Year, 12, 31);
Recipient teamMember = oApp.Session.CreateRecipient(email);
teamMember.Resolve();
if(teamMember.Resolved)
{
MAPIFolder sharedCalendar = oApp.Session.GetSharedDefaultFolder(teamMember, OlDefaultFolders.olFolderCalendar);
if(sharedCalendar.DefaultMessageClass != "IPM.Appointment" || teamMember.DisplayType != 0) {
return; //Calendar not shared.
}
string restrictCriteria = "[Start]<=\"" + dtTo.ToString("g") + "\"" + " AND [End]>=\"" + dtFrom.ToString("g") + "\"";
Items results = sharedCalendar.Items.Restrict(restrictCriteria);
foreach(AppointmentItem item in results) {
Console.WriteLine(item.Subject + " - " + item.Start + " - " + item.Body + " - " + item.Location);
}
}
}
As you may see the recipient should be resolved against your address book before trying to access a shared calendar. The Recipient.Resolve method attempts to resolve a Recipient
object against the Address Book.