I want to list all Outlook appointment times in a specific time range and I am only interested in start and end time of the appointments.
I'm using this code so far:
DateTime startTime = DateTime.Now.AddDays(2);
DateTime endTime = DateTime.Now.AddDays(3);
var outlookApplication = new Outlook.Application();
Outlook.NameSpace outlookNamespace = outlookApplication.GetNamespace("MAPI");
var recip = outlookNamespace.CreateRecipient("<valid contact>");
if (recip.Resolve())
{
var calendarItems = outlookNamespace.GetSharedDefaultFolder(recip, OlDefaultFolders.olFolderCalendar).Items;
calendarItems.IncludeRecurrences = true;
var filter = String.Format("[Start] >= '{0}' And [End] < '{1}'", startTime.ToShortDateString(), endTime.ToShortDateString());
calendarItems.Sort("[Start]");
calendarItems = calendarItems.Restrict(filter);
var result = calendarItems.Cast<AppointmentItem>().Select(x => x);
}
The code retrieves nearly all appointments, but not the private ones. How can I get the private appointments too?
Outlook always filters out private appointments form the shared folders even if they are perfectly accessible using MAPI. If using Redemption (I am its author) is an option, you can use RDOFolder.GetActivitiesForTimeRange - it returns private appointments.
Related
New to programming and trying to create this project for work. I have a text file inputted that has a list of usernames. I want the code to take the usernames from the text file and look them up in Outlook to give me a "true" or "false" if there is a match for the user in the system. How do I connect Outlook to the code with MAPI or an API? The code I have so far is below.
namespace QC_OUTLOOK
{
internal class Program
{
private static object MessageBox;
private static object objFile;
private static int i;
private static object Strings;
private static object response;
static int Main(string[] args)
{
string filePath = #"C:\Users\Documents\QC\User_list.txt";
// string[] lines = File.ReadAllLines(filePath);
List<string> lines = new List<string>();
lines = File.ReadAllLines(filePath).ToList();
using (StreamWriter streamWriter = File.CreateText(filePath));
foreach (String line in lines)
{
Console.WriteLine(line);
}
Console.ReadLine();
{
Outlook._Application oApp = new OutLook.Application();
//Get MAPI namespace
Outlook.AddressLists oNS = oNS.AddressLists;
Outlook.AddressList oGal = oALs.Item("Global Address List");
//Get all entries
Outlook.AddressEntries oEntries = oGal.AddressEntries;
// Get first user found
Outlook.AddressEntry oEntry = oEntries.GetFirst();
Outlook_UserName_Output = "";
response = sa.GetAllUsers;
Console.WriteLine(response);
//
UserCount = 0;
UsersFound = 0;
LastNameMatches = 0;
InactiveUser_Count = 0;
Inconsistent_EmailAddrs = 0;
GIS_UserCount = 0;
TodaysDate = DateTime.Today;
object value = objFile.WriteLine("Date:" + TodaysDate);
object value1 = objFile.WriteLine("QC_UserID, QC_FullName, OutLook_Last_Name, OutLook_First_Name");
for (i = 1; i <= Strings.Len(response) ; i++);
Outlook.Application oApp = new Outlook.Application();
// Get the MAPI namespace.
Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
oNS.Logon(Missing.Value, Missing.Value, false, true);
Outlook.MAPIFolder oInbox = oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
}
DataTable dt = new DataTable();
dt.Columns.Add("FirstName");
dt.Columns.Add("LastName");
Microsoft.Office.Interop.Outlook.Items OutlookItems;
Microsoft.Office.Interop.Outlook.Application outlookObj = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MAPIFolder Folder_Contacts = (MAPIFolder)outlookObj.Session.GetDefaultFolder(OlDefaultFolders.olFolderContacts);
OutlookItems = Folder_Contacts.Items;
foreach (var item in OutlookItems)
{
var contact = item as ContactItem;
if (contact != null)
{
DataRow dr = dt.NewRow();
dr["FirstName"] = contact.FirstName;
dr["LastName"] = contact.LastName;
dt.Rows.Add(dr);
}
First of all, creating a new Outlook Application instance multiple times in the code is not the best way to go:
Microsoft.Office.Interop.Outlook.Application outlookObj = new Microsoft.Office.Interop.Outlook.Application();
Outlook is a singleton. You can't run two instances of Outlook on the system at the same time. So, I'd suggest keeping the application object and re-use it where possible.
Iterating over all items in the Outlook folder is not really a good idea. Instead, use the Find/FindNext or Restrict methods of the Items class. Read more about these methods in the following articles:
How To: Retrieve Outlook Contact items using Restrict method
How To: Use Find and FindNext to retrieve Outlook Contact items
But better is to use the NameSpace.CreateRecipient method which creates a Recipient object and can be used to verify a given name against an address book. The Recipient.Resolve method attempts to resolve a created Recipient object against the Address Book. That's exactly what you are looking for!
I have implemented an SSIS Package getting all appoinments from a particular shared outlook calendar.
What I noticed is that the recurring ones are NOT returned because they are a kind of virtual. Only the Master of them will give me the ability to get also the recurring ones.
Looking at my code, do you have any suggestions how I can retrieve also the recurring ones?
I'm just a little stuck and any hint is highly appreciated!
#region Namespaces
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using Microsoft.Exchange.WebServices.Data;
#endregion
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
string sharedCalendarID;
static FolderId FindPublicFolder(ExchangeService myService, FolderId baseFolderId, string folderName)
{
// search using paging.
FolderView folderView = new FolderView(10, 0);
folderView.OffsetBasePoint = OffsetBasePoint.Beginning;
// need only DisplayName and Id of every folder
// reduce the property set to the properties
folderView.PropertySet = new PropertySet(FolderSchema.DisplayName, FolderSchema.Id);
FindFoldersResults folderResults;
do
{
folderResults = myService.FindFolders(baseFolderId, folderView);
foreach (Folder folder in folderResults)
if (String.Compare(folder.DisplayName, folderName, StringComparison.OrdinalIgnoreCase) == 0)
return folder.Id;
if (folderResults.NextPageOffset.HasValue)
// go to the next page
folderView.Offset = folderResults.NextPageOffset.Value;
}
while (folderResults.MoreAvailable);
return null;
}
public override void CreateNewOutputRows()
{
// IMPORTANT: ExchangeService is NOT thread safe, so one should create an instance of
// ExchangeService whenever one needs it.
ExchangeService myService = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
myService.Credentials = new NetworkCredential("username", "password");
myService.Url = new Uri("https://......Exchange.asmx");
// next line is very practical during development phase or for debugging
myService.TraceEnabled = true;
Folder myPublicFoldersRoot = Folder.Bind(myService, WellKnownFolderName.PublicFoldersRoot);
string myPublicFolderPath = #"CHI\WIED PFL Agenda";
string[] folderPath = myPublicFolderPath.Split('\\');
FolderId fId = myPublicFoldersRoot.Id;
foreach (string subFolderName in folderPath)
{
fId = FindPublicFolder(myService, fId, subFolderName);
if (fId == null)
{
// No Calendar found
return;
}
}
// verify
Folder folderFound = Folder.Bind(myService, fId);
if (String.Compare(folderFound.FolderClass, "IPF.Appointment", StringComparison.Ordinal) == 0)
{
sharedCalendarID = fId.ToString(); ;
}
else
return;
CalendarFolder myPublicFolder = CalendarFolder.Bind(myService,
//WellKnownFolderName.Calendar,
fId,
PropertySet.FirstClassProperties);
// search using paging. page size 10
ItemView viewCalendar = new ItemView(10);
// include all properties which we need in the view
// comment the next line then ALL properties will be read from the server.
//viewCalendar.PropertySet = new PropertySet(ItemSchema.Subject, ItemSchema.Id);
viewCalendar.Offset = 0;
viewCalendar.OffsetBasePoint = OffsetBasePoint.Beginning;
viewCalendar.OrderBy.Add(ContactSchema.DateTimeCreated, SortDirection.Descending);
FindItemsResults<Item> findResultsCalendar;
do
{
//SearchFilter searchFilter = new SearchFilter.IsGreaterThan(AppointmentSchema.Start, DateTime.Today);
var searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And,
new SearchFilter.IsEqualTo(ItemSchema.ItemClass, "IPM.Appointment"),
new SearchFilter.IsGreaterThanOrEqualTo(AppointmentSchema.Start, DateTime.Now),
new SearchFilter.IsLessThan(AppointmentSchema.Start, DateTime.Now.AddDays(4)));
findResultsCalendar = myPublicFolder.FindItems(searchFilter, viewCalendar);
//get additional properties for each item returned by view, do this as view cannot return a lot of useful stuff like attendees
ServiceResponseCollection<ServiceResponse> addProperties =
myService.LoadPropertiesForItems(from Item item in findResultsCalendar select item,
new PropertySet(
BasePropertySet.IdOnly,
AppointmentSchema.Body,
AppointmentSchema.Subject,
AppointmentSchema.Start,
AppointmentSchema.End,
AppointmentSchema.IsRecurring,
AppointmentSchema.AppointmentType
));
List<Appointment> additionalProperties = new List<Appointment>(addProperties.Count);
if (addProperties != null)
{
foreach (ServiceResponse currentResponce in addProperties)
{
additionalProperties.Add(((Appointment)((GetItemResponse)currentResponce).Item));
}
}
foreach (Item item in findResultsCalendar)
{
Appointment appt = item as Appointment;
if (item is Appointment || appt.AppointmentType == AppointmentType.RecurringMaster)
{
Appointment currentAppointmentAddProps = null;
currentAppointmentAddProps = additionalProperties.Find(
delegate(Appointment arg)
{
return arg.Id == item.Id;
}
);
//convert to int wether the Appointment is recurring or not
int isRecurring = currentAppointmentAddProps.IsRecurring ? 1 : 0;
Appointment appoint = item as Appointment;
OutputRecordSetBuffer.AddRow();
OutputRecordSetBuffer.ActualEndDate = currentAppointmentAddProps.End;
OutputRecordSetBuffer.ActualStartDate = currentAppointmentAddProps.Start;
OutputRecordSetBuffer.Subject = appoint.Subject;
OutputRecordSetBuffer.EntryID = Guid.NewGuid();
//OutputRecordSetBuffer.Detail = appoint.Body.ToString();
//OutputRecordSetBuffer.CalendarID = fId.ToString();
//OutputRecordSetBuffer.AppointmentID = appoint.Id.ToString();
OutputRecordSetBuffer.CalendarID = sharedCalendarID;
OutputRecordSetBuffer.AppointmentID = Guid.NewGuid();
OutputRecordSetBuffer.IsRecurring = isRecurring;
}
}
if (findResultsCalendar.NextPageOffset.HasValue)
// go to the next page
viewCalendar.Offset = findResultsCalendar.NextPageOffset.Value;
}
while (findResultsCalendar.MoreAvailable);
}
}
I have solved my issue on my own :)
Instead of using the ItemView class, I used the CalendarView class.
CalendarView expands also the recurring appointments, thats it :)
I'm currently trying to retrieve public Appointments of a users Calendar in Outlook (with Exchange2013) to a DataSet to be displayed later on.
Here's the relevant code so far:
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
service.AutodiscoverUrl("mail#mycompany.com", RedirectionCallback);
DateTime reportDate = dateTimePicker1.Value;
DateTime startDate = new DateTime(reportDate.Year, reportDate.Month, reportDate.Day, 0, 0, 1);
DateTime endDate = startDate.AddHours(23);
endDate = endDate.AddMinutes(59);
CalendarFolder calendar = CalendarFolder.Bind(service, new FolderId(WellKnownFolderName.Calendar, "somemail#mycompany.com"));
CalendarView cView = new CalendarView(startDate, endDate);
cView.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End, AppointmentSchema.Location);
// get appointment collection
FindItemsResults<Appointment> appointments = calendar.FindAppointments(cView);
// transfer to DataSet
DataSet1.Tables[0].Rows.Clear();
int i = 0;
foreach (Appointment a in appointments) {
DataSet1.Tables[0].Rows.Add(
i++.ToString(),
a.Subject.ToString(),
a.Start.ToString(),
a.End.ToString(),
a.Location.ToString());
}
An exception is being shown in the Line
CalendarFolder calendar = CalendarFolder.Bind(service, new FolderId(WellKnownFolderName.Calendar, "somemail#mycompany.com"));
Any ideas what I'm doing wrong here? Or is there even a completely other way on how to approach my problem?
The account which you are using to connect tho the exchange server doesn't have permission to read the mailbox of somemail#mycompany.com. Try to get a super user privilege for the account. Hope this is useful.
I am working on a Windows Phone 8.1 application, and this app want to get the meetings from Calendar.
I am using the Windows Runtime api to get all appointment like this:
AppointmentStore appointmentStore = await AppointmentManager.RequestStoreAsync(AppointmentStoreAccessType.AllCalendarsReadOnly);
IReadOnlyList<Windows.ApplicationModel.Appointments.Appointment> appointments = await appointmentStore.FindAppointmentsAsync(DateTime.Now, TimeSpan.FromHours(24)); ;
foreach (var appointment in appointments)
{
var persistentId = appointment.RoamingId;
var details = appointment.Details;//the details is empty, why
var invitees = appointment.Invitees;//the invitees is also empty, why?
}
Actually, I tried the Microsoft Phone api, I can get the details and attendees(invitees). However, the Microsoft Phone api can't get the appointment ID. Can anybody throw me some light how to get both appointment ID, and details/invitees? Thanks!
Appointments appts = new Appointments();
//Identify the method that runs after the asynchronous search completes.
appts.SearchCompleted += new EventHandler<AppointmentsSearchEventArgs>(Calendar_SearchCompleted);
DateTime start = DateTime.Now;
DateTime end = start.AddDays(1);
int max = 100;
appts.SearchAsync(start, end, max, "test");
private async void Calendar_SearchCompleted(object sender, AppointmentsSearchEventArgs e)
{
foreach (Microsoft.Phone.UserData.Appointment appt in e.Results)
{
var details = appt.Details;//I can get the details
var participants = new ObservableCollection<Person>();
var attendees = appt.Attendees;
if (attendees != null)
{
foreach (var attende in attendees)
{
Person attendPerson = new Person()
{
Email = attende.EmailAddress,
FullName = attende.DisplayName,
PersonID = attende.EmailAddress
};
participants.Add(attendPerson);
}
}
....
}
}
Your need to add FindAppointmentsOptions to get get whatever detail you want, try below code
AppointmentStore appointmentStore = await AppointmentManager.RequestStoreAsync(AppointmentStoreAccessType.AllCalendarsReadOnly);
FindAppointmentsOptions options = new FindAppointmentsOptions();
options.MaxCount = 100;
options.FetchProperties.Add(AppointmentProperties.Subject);
options.FetchProperties.Add(AppointmentProperties.Location);
options.FetchProperties.Add(AppointmentProperties.Invitees);
options.FetchProperties.Add(AppointmentProperties.Details);
options.FetchProperties.Add(AppointmentProperties.StartTime);
options.FetchProperties.Add(AppointmentProperties.ReplyTime);
IReadOnlyList<Windows.ApplicationModel.Appointments.Appointment> appointments = await appointmentStore.FindAppointmentsAsync(DateTime.Now, TimeSpan.FromHours(24), options);
foreach (var appointment in appointments)
{
var persistentId = appointment.RoamingId;
var details = appointment.Details;//the details is empty, why
var invitees = appointment.Invitees;//the invitees is also empty, why?
}
I have a program which fetches appointments from Microsoft Exchange for a given calendar and I want to output these in an ASP.net file
The "code behind" I have is:
DateTime StartDate = DateTime.Today;
DateTime EndDate = DateTime.Today.AddDays(1);
CalendarView cv = new CalendarView(StartDate, EndDate);
String MailboxToAccess = "RES_03037#company.com";
FolderId CalendarFolderId = new FolderId(WellKnownFolderName.Calendar, MailboxToAccess);
FindItemsResults<Appointment> fapts = service.FindAppointments(CalendarFolderId, cv);
if (fapts.Items.Count > 0)
{
DataRow row = table2.NewRow();
foreach (Appointment Appoint in fapts)
{
//Output to ASPX file
}
}
I am fairly new to ASP and C#
Your advice will be much appreciated!