C# Outlook Add-On: Check Calendars Availability - c#

I am working on an add-in for Outlook using C# and I want to be able to check the availability of calendars (mine and others'). I tried using GetSharedDefaultFolder() but it only worked with those who specifically gave me permission, even though all calendars in my company can be viewed by others (we can see the subject and times of appointments). Is there anyway I can get these information? Thanks.
EDIT: I want to emphasize that my problem is with GetSharedDefaultFolder() rather than GetDefaultFolder() (i.e. viewing others' calendars.) Also, I only need to be able to check others' calendars availability, as opposed to having full access to the calendar.

Do not access the folder directly - use Recipient.FreeBusy or AddressEntry.GetFreeBusy

Try This>>
public void GetAllCalendarItems()
{
Microsoft.Office.Interop.Outlook.Application oApp = null;
Microsoft.Office.Interop.Outlook.NameSpace mapiNamespace = null;
Microsoft.Office.Interop.Outlook.MAPIFolder CalendarFolder = null;
Microsoft.Office.Interop.Outlook.Items outlookCalendarItems = null;
oApp = new Microsoft.Office.Interop.Outlook.Application();
mapiNamespace = oApp.GetNamespace("MAPI"); ;
CalendarFolder = mapiNamespace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar); outlookCalendarItems = CalendarFolder.Items;
outlookCalendarItems.IncludeRecurrences = true;
foreach (Microsoft.Office.Interop.Outlook.AppointmentItem item in outlookCalendarItems)
{
if (item.IsRecurring)
{
Microsoft.Office.Interop.Outlook.RecurrencePattern rp = item.GetRecurrencePattern();
DateTime first = new DateTime(2008, 8, 31, item.Start.Hour, item.Start.Minute, 0);
DateTime last = new DateTime(2008, 10, 1);
Microsoft.Office.Interop.Outlook.AppointmentItem recur = null;
for (DateTime cur = first; cur <= last; cur = cur.AddDays(1))
{
try
{
recur = rp.GetOccurrence(cur);
MessageBox.Show(recur.Subject + " -> " + cur.ToLongDateString());
}
catch
{ }
}
}
else
{
MessageBox.Show(item.Subject + " -> " + item.Start.ToLongDateString());
}
}
}
Seems problem similar to this>
http://www.add-in-express.com/forum/read.php?FID=5&TID=8953
So follow discussion on this link. It might helpful to you.

Related

outlook interop application doesn't get all emails C#

I'm trying to get outlook Email using Microsoft.Office.Interop.Outlook but in cases where the folder has a lot of emails (for example 1904 Emails) I'm getting only 571 emails.
here's my code:
Application oApp = new Application();
_NameSpace oNS = (_NameSpace)oApp.GetNamespace("MAPI");
MAPIFolder inbox = oNS.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
var emails = inbox.Items;
int emailsCount = emails.Count;
when I open outlook I see the number 1904 next to the Inbox folder, but when I scroll down I see the line "there are more items in this folder on the sever"
dose anyone know how can I download all my Emails using outlook interop?
this is my code from a working app:
A lot of it seems cracking a nut with a sledge hammer however, this hasnt failed me in many years.
MAPIFolder f;
int retries = 0;
while (!connected && retries < 2)
{
doUpdateStatus("Connecting");
try
{
app = new Application();
NameSpace ns = app.GetNamespace("MAPI");
f = ns.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
doUpdateStatus("Connected to outlook");
doUpdateStatus("Walking Outlook Folders .. Please wait");
try
{
doUpdateStatus("");
if (DoSync)
{
try
{
doUpdateStatus("Syncing");
SyncObject _syncObj = null;
_syncObj = ns.SyncObjects.AppFolders;
_syncObj.SyncEnd += _syncObj_SyncEnd;
ns.SendAndReceive(false);
syncing = true;
_syncObj.Start();
while (syncing)
{
Thread.Sleep(10);
}
connected = true;
}
catch
{
doUpdateStatus("Sync failed");
}
finally
{
syncing = false;
}
}
else
{
doUpdateStatus("Outlook sync disabled");
connected = true;
}
}
catch
{
doUpdateStatus("Unable to connect to Outlook and Load folders");
app.Quit();
retries++;
Thread.Sleep(5000);
}
}
catch
{
doUpdateStatus("Unable to connect to Outlook");
if (app!=null) app.Quit();
retries++;
Thread.Sleep(5000);
}
}
private static void _syncObj_SyncEnd()
{
syncing = false;
}
You can either force Outlook to download all items (make sure the slider in the Exchange account properties is set to "All' rather than something like "12 months") or you can reopen the folder in the online mode - in Extended MAPI (C++ or Delphi), you can do that by using the MAPI_NO_CACHE flag when calling IMAPISession::OpenEntry or IMsgStore::OpenEntry. If Extended MAPI is not an option, you can use Redemption (I am its author):
MAPI_NO_CACHE = &H200
MAPI_BEST_ACCESS = &H10
set OutlookFolder = Application.ActiveExplorer.CurrentFolder
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set OnlineFolder = Session.GetFolderFromID(OutlookFolder.EntryID, OutlookFolder.StoreID, MAPI_NO_CACHE + MAPI_BEST_ACCESS)
MsgBox OnlineFolder.Items.Count

Retrieve Public Outlook Calendar Appointments?

I am trying to retrieve the appointments for the same day from any given user's name.
So far, I am able to retrieve my own appointments for today with the code below.
else if (UserSelection == "2")
{
//Create the Outlook application
Outlook.Application oApplication = new Outlook.Application();
// Get the NameSpace and Logon information.
Outlook.NameSpace oNameSpace = oApplication.GetNamespace("mapi");
//Log on by using a dialog box to choose the profile.
oNameSpace.Logon(Missing.Value, Missing.Value, true, true);
// Get the Calendar folder.
Outlook.MAPIFolder oCalendar = oNameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
// Get the appointments (items) collection from the Calendar folder.
Outlook.Items oItems = oCalendar.Items;
oItems.IncludeRecurrences = true;
List<Outlook.AppointmentItem> lst = new List<Outlook.AppointmentItem>();
foreach (Outlook.AppointmentItem item in oItems)
{
if (item.Start.Day == DateTime.Today.Day && item.Start.Month == DateTime.Today.Month && item.Start.Year == DateTime.Today.Year)
{
Console.WriteLine("Organizer: " + item.Organizer);
Console.WriteLine("Start: " + item.Start.ToString());
Console.WriteLine("End: " + item.End.ToString());
Console.WriteLine("Location: " + item.Location);
Console.WriteLine("Recurring: " + item.IsRecurring);
Console.WriteLine("Subject: " + item.Subject);
Console.WriteLine("Attendees: " + item.OptionalAttendees);
Console.WriteLine("");
}
}
//Get the last appointment(item)
//Outlook.AppointmentItem oAppt = (Outlook.AppointmentItem)oItems.GetLast();
//Show the appointment(item) in outlook.
//oAppt.Display(true);
// Done. Log off.
oNameSpace.Logoff();
//Clean up.
oItems = null;
oCalendar = null;
oNameSpace = null;
oApplication = null;
Console.ReadLine();
This works fine. However, the following code below doesnt return the given user "userName"'s appointments.
if (UserSelection == "1")
//try (used for error handling)
{
string userName = Console.ReadLine();
Outlook.Application oApplication;
oApplication = new Outlook.Application();
Outlook.NameSpace oNameSpace = oApplication.GetNamespace("mapi");
oNameSpace.Logon(Missing.Value, Missing.Value, true, true);
Outlook.Recipient oRecip = (Outlook.Recipient)oNameSpace.CreateRecipient(userName);
Outlook.MAPIFolder oCalendar = (Outlook.MAPIFolder)oNameSpace.GetSharedDefaultFolder(oRecip, Outlook.OlDefaultFolders.olFolderCalendar);
// Get the appointments (items) collection from the Calendar folder.
Outlook.Items oItems = oCalendar.Items;
oItems.IncludeRecurrences = true;
List<Outlook.AppointmentItem> lst = new List<Outlook.AppointmentItem>();
foreach (Outlook.AppointmentItem item in oItems)
{
if (item.Start.Day == DateTime.Today.Day && item.Start.Month == DateTime.Today.Month && item.Start.Year == DateTime.Today.Year)
{
Console.WriteLine("Organizer: " + item.Organizer);
Console.WriteLine("Start: " + item.Start.ToString());
Console.WriteLine("End: " + item.End.ToString());
Console.WriteLine("Location: " + item.Location);
Console.WriteLine("Recurring: " + item.IsRecurring);
Console.WriteLine("Subject: " + item.Subject);
Console.WriteLine("Attendees: " + item.OptionalAttendees);
Console.WriteLine("");
}
}
//Show the appointment(item) in outlook.
//oAppt.Display(true);
// Done. Log off.
oNameSpace.Logoff();
// Clean up.
oItems = null;
oCalendar = null;
oNameSpace = null;
oApplication = null;
Console.ReadLine();
The code line producing the error is foreach (Outlook.AppointmentItem item in oItems)
The error returned is "An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in mscorlib.dll
Additional information: Exception from HRESULT: 0x8834010F"
Any help to make this work would be greatly appreciated, thanks.
I'd suggest starting from releasing underlying COM objects instantly. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. This is particularly important if your add-in attempts to enumerate more than 256 Outlook items in a collection that is stored on a Microsoft Exchange Server. If you do not release these objects in a timely manner, you can reach the limit imposed by Exchange on the maximum number of items opened at any one time. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. See Systematically Releasing Objects for more information.
Also I'd suggest using the Find/FindNext or Restrict methods of the Items class. You can read more about them in the following articles:
How To: Retrieve Outlook calendar items using Find and FindNext methods
How To: Use Restrict method in Outlook to get calendar items

Is there a better way to filter mails based on date?

Well I have run into a problem.
I am using the MS outlook API using C # to generate a few excel based reports from the emails that I receive.
Now initially when I started this, it was OK as the number emails were a little less in the folder. Now after a few days, the number has gone into thousands.
Application app = null;
_NameSpace ns = null;
MailItem item = null;
MAPIFolder inboxFolder = null;
MAPIFolder subFolder = null;
DateTime MyDateTime;
MyDateTime = new DateTime();
MyDateTime = DateTime.ParseExact(dateFilter, "yyyy-MM-dd HH:mm tt", null);
try
{
app = new Application();
ns = app.GetNamespace("MAPI");
ns.Logon(null, null, false, false);
inboxFolder = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
subFolder = inboxFolder.Folders["Alerts"];
for (int i = 1; i <= subFolder.Items.Count; i++)
{
item = (Microsoft.Office.Interop.Outlook.MailItem)subFolder.Items[i];
string subject = item.Subject;
DateTime sent = item.SentOn;
if (item.SentOn > MyDateTime && item.SentOn < MyDateTime.AddDays(1))
{//Do some logging
}}
Now the issue with the above code is that it starts searching from the last email received. This is causing it to increase the time it takes to reach the "filter".
I need suggestions to improve my code, if any.
Thanks for reading me out.
Before your loop, get a collection of items from subFolder filtered by the Restrict method.
You can use your date ranges in the filter string that you use (I've not written it here since I'm not in a position to test it and don't want to mislead you - a search should give plenty of examples). Then just loop/iterate over the resulting collection which should then contain just the items you need.
Microsoft.Office.Interop.Outlook.Items restrictedItems = subFolder.Items.Restrict("*filter*");
for (int i = 1; i <= restrictedItems.Count; i++)...
This is how I filter Outlook appointments.
For mails you need .olFolderInbox instead of .olFolderCalendar.
https://learn.microsoft.com/en-us/dotnet/api/microsoft.office.interop.outlook._items.restrict?view=outlook-pia
Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.Application();
NameSpace mapiNamespace = oApp.GetNamespace("MAPI");
MAPIFolder calendarFolder = mapiNamespace.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
DateTime filterDate = DateTime.Now;
string filterDateString = filterDate.Day + "/" + filterDate.Month + "/" + filterDate.Year + " 1:00am";
string filter = "[CreationTime] > '" + string.Format(filterDateString, "ddddd h:nn AMPM") + "'";
Items outlookCalendarItems = calendarFolder.Items.Restrict(filter);
foreach (AppointmentItem item in outlookCalendarItems)
{
// Here I write to our database
}

Retrieve current Outlook appointment

I need the current appointment. If no current appointment then the next or even previous appointment.
I figure to use Restrict to limit the set of appointments, and then choose either the first or last appointment depending on the restrict argument (e.g. Restrict to appointments ending after current time, or appointments starting before current time).
I'm having trouble with the string filter needed as argument.
A simple VB example (code stump):
myStart = Format(Date, "mm/dd/yyyy hh:mm AMPM")
strRestriction = "[Start] <= '" & myStart & "'"
'Restrict the Items collection
Set oResItems = oItems.Restrict(strRestriction)
'Sort
oResItems.Sort "[Start]"
I am attempting to do the same in C#.
// Create the Outlook application.
Outlook.Application oApp = new Outlook.Application();
// Get the NameSpace and Logon information.
// Outlook.NameSpace oNS = (Outlook.NameSpace)oApp.GetNamespace("mapi");
Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
//Log on by using a dialog box to choose the profile.
oNS.Logon(Missing.Value, Missing.Value, true, true);
// Get the Calendar folder.
Outlook.MAPIFolder oCalendar = oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
// Get the Items (Appointments) collection from the Calendar folder.
oItems = oCalendar.Items;
oItems.IncludeRecurrences = true;
// THIS IS THE PROBLEM AREA
String filter = "[Start] <= '" + DateTime.Now.ToString("MM/dd/yyyy hh:mm AMPM") + "'";
Outlook.Items restrictedItems = oItems.Restrict(filter);
// Take the last item on the list - should be current or next appointment
restrictedItems.Sort("[Start]");
Outlook.AppointmentItem oAppt = restrictedItems.GetLast();
// Done. Log off.
oNS.Logoff();
I imagine since the filter is a string, the date format needs to be yyyy/mm/dd HH:mm:ss? I can't find any documentation on how to manipulate the [Start], like parsing it to a date or something.
Depending on the date format, I will either get the wrong appointment, or will be unable to use GetLast due to the filter excluding all appointments.
I've seen examples, but either they loop through the appointments (too inefficient), or the date formats look like they can't be trusted to return the correct appointment (For example https://social.msdn.microsoft.com/Forums/vstudio/en-US/c6a8bd21-6534-43be-b23e-1068651da92e/retrieve-appointment-items-from-outlook-2007-calendar-restrict?forum=vsto, which seems to have the date hardcoded instead if using DateTime.Now.)
UPDATE: I'm currently looping through like shown below. Any suggestions for more efficient code?
DateTime currentTime = DateTime.Now;
foreach (Outlook.AppointmentItem item in oItems)
{
if (item.Start <= currentTime && item.End.Subtract(new TimeSpan(0, 10, 0)) > currentTime)
{
appointmentArrayList.Add(item);
}
}
This is your issue:
DateTime.Now.ToString("MM/dd/yyyy hh:mm AMPM")
What I think you're going for is:
DateTime.Now.ToString("MM/dd/yyyy hh:mm tt", CultureInfo.InvariantCulture)
By following the information found here, I was able to get it to work using "yyyy-MM-dd HH:mm" as the format string for the toString call.
Hope this helps.
This code works to show Outlook appointments from today onwards:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DemoAppointmentsInRange();
}
private void DemoAppointmentsInRange()
{
Application a = new Application();
Microsoft.Office.Interop.Outlook.Folder calFolder = a.Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar) as Microsoft.Office.Interop.Outlook.Folder;
DateTime start = DateTime.Now;
DateTime end = start.AddDays(5);
Microsoft.Office.Interop.Outlook.Items rangeAppts = GetAppointmentsInRange(calFolder, start, end);
if (rangeAppts != null)
{
foreach (Microsoft.Office.Interop.Outlook.AppointmentItem appt in rangeAppts)
{
Response.Write("Subject: " + appt.Subject + " "+" Start: "+appt.Start.ToString()+" "+"End:"+appt.End.ToString()+"<br/>");
}
}
}
private Microsoft.Office.Interop.Outlook.Items GetAppointmentsInRange(
Microsoft.Office.Interop.Outlook.Folder folder, DateTime startTime, DateTime endTime)
{
string filter = "[Start] >= '"+ startTime.ToString("g")+ "' AND [End] <= '" + endTime.ToString("g") + "'";
//Response.Write(filter);
try
{
Microsoft.Office.Interop.Outlook.Items calItems = folder.Items;
calItems.IncludeRecurrences = true;
calItems.Sort("[Start]", Type.Missing);
Microsoft.Office.Interop.Outlook.Items restrictItems = calItems.Restrict(filter);
if (restrictItems.Count > 0)
{
return restrictItems;
}
else
{
return null;
}
}
catch
{
return null;
}
}
}
I couldn't figure out DateTime format, but I found this article:
https://learn.microsoft.com/en-us/office/vba/outlook/how-to/search-and-filter/filtering
Then I realized that they have a concept called "DASL Queries", reading furthermore I found this related to filtering with DateTime:
https://learn.microsoft.com/en-us/office/vba/outlook/how-to/search-and-filter/filtering-items-using-a-date-time-comparison
And I've decided to get all today's AppointmentItem(s) this way:
public enum MacroName
{
today,
tomorrow,
yesterday,
next7days,
last7days,
nextweek,
thisweek,
lastweek,
nextmonth,
thismonth,
lastmonth
}
private Outlook.Items GetAppointmentsWithMacro(Outlook.Folder folder, MacroName macro)
{
string strFilter = "#SQL=%" + macro.ToString() + "(\"urn:schemas:calendar:dtstart\")%";
try
{
Outlook.Items calItems = folder.Items;
calItems.IncludeRecurrences = true;
calItems.Sort("[Start]", Type.Missing);
Outlook.Items restrictItems = calItems.Restrict(strFilter);
if (restrictItems.Count > 0)
{
return restrictItems;
}
else
{
return null;
}
}
catch { return null; }
}
I want to be safest as possible because it seems that filtering by DateTime is related to local DateTime settings. By using the "today" macro I was able for the first time to extract the correct information from Outlook appointments store

.NET: Get all Outlook calendar items

How can I get all items from a specific calendar (for a specific date).
Lets say for instance that I have a calendar with a recurring item every Monday evening. When I request all items like this:
CalendarItems = CalendarFolder.Items;
CalendarItems.IncludeRecurrences = true;
I only get 1 item...
Is there an easy way to get all items (main item + derived items) from a calendar?
In my specific situation it can be possible to set a date limit but it would be cool just to get all items (my recurring items are time limited themselves).
I'm using the Microsoft Outlook 12 Object library (Microsoft.Office.Interop.Outlook).
I've studied the docs and this is my result:
I've put a time limit of one month hard-coded, but this is just an example.
public void GetAllCalendarItems()
{
Microsoft.Office.Interop.Outlook.Application oApp = null;
Microsoft.Office.Interop.Outlook.NameSpace mapiNamespace = null;
Microsoft.Office.Interop.Outlook.MAPIFolder CalendarFolder = null;
Microsoft.Office.Interop.Outlook.Items outlookCalendarItems = null;
oApp = new Microsoft.Office.Interop.Outlook.Application();
mapiNamespace = oApp.GetNamespace("MAPI"); ;
CalendarFolder = mapiNamespace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar);
outlookCalendarItems = CalendarFolder.Items;
outlookCalendarItems.IncludeRecurrences = true;
foreach (Microsoft.Office.Interop.Outlook.AppointmentItem item in outlookCalendarItems)
{
if (item.IsRecurring)
{
Microsoft.Office.Interop.Outlook.RecurrencePattern rp = item.GetRecurrencePattern();
DateTime first = new DateTime(2008, 8, 31, item.Start.Hour, item.Start.Minute, 0);
DateTime last = new DateTime(2008, 10, 1);
Microsoft.Office.Interop.Outlook.AppointmentItem recur = null;
for (DateTime cur = first; cur <= last; cur = cur.AddDays(1))
{
try
{
recur = rp.GetOccurrence(cur);
MessageBox.Show(recur.Subject + " -> " + cur.ToLongDateString());
}
catch
{ }
}
}
else
{
MessageBox.Show(item.Subject + " -> " + item.Start.ToLongDateString());
}
}
}
I believe that you must Restrict or Find in order to get recurring appointments, otherwise Outlook won't expand them. Also, you must Sort by Start before setting IncludeRecurrences.
I wrote similar code, but then found the export functionality:
Application outlook;
NameSpace OutlookNS;
outlook = new ApplicationClass();
OutlookNS = outlook.GetNamespace("MAPI");
MAPIFolder f = OutlookNS.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
CalendarSharing cs = f.GetCalendarExporter();
cs.CalendarDetail = OlCalendarDetail.olFullDetails;
cs.StartDate = new DateTime(2011, 11, 1);
cs.EndDate = new DateTime(2011, 12, 31);
cs.SaveAsICal("c:\\temp\\cal.ics");
LinqPad snipped that works for me:
//using Microsoft.Office.Interop.Outlook
Application a = new Application();
Items i = a.Session.GetDefaultFolder(OlDefaultFolders.olFolderCalendar).Items;
i.IncludeRecurrences = true;
i.Sort("[Start]");
i = i.Restrict(
"[Start] >= '10/1/2013 12:00 AM' AND [End] < '10/3/2013 12:00 AM'");
var r =
from ai in i.Cast<AppointmentItem>()
select new {
ai.Categories,
ai.Start,
ai.Duration
};
r.Dump();
If you need want to access the shared folder from your friend, then you can set your friend as the recipient. Requirement: his calendar must be shared first.
// Set recepient
Outlook.Recipient oRecip = (Outlook.Recipient)oNS.CreateRecipient("abc#yourmail.com");
// Get calendar folder
Outlook.MAPIFolder oCalendar = oNS.GetSharedDefaultFolder(oRecip, Outlook.OlDefaultFolders.olFolderCalendar);
There is no need to expand recurring items manually. Just ensure you sort the items before using IncludeRecurrences.
Here is VBA example:
tdystart = VBA.Format(#8/1/2012#, "Short Date")
tdyend = VBA.Format(#8/31/2012#, "Short Date")
Dim folder As MAPIFolder
Set appointments = folder.Items
appointments.Sort "[Start]" ' <-- !!! Sort is a MUST
appointments.IncludeRecurrences = True ' <-- This will expand reccurent items
Set app = appointments.Find("[Start] >= """ & tdystart & """ and [Start] <= """ & tdyend & """")
While TypeName(app) <> "Nothing"
MsgBox app.Start & " " & app.Subject
Set app = appointments.FindNext
Wend
public void GetAllCalendarItems()
{
DataTable sample = new DataTable(); //Sample Data
sample.Columns.Add("Subject", typeof(string));
sample.Columns.Add("Location", typeof(string));
sample.Columns.Add("StartTime", typeof(DateTime));
sample.Columns.Add("EndTime", typeof(DateTime));
sample.Columns.Add("StartDate", typeof(DateTime));
sample.Columns.Add("EndDate", typeof(DateTime));
sample.Columns.Add("AllDayEvent", typeof(bool));
sample.Columns.Add("Body", typeof(string));
listViewContacts.Items.Clear();
oApp = new Outlook.Application();
oNS = oApp.GetNamespace("MAPI");
oCalenderFolder = oNS.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar);
outlookCalendarItems = oCalenderFolder.Items;
outlookCalendarItems.IncludeRecurrences = true;
// DataTable sample = new DataTable();
foreach (Microsoft.Office.Interop.Outlook.AppointmentItem item in outlookCalendarItems)
{
DataRow row = sample.NewRow();
row["Subject"] = item.Subject;
row["Location"] = item.Location;
row["StartTime"] = item.Start.TimeOfDay.ToString();
row["EndTime"] = item.End.TimeOfDay.ToString();
row["StartDate"] = item.Start.Date;
row["EndDate"] = item.End.Date;
row["AllDayEvent"] = item.AllDayEvent;
row["Body"] = item.Body;
sample.Rows.Add(row);
}
sample.AcceptChanges();
foreach (DataRow dr in sample.Rows)
{
ListViewItem lvi = new ListViewItem(dr["Subject"].ToString());
lvi.SubItems.Add(dr["Location"].ToString());
lvi.SubItems.Add(dr["StartTime"].ToString());
lvi.SubItems.Add(dr["EndTime"].ToString());
lvi.SubItems.Add(dr["StartDate"].ToString());
lvi.SubItems.Add(dr["EndDate"].ToString());
lvi.SubItems.Add(dr["AllDayEvent"].ToString());
lvi.SubItems.Add(dr["Body"].ToString());
this.listViewContacts.Items.Add(lvi);
}
oApp = null;
oNS = null;
}
I found this article very useful: https://learn.microsoft.com/en-us/office/client-developer/outlook/pia/how-to-search-and-obtain-appointments-in-a-time-range
It demonstrates how to get calendar entries in a specified time range. It worked for me. Here is the source code from the article for your convenience :)
using Outlook = Microsoft.Office.Interop.Outlook;
private void DemoAppointmentsInRange()
{
Outlook.Folder calFolder = Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar)
as Outlook.Folder;
DateTime start = DateTime.Now;
DateTime end = start.AddDays(5);
Outlook.Items rangeAppts = GetAppointmentsInRange(calFolder, start, end);
if (rangeAppts != null)
{
foreach (Outlook.AppointmentItem appt in rangeAppts)
{
Debug.WriteLine("Subject: " + appt.Subject
+ " Start: " + appt.Start.ToString("g"));
}
}
}
/// <summary>
/// Get recurring appointments in date range.
/// </summary>
/// <param name="folder"></param>
/// <param name="startTime"></param>
/// <param name="endTime"></param>
/// <returns>Outlook.Items</returns>
private Outlook.Items GetAppointmentsInRange(
Outlook.Folder folder, DateTime startTime, DateTime endTime)
{
string filter = "[Start] >= '"
+ startTime.ToString("g")
+ "' AND [End] <= '"
+ endTime.ToString("g") + "'";
Debug.WriteLine(filter);
try
{
Outlook.Items calItems = folder.Items;
calItems.IncludeRecurrences = true;
calItems.Sort("[Start]", Type.Missing);
Outlook.Items restrictItems = calItems.Restrict(filter);
if (restrictItems.Count > 0)
{
return restrictItems;
}
else
{
return null;
}
}
catch { return null; }
}
Try this:
public List<AdxCalendarItem> GetAllCalendarItems()
{
Outlook.Application OutlookApp = new Outlook.Application();
List<AdxCalendarItem> result = new List<AdxCalendarItem>();
Outlook._NameSpace session = OutlookApp.Session;
if (session != null)
try
{
object stores = session.GetType().InvokeMember("Stores", BindingFlags.GetProperty, null, session, null);
if (stores != null)
try
{
int count = (int)stores.GetType().InvokeMember("Count", BindingFlags.GetProperty, null, stores, null);
for (int i = 1; i <= count; i++)
{
object store = stores.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, stores, new object[] { i });
if (store != null)
try
{
Outlook.MAPIFolder calendar = null;
try
{
calendar = (Outlook.MAPIFolder)store.GetType().InvokeMember("GetDefaultFolder", BindingFlags.GetProperty, null, store, new object[] { Outlook.OlDefaultFolders.olFolderCalendar });
}
catch
{
continue;
}
if (calendar != null)
try
{
Outlook.Folders folders = calendar.Folders;
try
{
Outlook.MAPIFolder subfolder = null;
for (int j = 1; j < folders.Count + 1; j++)
{
subfolder = folders[j];
try
{
// add subfolder items
result.AddRange(GetAppointmentItems(subfolder));
}
finally
{ if (subfolder != null) Marshal.ReleaseComObject(subfolder); }
}
}
finally
{ if (folders != null) Marshal.ReleaseComObject(folders); }
// add root items
result.AddRange(GetAppointmentItems(calendar));
}
finally { Marshal.ReleaseComObject(calendar); }
}
finally { Marshal.ReleaseComObject(store); }
}
}
finally { Marshal.ReleaseComObject(stores); }
}
finally { Marshal.ReleaseComObject(session); }
return result;
}
List<AdxCalendarItem> GetAppointmentItems(Outlook.MAPIFolder calendarFolder)
{
List<AdxCalendarItem> result = new List<AdxCalendarItem>();
Outlook.Items calendarItems = calendarFolder.Items;
try
{
calendarItems.IncludeRecurrences = true;
Outlook.AppointmentItem appointment = null;
for (int j = 1; j < calendarItems.Count + 1; j++)
{
appointment = calendarItems[j] as Outlook.AppointmentItem;
try
{
AdxCalendarItem item = new AdxCalendarItem(
calendarFolder.Name,
appointment.Subject,
appointment.Location,
appointment.Start,
appointment.End,
appointment.Start.Date,
appointment.End.Date,
appointment.AllDayEvent,
appointment.Body);
result.Add(item);
}
finally
{
{ Marshal.ReleaseComObject(appointment); }
}
}
}
finally { Marshal.ReleaseComObject(calendarItems); }
return result;
}
}
public class AdxCalendarItem
{
public string CalendarName;
public string Subject;
public string Location;
public DateTime StartTime;
public DateTime EndTime;
public DateTime StartDate;
public DateTime EndDate;
public bool AllDayEvent;
public string Body;
public AdxCalendarItem(string CalendarName, string Subject, string Location, DateTime StartTime, DateTime EndTime,
DateTime StartDate, DateTime EndDate, bool AllDayEvent, string Body)
{
this.CalendarName = CalendarName;
this.Subject = Subject;
this.Location = Location;
this.StartTime = StartTime;
this.EndTime = EndTime;
this.StartDate = StartDate;
this.EndDate = EndDate;
this.AllDayEvent = AllDayEvent;
this.Body = Body;
}
}
Microsoft.Office.Interop.Outlook.Application oApp = null;
Microsoft.Office.Interop.Outlook.NameSpace mapiNamespace = null;
Microsoft.Office.Interop.Outlook.MAPIFolder CalendarFolder = null;
Microsoft.Office.Interop.Outlook.Items outlookCalendarItems = null;
oApp = new Microsoft.Office.Interop.Outlook.Application();
mapiNamespace = oApp.GetNamespace("MAPI"); ;
CalendarFolder = mapiNamespace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar);
outlookCalendarItems = CalendarFolder.Items;
outlookCalendarItems.IncludeRecurrences = true;
foreach (Microsoft.Office.Interop.Outlook.AppointmentItem item in outlookCalendarItems)
{
if (item.IsRecurring)
{
Microsoft.Office.Interop.Outlook.RecurrencePattern rp = item.GetRecurrencePattern();
// get all date
DateTime first = new DateTime( item.Start.Hour, item.Start.Minute, 0);
DateTime last = new DateTime();
Microsoft.Office.Interop.Outlook.AppointmentItem recur = null;
for (DateTime cur = first; cur <= last; cur = cur.AddDays(1))
{
try
{
recur = rp.GetOccurrence(cur);
MessageBox.Show(recur.Subject + " -> " + cur.ToLongDateString());
}
catch
{ }
}
}
else
{
MessageBox.Show(item.Subject + " -> " + item.Start.ToLongDateString());
}
}
}
it is working I try it but you need to add reference about
Microsoft outlook
Here's a combination of a few answers to get entries from the past 30 days. Will output to console but you can take the console log output and save to a file or whatever you want from there. Thanks to everyone for posting their code here, was very helpful!
using Microsoft.Office.Interop.Outlook;
void GetAllCalendarItems()
{
Microsoft.Office.Interop.Outlook.Application oApp = null;
Microsoft.Office.Interop.Outlook.NameSpace mapiNamespace = null;
Microsoft.Office.Interop.Outlook.MAPIFolder CalendarFolder = null;
Microsoft.Office.Interop.Outlook.Items outlookCalendarItems = null;
oApp = new Microsoft.Office.Interop.Outlook.Application();
mapiNamespace = oApp.GetNamespace("MAPI"); ;
CalendarFolder = mapiNamespace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar);
outlookCalendarItems = CalendarFolder.Items;
outlookCalendarItems.IncludeRecurrences = false;
Console.WriteLine("Showing Calendar Items From the last 30 days");
//Set your dates here...
DateTime startTime = DateTime.Now.AddDays(-31);
DateTime endTime = DateTime.Now;
string filter = "[Start] >= '"
+ startTime.ToString("g")
+ "' AND [End] <= '"
+ endTime.ToString("g") + "'";
try
{
outlookCalendarItems.Sort("[Start]", Type.Missing);
foreach (Microsoft.Office.Interop.Outlook.AppointmentItem item in outlookCalendarItems.Restrict(filter))
{
Console.WriteLine(item.Subject + " -> " + item.Start.ToLongDateString());
}
}
catch { }
Console.WriteLine("Finished");
}
GetAllCalendarItems();
calendarFolder =
mapiNamespace.GetDefaultFolder(
Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderCalendar);

Categories

Resources