private MAPIFolder getSharedCalendar(NameSpace oNS, String sharedURI) { Recipient sharer = null; MAPIFolder sharedCalendar = null; try { sharer = oNS.CreateRecipient(sharedURI); sharer.Resolve(); if (sharer.DisplayType == OlDisplayType.olDistList) { throw new System.Exception("User selected a distribution list!"); } sharedCalendar = oNS.GetSharedDefaultFolder(sharer, OlDefaultFolders.olFolderCalendar); if (sharedCalendar.DefaultItemType != OlItemType.olAppointmentItem) { log.Debug(sharer.Name + " does not have a calendar shared."); throw new System.Exception("Wrong default item type."); } calendarFolders.Add(sharer.Name, sharedCalendar); return(sharedCalendar); } catch (System.Exception ex) { log.Error("Failed to get shared calendar from " + sharedURI + ". " + ex.Message); MessageBox.Show("Could not find a shared calendar for '" + sharer.Name + "'.", "No shared calendar found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return(null); } finally { sharer = (Recipient)OutlookCalendar.ReleaseObject(sharer); } }
public void Disconnect(Boolean onlyWhenNoGUI = false) { if (!onlyWhenNoGUI || (onlyWhenNoGUI && oApp.Explorers.Count == 0)) { log.Debug("De-referencing all Outlook application objects."); try { folders = (Folders)OutlookCalendar.ReleaseObject(folders); useOutlookCalendar = (MAPIFolder)OutlookCalendar.ReleaseObject(useOutlookCalendar); for (int fld = calendarFolders.Count - 1; fld >= 0; fld--) { MAPIFolder mFld = calendarFolders.ElementAt(fld).Value; mFld = (MAPIFolder)OutlookCalendar.ReleaseObject(mFld); calendarFolders.Remove(calendarFolders.ElementAt(fld).Key); } calendarFolders = null; } catch (System.Exception ex) { log.Debug(ex.Message); } log.Info("Disconnecting from Outlook application."); Marshal.FinalReleaseComObject(oApp); oApp = null; GC.Collect(); } }
public void GetAppointmentByID(String entryID, out AppointmentItem ai) { NameSpace ns = oApp.GetNamespace("mapi"); ai = ns.GetItemFromID(entryID) as AppointmentItem; ns = (NameSpace)OutlookCalendar.ReleaseObject(ns); }
public void BuildOutlookPattern(Event ev, AppointmentItem ai) { RecurrencePattern ignore; BuildOutlookPattern(ev, ai, out ignore); ignore = (RecurrencePattern)OutlookCalendar.ReleaseObject(ignore); }
private static Boolean exceptionIsDeleted(Microsoft.Office.Interop.Outlook.Exception oExcp) { if (oExcp.Deleted) { return(true); } AppointmentItem ai = null; try { ai = oExcp.AppointmentItem; return(false); } catch (System.Exception ex) { if (ex.Message == "You changed one of the recurrences of this item, and this instance no longer exists. Close any open items and try again.") { log.Warn("This Outlook recurrence instance has become inaccessible, probably due to caching"); return(true); } else { log.Warn("Error when determining if Outlook recurrence is deleted or not.\r\n" + ex.Message); return(true); } } finally { ai = (AppointmentItem)OutlookCalendar.ReleaseObject(ai); } }
public void CompareOutlookPattern(Event ev, ref RecurrencePattern aiOpattern, SyncDirection syncDirection, System.Text.StringBuilder sb, ref int itemModified) { if (ev.Recurrence == null) { return; } log.Fine("Building a temporary recurrent Appointment generated from Event"); AppointmentItem evAI = OutlookCalendar.Instance.IOutlook.UseOutlookCalendar().Items.Add() as AppointmentItem; evAI.Start = DateTime.Parse(ev.Start.Date ?? ev.Start.DateTime); RecurrencePattern evOpattern = null; try { buildOutlookPattern(ev, evAI, out evOpattern); log.Fine("Comparing Google recurrence to Outlook equivalent"); if (MainForm.CompareAttribute("Recurrence Type", syncDirection, evOpattern.RecurrenceType.ToString(), aiOpattern.RecurrenceType.ToString(), sb, ref itemModified)) { aiOpattern.RecurrenceType = evOpattern.RecurrenceType; } if (MainForm.CompareAttribute("Recurrence Interval", syncDirection, evOpattern.Interval.ToString(), aiOpattern.Interval.ToString(), sb, ref itemModified)) { aiOpattern.Interval = evOpattern.Interval; } if (MainForm.CompareAttribute("Recurrence Instance", syncDirection, evOpattern.Instance.ToString(), aiOpattern.Instance.ToString(), sb, ref itemModified)) { aiOpattern.Instance = evOpattern.Instance; } if (MainForm.CompareAttribute("Recurrence DoW", syncDirection, evOpattern.DayOfWeekMask.ToString(), aiOpattern.DayOfWeekMask.ToString(), sb, ref itemModified)) { aiOpattern.DayOfWeekMask = evOpattern.DayOfWeekMask; } if (MainForm.CompareAttribute("Recurrence MoY", syncDirection, evOpattern.MonthOfYear.ToString(), aiOpattern.MonthOfYear.ToString(), sb, ref itemModified)) { aiOpattern.MonthOfYear = evOpattern.MonthOfYear; } if (MainForm.CompareAttribute("Recurrence NoEndDate", syncDirection, evOpattern.NoEndDate, aiOpattern.NoEndDate, sb, ref itemModified)) { aiOpattern.NoEndDate = evOpattern.NoEndDate; } if (MainForm.CompareAttribute("Recurrence Occurences", syncDirection, evOpattern.Occurrences.ToString(), aiOpattern.Occurrences.ToString(), sb, ref itemModified)) { aiOpattern.Occurrences = evOpattern.Occurrences; } } finally { evOpattern = (RecurrencePattern)OutlookCalendar.ReleaseObject(evOpattern); evAI.Delete(); evAI = (AppointmentItem)OutlookCalendar.ReleaseObject(evAI); } }
private void processOutlookExceptions(AppointmentItem ai, Event ev, Boolean forceCompare) { if (!HasExceptions(ev, checkLocalCacheOnly: true)) { return; } if (!ai.Saved) { ai.Save(); } RecurrencePattern oPattern = ai.GetRecurrencePattern(); foreach (Event gExcp in Recurrence.Instance.googleExceptions.Where(exp => exp.RecurringEventId == ev.Id)) { log.Fine("Found Google exception for " + (gExcp.OriginalStartTime.DateTime ?? gExcp.OriginalStartTime.Date)); DateTime oExcpDate = DateTime.Parse(gExcp.OriginalStartTime.DateTime ?? gExcp.OriginalStartTime.Date); AppointmentItem newAiExcp = getOutlookInstance(oPattern, oExcpDate); if (newAiExcp == null) { continue; } if (gExcp.Status != "cancelled") { int itemModified = 0; newAiExcp = OutlookCalendar.Instance.UpdateCalendarEntry(newAiExcp, gExcp, ref itemModified, forceCompare); if (itemModified > 0) { try { newAiExcp.Save(); } catch (System.Exception ex) { log.Warn(ex.Message); if (ex.Message == "Cannot save this item.") { MainForm.Instance.Logboxout("Uh oh! Outlook wasn't able to save this recurrence exception! " + "You may have two occurences on the same day, which it doesn't allow."); } } } } else { MainForm.Instance.Logboxout(OutlookCalendar.GetEventSummary(ai) + "\r\nDeleted."); newAiExcp.Delete(); } newAiExcp = (AppointmentItem)OutlookCalendar.ReleaseObject(newAiExcp); } if (!ai.Saved) { ai.Save(); } oPattern = (RecurrencePattern)OutlookCalendar.ReleaseObject(oPattern); }
private static void getOutlookInstance(RecurrencePattern oPattern, DateTime instanceDate, ref AppointmentItem ai) { //First check if this is not yet an exception try { ai = oPattern.GetOccurrence(instanceDate); } catch { } if (ai == null) { //The Outlook API is rubbish as the date argument is how it exists NOW (not OriginalDate). //If this has changed >1 in Google then there's no way of knowing what it might be! Exceptions oExcps = null; try { oExcps = oPattern.Exceptions; for (int e = 1; e <= oExcps.Count; e++) { Microsoft.Office.Interop.Outlook.Exception oExcp = null; try { oExcp = oExcps[e]; if (oExcp.OriginalDate.Date == instanceDate.Date) { try { log.Debug("Found Outlook exception for " + instanceDate); if (exceptionIsDeleted(oExcp)) { log.Debug("This exception is deleted."); break; } else { ai = oExcp.AppointmentItem; break; } } catch (System.Exception ex) { MainForm.Instance.Logboxout(ex.Message); MainForm.Instance.Logboxout("If this keeps happening, please restart OGCS."); break; } finally { OutlookCalendar.ReleaseObject(oExcp); } } } finally { oExcp = (Microsoft.Office.Interop.Outlook.Exception)OutlookCalendar.ReleaseObject(oExcp); } } } finally { oExcps = (Exceptions)OutlookCalendar.ReleaseObject(oExcps); } if (ai == null) { log.Warn("Unable to find Outlook exception for " + instanceDate); } } }
public void WindowsTimeZone_get(AppointmentItem ai, out String startTz, out String endTz) { Microsoft.Office.Interop.Outlook.TimeZone _startTz = null; Microsoft.Office.Interop.Outlook.TimeZone _endTz = null; try { _startTz = ai.StartTimeZone; _endTz = ai.EndTimeZone; startTz = _startTz.ID; endTz = _endTz.ID; } finally { _startTz = (Microsoft.Office.Interop.Outlook.TimeZone)OutlookCalendar.ReleaseObject(_startTz); _endTz = (Microsoft.Office.Interop.Outlook.TimeZone)OutlookCalendar.ReleaseObject(_endTz); } }
public static Boolean HasExceptions(AppointmentItem ai) { RecurrencePattern rp = null; Exceptions excps = null; try { rp = ai.GetRecurrencePattern(); excps = rp.Exceptions; return(excps.Count != 0); } finally { excps = (Exceptions)OutlookCalendar.ReleaseObject(excps); rp = (RecurrencePattern)OutlookCalendar.ReleaseObject(rp); } }
private void processOutlookExceptions(AppointmentItem ai, Event ev, Boolean forceCompare) { if (!HasExceptions(ev, checkLocalCacheOnly: true)) { return; } if (!ai.Saved) { ai.Save(); } RecurrencePattern oPattern = ai.GetRecurrencePattern(); foreach (Event gExcp in Recurrence.Instance.googleExceptions.Where(exp => exp.RecurringEventId == ev.Id)) { log.Fine("Found Google exception for " + (gExcp.OriginalStartTime.DateTime ?? gExcp.OriginalStartTime.Date)); DateTime oExcpDate = DateTime.Parse(gExcp.OriginalStartTime.DateTime ?? gExcp.OriginalStartTime.Date); AppointmentItem newAiExcp = getOutlookInstance(oPattern, oExcpDate); if (newAiExcp == null) { continue; } if (gExcp.Status != "cancelled") { int itemModified = 0; newAiExcp = OutlookCalendar.Instance.UpdateCalendarEntry(newAiExcp, gExcp, ref itemModified, forceCompare); if (itemModified > 0) { newAiExcp.Save(); } } else { MainForm.Instance.Logboxout(OutlookCalendar.GetEventSummary(ai) + "\r\nDeleted."); newAiExcp.Delete(); } newAiExcp = (AppointmentItem)OutlookCalendar.ReleaseObject(newAiExcp); } if (!ai.Saved) { ai.Save(); } oPattern = (RecurrencePattern)OutlookCalendar.ReleaseObject(oPattern); }
public void CompareOutlookPattern(Event ev, AppointmentItem ai, System.Text.StringBuilder sb, ref int itemModified) { if (ev.Recurrence == null) { return; } log.Fine("Building a temporary recurrent Appointment generated from Event"); AppointmentItem evAI = OutlookCalendar.Instance.IOutlook.UseOutlookCalendar().Items.Add() as AppointmentItem; RecurrencePattern evOpattern; RecurrencePattern aiOpattern = ai.GetRecurrencePattern(); BuildOutlookPattern(ev, evAI, out evOpattern); log.Fine("Comparing Google recurrence to Outlook equivalent"); if (MainForm.CompareAttribute("Recurrence Type", Settings.Instance.SyncDirection, evOpattern.RecurrenceType.ToString(), aiOpattern.RecurrenceType.ToString(), sb, ref itemModified)) { aiOpattern.RecurrenceType = evOpattern.RecurrenceType; } if (MainForm.CompareAttribute("Recurrence Interval", Settings.Instance.SyncDirection, evOpattern.Interval.ToString(), aiOpattern.Interval.ToString(), sb, ref itemModified)) { aiOpattern.Interval = evOpattern.Interval; } if (MainForm.CompareAttribute("Recurrence Instance", Settings.Instance.SyncDirection, evOpattern.Instance.ToString(), aiOpattern.Instance.ToString(), sb, ref itemModified)) { aiOpattern.Instance = evOpattern.Instance; } if (MainForm.CompareAttribute("Recurrence DoW", Settings.Instance.SyncDirection, evOpattern.DayOfWeekMask.ToString(), aiOpattern.DayOfWeekMask.ToString(), sb, ref itemModified)) { aiOpattern.DayOfWeekMask = evOpattern.DayOfWeekMask; } if (MainForm.CompareAttribute("Recurrence MoY", Settings.Instance.SyncDirection, evOpattern.MonthOfYear.ToString(), aiOpattern.MonthOfYear.ToString(), sb, ref itemModified)) { aiOpattern.MonthOfYear = evOpattern.MonthOfYear; } aiOpattern = (RecurrencePattern)OutlookCalendar.ReleaseObject(aiOpattern); evOpattern = (RecurrencePattern)OutlookCalendar.ReleaseObject(evOpattern); evAI = (AppointmentItem)OutlookCalendar.ReleaseObject(evAI); }
public List <String> BuildGooglePattern(AppointmentItem ai, Event ev) { if (!ai.IsRecurring || ai.RecurrenceState != OlRecurrenceState.olApptMaster) { return(null); } log.Debug("Creating Google iCalendar definition for recurring event."); List <String> gPattern = new List <String>(); RecurrencePattern rp = null; try { rp = ai.GetRecurrencePattern(); gPattern.Add("RRULE:" + buildRrule(rp)); } finally { rp = (RecurrencePattern)OutlookCalendar.ReleaseObject(rp); } log.Debug(string.Join("\r\n", gPattern.ToArray())); return(gPattern); }
private MAPIFolder getCalendarStore(NameSpace oNS) { MAPIFolder defaultCalendar = null; if (Settings.Instance.OutlookService == OutlookCalendar.Service.AlternativeMailbox && Settings.Instance.MailboxName != "") { log.Debug("Finding Alternative Mailbox calendar folders"); Folders binFolders = null; Store binStore = null; PropertyAccessor pa = null; try { binFolders = oNS.Folders; binStore = binFolders[Settings.Instance.MailboxName].Store; pa = binStore.PropertyAccessor; object bin = pa.GetProperty(PR_IPM_WASTEBASKET_ENTRYID); string excludeDeletedFolder = pa.BinaryToString(bin); //EntryID MainForm.Instance.lOutlookCalendar.Text = "Getting calendars"; MainForm.Instance.lOutlookCalendar.BackColor = System.Drawing.Color.Yellow; findCalendars(oNS.Folders[Settings.Instance.MailboxName].Folders, calendarFolders, excludeDeletedFolder); MainForm.Instance.lOutlookCalendar.BackColor = System.Drawing.Color.White; MainForm.Instance.lOutlookCalendar.Text = "Select calendar"; } catch (System.Exception ex) { log.Error("Failed to find calendar folders in alternate mailbox '" + Settings.Instance.MailboxName + "'."); log.Debug(ex.Message); } finally { pa = (PropertyAccessor)OutlookCalendar.ReleaseObject(pa); binStore = (Store)OutlookCalendar.ReleaseObject(binStore); binFolders = (Folders)OutlookCalendar.ReleaseObject(binFolders); } //Default to first calendar in drop down defaultCalendar = calendarFolders.FirstOrDefault().Value; if (defaultCalendar == null) { log.Info("Could not find Alternative mailbox Calendar folder. Reverting to the default mailbox calendar."); System.Windows.Forms.MessageBox.Show("Unable to find a Calendar folder in the alternative mailbox.\r\n" + "Reverting to the default mailbox calendar", "Calendar not found", System.Windows.Forms.MessageBoxButtons.OK); getDefaultCalendar(oNS, ref defaultCalendar); MainForm.Instance.ddMailboxName.Text = ""; } } else if (Settings.Instance.OutlookService == OutlookCalendar.Service.SharedCalendar) { log.Debug("Finding shared calendar"); if (MainForm.Instance.Visible) { SelectNamesDialog snd; try { snd = oNS.GetSelectNamesDialog(); snd.NumberOfRecipientSelectors = OlRecipientSelectors.olShowNone; snd.ForceResolution = true; snd.AllowMultipleSelection = false; snd.Display(); if (snd.Recipients.Count == 0) { log.Info("No shared calendar selected."); getDefaultCalendar(oNS, ref defaultCalendar); } else { String sharedURI = snd.Recipients[1].Address; MAPIFolder sharedCalendar = getSharedCalendar(oNS, sharedURI); if (sharedCalendar == null) { getDefaultCalendar(oNS, ref defaultCalendar); } else { Settings.Instance.SharedCalendar = sharedURI; return(sharedCalendar); } } } finally { snd = null; } } else { defaultCalendar = getSharedCalendar(oNS, Settings.Instance.SharedCalendar); if (defaultCalendar == null) { getDefaultCalendar(oNS, ref defaultCalendar); } else { return(defaultCalendar); } } } else { getDefaultCalendar(oNS, ref defaultCalendar); } log.Debug("Default Calendar folder: " + defaultCalendar.Name); return(defaultCalendar); }
public NameSpace GetCurrentUser(NameSpace oNS) { //We only need the current user details when syncing meeting attendees. //If GAL had previously been detected as blocked, let's always try one attempt to see if it's been opened up if (!Settings.Instance.OutlookGalBlocked && !Settings.Instance.AddAttendees) { return(oNS); } Boolean releaseNamespace = (oNS == null); if (releaseNamespace) { oNS = oApp.GetNamespace("mapi"); } Recipient currentUser = null; try { DateTime triggerOOMsecurity = DateTime.Now; try { currentUser = oNS.CurrentUser; if (!MainForm.Instance.IsHandleCreated && (DateTime.Now - triggerOOMsecurity).TotalSeconds > 1) { log.Warn(">1s delay possibly due to Outlook security popup."); OutlookCalendar.OOMsecurityInfo = true; } } catch (System.Exception ex) { OGCSexception.Analyse(ex); if (Settings.Instance.OutlookGalBlocked) //Fail fast { log.Debug("Corporate policy is still blocking access to GAL."); return(oNS); } log.Warn("We seem to have a faux connection to Outlook! Forcing starting it with a system call :-/"); oNS = (NameSpace)OutlookCalendar.ReleaseObject(oNS); Disconnect(); OutlookCalendar.AttachToOutlook(ref oApp, openOutlookOnFail: true, withSystemCall: true); oNS = oApp.GetNamespace("mapi"); int maxDelay = 5; int delay = 1; while (delay <= maxDelay) { log.Debug("Sleeping..." + delay + "/" + maxDelay); System.Threading.Thread.Sleep(10000); try { currentUser = oNS.CurrentUser; delay = maxDelay; } catch (System.Exception ex2) { if (delay == maxDelay) { if (OGCSexception.GetErrorCode(ex2) == "0x80004004") //E_ABORT { log.Warn("Corporate policy or possibly anti-virus is blocking access to GAL."); } else { OGCSexception.Analyse(ex2); } log.Warn("OGCS is unable to obtain CurrentUser from Outlook."); Settings.Instance.OutlookGalBlocked = true; return(oNS); } OGCSexception.Analyse(ex2); } delay++; } } if (Settings.Instance.OutlookGalBlocked) { log.Debug("GAL is no longer blocked!"); } Settings.Instance.OutlookGalBlocked = false; currentUserSMTP = GetRecipientEmail(currentUser); currentUserName = currentUser.Name; } finally { currentUser = (Recipient)OutlookCalendar.ReleaseObject(currentUser); if (releaseNamespace) { oNS = (NameSpace)OutlookCalendar.ReleaseObject(oNS); } } return(oNS); }
public static void UpdateGoogleExceptions(AppointmentItem ai, Event ev) { if (ai.IsRecurring) { RecurrencePattern recurrence = ai.GetRecurrencePattern(); try { if (recurrence.Exceptions.Count > 0) { log.Debug(OutlookCalendar.GetEventSummary(ai)); log.Debug("This is a recurring appointment with " + recurrence.Exceptions.Count + " exceptions that will now be iteratively compared."); foreach (Microsoft.Office.Interop.Outlook.Exception oExcp in recurrence.Exceptions) { int excp_itemModified = 0; //Check the exception falls in the date range being synced Boolean oIsDeleted = exceptionIsDeleted(oExcp); String logDeleted = oIsDeleted ? " deleted and" : ""; DateTime oExcp_currDate = oIsDeleted ? oExcp.OriginalDate : oExcp.AppointmentItem.Start; if (oExcp_currDate < Settings.Instance.SyncStart.Date || oExcp_currDate > Settings.Instance.SyncEnd.Date) { log.Fine("Exception is" + logDeleted + " outside date range being synced: " + oExcp_currDate.Date.ToString("dd/MM/yyyy")); continue; } Event gExcp = Recurrence.Instance.GetGoogleInstance(oExcp, ev.RecurringEventId ?? ev.Id, OutlookCalendar.Instance.IOutlook.GetGlobalApptID(ai)); if (gExcp != null) { log.Debug("Matching Google Event recurrence found."); if (gExcp.Status == "cancelled") { log.Debug("It is deleted in Google, so cannot compare items."); if (!oIsDeleted) { log.Warn("Outlook is NOT deleted though - a mismatch has occurred somehow"); } continue; } try { GoogleCalendar.Instance.UpdateCalendarEntry(oExcp.AppointmentItem, gExcp, ref excp_itemModified); } catch (System.Exception ex) { if (oIsDeleted) { if (gExcp.Status != "cancelled") { gExcp.Status = "cancelled"; excp_itemModified++; } } else { log.Error(ex.Message); log.Error(ex.StackTrace); throw ex; } } if (excp_itemModified > 0) { try { GoogleCalendar.Instance.UpdateCalendarEntry_save(ref gExcp); } catch (System.Exception ex) { MainForm.Instance.Logboxout("WARNING: Updated event exception failed to save.\r\n" + ex.Message); log.Error(ex.StackTrace); if (MessageBox.Show("Updated Google event exception failed to save. Continue with synchronisation?", "Sync item failed", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { continue; } else { throw new UserCancelledSyncException("User chose not to continue sync."); } } } } else { log.Debug("No matching Google Event recurrence found."); if (oIsDeleted) { log.Debug("The Outlook appointment is deleted, so not a problem."); } } } } } finally { recurrence = (RecurrencePattern)OutlookCalendar.ReleaseObject(recurrence); } } }
public void Connect() { OutlookCalendar.AttachToOutlook(ref oApp, openOutlookOnFail: true, withSystemCall: false); log.Debug("Setting up Outlook connection."); // Get the NameSpace and Logon information. NameSpace oNS = null; try { oNS = oApp.GetNamespace("mapi"); //Implicit logon to default profile, with no dialog box //If 1< profile, a dialogue is forced unless implicit login used exchangeConnectionMode = oNS.ExchangeConnectionMode; if (exchangeConnectionMode != OlExchangeConnectionMode.olNoExchange) { log.Info("Exchange server version: Unknown"); } log.Info("Exchange connection mode: " + exchangeConnectionMode.ToString()); oNS = GetCurrentUser(oNS); if (!Settings.Instance.OutlookGalBlocked && currentUserName == "Unknown") { log.Info("Current username is \"Unknown\""); if (Settings.Instance.AddAttendees) { System.Windows.Forms.MessageBox.Show("It appears you do not have an Email Account configured in Outlook.\r\n" + "You should set one up now (Tools > Email Accounts) to avoid problems syncing meeting attendees.", "No Email Account Found", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning); } } log.Debug("Get the folders configured in Outlook"); folders = oNS.Folders; // Get the Calendar folders useOutlookCalendar = getCalendarStore(oNS); if (MainForm.Instance.IsHandleCreated) { log.Fine("Resetting connection, so re-selecting calendar from GUI dropdown"); MainForm.Instance.cbOutlookCalendars.SelectedIndexChanged -= MainForm.Instance.cbOutlookCalendar_SelectedIndexChanged; MainForm.Instance.cbOutlookCalendars.DataSource = new BindingSource(calendarFolders, null); //Select the right calendar int c = 0; foreach (KeyValuePair <String, MAPIFolder> calendarFolder in calendarFolders) { if (calendarFolder.Value.EntryID == Settings.Instance.UseOutlookCalendar.Id) { MainForm.Instance.SetControlPropertyThreadSafe(MainForm.Instance.cbOutlookCalendars, "SelectedIndex", c); } c++; } if ((int)MainForm.Instance.GetControlPropertyThreadSafe(MainForm.Instance.cbOutlookCalendars, "SelectedIndex") == -1) { MainForm.Instance.SetControlPropertyThreadSafe(MainForm.Instance.cbOutlookCalendars, "SelectedIndex", 0); } KeyValuePair <String, MAPIFolder> calendar = (KeyValuePair <String, MAPIFolder>)MainForm.Instance.GetControlPropertyThreadSafe(MainForm.Instance.cbOutlookCalendars, "SelectedItem"); useOutlookCalendar = calendar.Value; MainForm.Instance.cbOutlookCalendars.SelectedIndexChanged += MainForm.Instance.cbOutlookCalendar_SelectedIndexChanged; } } finally { // Done. Log off. if (oNS != null) { oNS.Logoff(); } oNS = (NameSpace)OutlookCalendar.ReleaseObject(oNS); } }
public String GetRecipientEmail(Recipient recipient) { String retEmail = ""; Boolean builtFakeEmail = false; log.Fine("Determining email of recipient: " + recipient.Name); AddressEntry addressEntry = null; try { try { addressEntry = recipient.AddressEntry; } catch { log.Warn("Can't resolve this recipient!"); addressEntry = null; } if (addressEntry == null) { log.Warn("No AddressEntry exists!"); retEmail = EmailAddress.BuildFakeEmailAddress(recipient.Name, out builtFakeEmail); } else { log.Fine("addressEntry Type: " + addressEntry.Type); if (addressEntry.Type == "EX") //Exchange { log.Fine("Address is from Exchange"); retEmail = ADX_GetSMTPAddress(addressEntry.Address); } else if (addressEntry.Type != null && addressEntry.Type.ToUpper() == "NOTES") { log.Fine("From Lotus Notes"); //Migrated contacts from notes, have weird "email addresses" eg: "James T. Kirk/US-Corp03/enterprise/US" retEmail = EmailAddress.BuildFakeEmailAddress(recipient.Name, out builtFakeEmail); } else { log.Fine("Not from Exchange"); try { if (string.IsNullOrEmpty(addressEntry.Address)) { log.Warn("addressEntry.Address is empty."); retEmail = EmailAddress.BuildFakeEmailAddress(recipient.Name, out builtFakeEmail); } else { retEmail = addressEntry.Address; } } catch (System.Exception ex) { log.Error("Failed accessing addressEntry.Address"); log.Error(ex.Message); retEmail = EmailAddress.BuildFakeEmailAddress(recipient.Name, out builtFakeEmail); } } } if (string.IsNullOrEmpty(retEmail) || retEmail == "Unknown") { log.Error("Failed to get email address through Addin MAPI access!"); retEmail = EmailAddress.BuildFakeEmailAddress(recipient.Name, out builtFakeEmail); } if (retEmail != null && retEmail.IndexOf("<") > 0) { retEmail = retEmail.Substring(retEmail.IndexOf("<") + 1); retEmail = retEmail.TrimEnd(Convert.ToChar(">")); } log.Fine("Email address: " + retEmail, retEmail); if (!EmailAddress.IsValidEmail(retEmail) && !builtFakeEmail) { retEmail = EmailAddress.BuildFakeEmailAddress(recipient.Name, out builtFakeEmail); if (!EmailAddress.IsValidEmail(retEmail)) { MainForm.Instance.Logboxout("ERROR: Recipient \"" + recipient.Name + "\" with email address \"" + retEmail + "\" is invalid.", notifyBubble: true); MainForm.Instance.Logboxout("This must be manually resolved in order to sync this appointment."); throw new ApplicationException("Invalid recipient email for \"" + recipient.Name + "\""); } } return(retEmail); } finally { addressEntry = (AddressEntry)OutlookCalendar.ReleaseObject(addressEntry); } }
private Event getGoogleInstance(ref Microsoft.Office.Interop.Outlook.Exception oExcp, String gRecurringEventID, String oEntryID, Boolean dirtyCache) { Boolean oIsDeleted = exceptionIsDeleted(oExcp); log.Debug("Finding Google instance for " + (oIsDeleted ? "deleted " : "") + "Outlook exception:-"); log.Debug(" Original date: " + oExcp.OriginalDate.ToString("dd/MM/yyyy")); if (!oIsDeleted) { AppointmentItem ai = null; try { ai = oExcp.AppointmentItem; log.Debug(" Current date: " + ai.Start.ToString("dd/MM/yyyy")); } finally { ai = (AppointmentItem)OutlookCalendar.ReleaseObject(ai); } } if (dirtyCache) { log.Debug("Google exception cache not being used. Retrieving all recurring instances afresh..."); //Remove dirty items googleExceptions.RemoveAll(ev => ev.RecurringEventId == gRecurringEventID); } else { foreach (Event gExcp in googleExceptions) { if (gExcp.RecurringEventId == gRecurringEventID) { if ((!oIsDeleted && oExcp.OriginalDate == DateTime.Parse(gExcp.OriginalStartTime.Date ?? gExcp.OriginalStartTime.DateTime) ) || (oIsDeleted && oExcp.OriginalDate == DateTime.Parse(gExcp.OriginalStartTime.Date ?? gExcp.OriginalStartTime.DateTime).Date )) { return(gExcp); } } } log.Debug("Google exception event is not cached. Retrieving all recurring instances..."); } List <Event> gInstances = GoogleCalendar.Instance.GetCalendarEntriesInRecurrence(gRecurringEventID); //Add any new exceptions to local cache googleExceptions = googleExceptions.Union(gInstances.Where(ev => !String.IsNullOrEmpty(ev.RecurringEventId))).ToList(); foreach (Event gInst in gInstances) { if (gInst.RecurringEventId == gRecurringEventID) { if (((!oIsDeleted || (oIsDeleted && !oExcp.Deleted)) && /* Weirdness when exception is cancelled by organiser but not yet deleted/accepted by recipient */ oExcp.OriginalDate == DateTime.Parse(gInst.OriginalStartTime.Date ?? gInst.OriginalStartTime.DateTime) ) || (oIsDeleted && oExcp.OriginalDate == DateTime.Parse(gInst.OriginalStartTime.Date ?? gInst.OriginalStartTime.DateTime).Date )) { return(gInst); } } } return(null); }
public void Connect() { OutlookCalendar.AttachToOutlook(ref oApp); log.Debug("Setting up Outlook connection."); // Get the NameSpace and Logon information. NameSpace oNS = null; try { oNS = oApp.GetNamespace("mapi"); //Implicit logon to default profile, with no dialog box //If 1< profile, a dialogue is forced unless implicit login used exchangeConnectionMode = oNS.ExchangeConnectionMode; if (exchangeConnectionMode != OlExchangeConnectionMode.olNoExchange) { log.Info("Exchange server version: Unknown"); } log.Info("Exchange connection mode: " + exchangeConnectionMode.ToString()); Recipient currentUser = null; try { try { currentUser = oNS.CurrentUser; } catch { log.Warn("We seem to have a faux connection to Outlook! Forcing starting it with a system call :-/"); oNS = (NameSpace)OutlookCalendar.ReleaseObject(oNS); Disconnect(); OutlookCalendar.AttachToOutlook(ref oApp, openOutlookOnFail: true, withSystemCall: true); oNS = oApp.GetNamespace("mapi"); currentUser = oNS.CurrentUser; } currentUserSMTP = GetRecipientEmail(currentUser); currentUserName = currentUser.Name; } finally { currentUser = (Recipient)OutlookCalendar.ReleaseObject(currentUser); } if (currentUserName == "Unknown") { log.Info("Current username is \"Unknown\""); if (Settings.Instance.AddAttendees) { System.Windows.Forms.MessageBox.Show("It appears you do not have an Email Account configured in Outlook.\r\n" + "You should set one up now (Tools > Email Accounts) to avoid problems syncing meeting attendees.", "No Email Account Found", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning); } } //Get the folders configured in Outlook folders = oNS.Folders; // Get the Calendar folders useOutlookCalendar = getCalendarStore(oNS); if (MainForm.Instance.IsHandleCreated) //resetting connection, so pick up selected calendar from GUI dropdown { MainForm.Instance.cbOutlookCalendars.DataSource = new BindingSource(calendarFolders, null); KeyValuePair <String, MAPIFolder> calendar = (KeyValuePair <String, MAPIFolder>)MainForm.Instance.cbOutlookCalendars.SelectedItem; calendar = (KeyValuePair <String, MAPIFolder>)MainForm.Instance.cbOutlookCalendars.SelectedItem; useOutlookCalendar = calendar.Value; } } finally { // Done. Log off. oNS.Logoff(); oNS = (NameSpace)OutlookCalendar.ReleaseObject(oNS); } }
public static void CreateGoogleExceptions(AppointmentItem ai, String recurringEventId) { if (!ai.IsRecurring) { return; } log.Debug("Creating Google recurrence exceptions."); List <Event> gRecurrences = GoogleCalendar.Instance.GetCalendarEntriesInRecurrence(recurringEventId); if (gRecurrences != null) { RecurrencePattern rp = null; Exceptions excps = null; try { rp = ai.GetRecurrencePattern(); excps = rp.Exceptions; for (int e = 1; e <= excps.Count; e++) { Microsoft.Office.Interop.Outlook.Exception oExcp = null; try { oExcp = excps[e]; for (int g = 0; g < gRecurrences.Count; g++) { Event ev = gRecurrences[g]; String gDate = ev.OriginalStartTime.DateTime ?? ev.OriginalStartTime.Date; Boolean isDeleted = exceptionIsDeleted(oExcp); if (isDeleted && !ai.AllDayEvent) //Deleted items get truncated?! { gDate = GoogleCalendar.GoogleTimeFrom(DateTime.Parse(gDate).Date); } if (oExcp.OriginalDate == DateTime.Parse(gDate)) { if (isDeleted) { MainForm.Instance.Logboxout(GoogleCalendar.GetEventSummary(ev)); MainForm.Instance.Logboxout("Recurrence deleted."); ev.Status = "cancelled"; GoogleCalendar.Instance.UpdateCalendarEntry_save(ref ev); } else { int exceptionItemsModified = 0; Event modifiedEv = GoogleCalendar.Instance.UpdateCalendarEntry(oExcp.AppointmentItem, ev, ref exceptionItemsModified, forceCompare: true); if (exceptionItemsModified > 0) { GoogleCalendar.Instance.UpdateCalendarEntry_save(ref modifiedEv); } } break; } } } finally { oExcp = (Microsoft.Office.Interop.Outlook.Exception)OutlookCalendar.ReleaseObject(oExcp); } } } finally { excps = (Exceptions)OutlookCalendar.ReleaseObject(excps); rp = (RecurrencePattern)OutlookCalendar.ReleaseObject(rp); } } }
public void Connect() { OutlookCalendar.AttachToOutlook(ref oApp, openOutlookOnFail: true, withSystemCall: false); log.Debug("Setting up Outlook connection."); // Get the NameSpace and Logon information. NameSpace oNS = null; try { oNS = oApp.GetNamespace("mapi"); //Log on by using a dialog box to choose the profile. //oNS.Logon("", Type.Missing, true, true); //Implicit logon to default profile, with no dialog box //If 1< profile, a dialogue is forced unless implicit login used exchangeConnectionMode = oNS.ExchangeConnectionMode; if (exchangeConnectionMode != OlExchangeConnectionMode.olNoExchange) { log.Info("Exchange server version: " + oNS.ExchangeMailboxServerVersion.ToString()); } //Logon using a specific profile. Can't see a use case for this when using OGsync //If using this logon method, change the profile name to an appropriate value: //HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles //oNS.Logon("YourValidProfile", Type.Missing, false, true); log.Info("Exchange connection mode: " + exchangeConnectionMode.ToString()); Recipient currentUser = null; try { try { currentUser = oNS.CurrentUser; } catch { log.Warn("We seem to have a faux connection to Outlook! Forcing starting it with a system call :-/"); oNS = (NameSpace)OutlookCalendar.ReleaseObject(oNS); Disconnect(); OutlookCalendar.AttachToOutlook(ref oApp, openOutlookOnFail: true, withSystemCall: true); oNS = oApp.GetNamespace("mapi"); currentUser = oNS.CurrentUser; } //Issue 402 log.Debug("Getting active window inspector"); Inspector inspector = oApp.ActiveInspector(); inspector = (Inspector)OutlookCalendar.ReleaseObject(inspector); log.Debug("Done."); currentUserSMTP = GetRecipientEmail(currentUser); currentUserName = currentUser.Name; } finally { currentUser = (Recipient)OutlookCalendar.ReleaseObject(currentUser); } if (currentUserName == "Unknown") { log.Info("Current username is \"Unknown\""); if (Settings.Instance.AddAttendees) { System.Windows.Forms.MessageBox.Show("It appears you do not have an Email Account configured in Outlook.\r\n" + "You should set one up now (Tools > Email Accounts) to avoid problems syncing meeting attendees.", "No Email Account Found", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning); } } //Get the folders configured in Outlook folders = oNS.Folders; // Get the Calendar folders useOutlookCalendar = getCalendarStore(oNS); if (MainForm.Instance.IsHandleCreated) { log.Fine("Resetting connection, so re-selecting calendar from GUI dropdown"); MainForm.Instance.cbOutlookCalendars.SelectedIndexChanged -= MainForm.Instance.cbOutlookCalendar_SelectedIndexChanged; MainForm.Instance.cbOutlookCalendars.DataSource = new BindingSource(calendarFolders, null); //Select the right calendar int c = 0; foreach (KeyValuePair <String, MAPIFolder> calendarFolder in calendarFolders) { if (calendarFolder.Value.EntryID == Settings.Instance.UseOutlookCalendar.Id) { MainForm.Instance.SetControlPropertyThreadSafe(MainForm.Instance.cbOutlookCalendars, "SelectedIndex", c); } c++; } if ((int)MainForm.Instance.GetControlPropertyThreadSafe(MainForm.Instance.cbOutlookCalendars, "SelectedIndex") == -1) { MainForm.Instance.SetControlPropertyThreadSafe(MainForm.Instance.cbOutlookCalendars, "SelectedIndex", 0); } KeyValuePair <String, MAPIFolder> calendar = (KeyValuePair <String, MAPIFolder>)MainForm.Instance.GetControlPropertyThreadSafe(MainForm.Instance.cbOutlookCalendars, "SelectedItem"); useOutlookCalendar = calendar.Value; MainForm.Instance.cbOutlookCalendars.SelectedIndexChanged += MainForm.Instance.cbOutlookCalendar_SelectedIndexChanged; } } finally { // Done. Log off. oNS.Logoff(); oNS = (NameSpace)OutlookCalendar.ReleaseObject(oNS); } }
public String GetRecipientEmail(Recipient recipient) { String retEmail = ""; Boolean builtFakeEmail = false; log.Fine("Determining email of recipient: " + recipient.Name); AddressEntry addressEntry = null; String addressEntryType = ""; try { try { addressEntry = recipient.AddressEntry; } catch { log.Warn("Can't resolve this recipient!"); addressEntry = null; } if (addressEntry == null) { log.Warn("No AddressEntry exists!"); retEmail = EmailAddress.BuildFakeEmailAddress(recipient.Name, out builtFakeEmail); } else { try { addressEntryType = addressEntry.Type; } catch { log.Warn("Cannot access addressEntry.Type!"); } log.Fine("AddressEntry Type: " + addressEntryType); if (addressEntryType == "EX") //Exchange { log.Fine("Address is from Exchange"); if (addressEntry.AddressEntryUserType == OlAddressEntryUserType.olExchangeUserAddressEntry || addressEntry.AddressEntryUserType == OlAddressEntryUserType.olExchangeRemoteUserAddressEntry) { ExchangeUser eu = null; try { eu = addressEntry.GetExchangeUser(); if (eu != null && eu.PrimarySmtpAddress != null) { retEmail = eu.PrimarySmtpAddress; } else { log.Warn("Exchange does not have an email for recipient: " + recipient.Name); Microsoft.Office.Interop.Outlook.PropertyAccessor pa = null; try { //Should I try PR_EMS_AB_PROXY_ADDRESSES next to cater for cached mode? pa = recipient.PropertyAccessor; retEmail = pa.GetProperty(OutlookNew.PR_SMTP_ADDRESS).ToString(); log.Debug("Retrieved from PropertyAccessor instead."); } catch { log.Warn("Also failed to retrieve email from PropertyAccessor."); retEmail = EmailAddress.BuildFakeEmailAddress(recipient.Name, out builtFakeEmail); } finally { pa = (Microsoft.Office.Interop.Outlook.PropertyAccessor)OutlookCalendar.ReleaseObject(pa); } } } finally { eu = (ExchangeUser)OutlookCalendar.ReleaseObject(eu); } } else if (addressEntry.AddressEntryUserType == OlAddressEntryUserType.olOutlookContactAddressEntry) { log.Fine("This is an Outlook contact"); ContactItem contact = null; try { try { contact = addressEntry.GetContact(); } catch { log.Warn("Doesn't seem to be a valid contact object. Maybe this account is no longer in Exchange."); retEmail = EmailAddress.BuildFakeEmailAddress(recipient.Name, out builtFakeEmail); } if (contact != null) { if (contact.Email1AddressType == "EX") { log.Fine("Address is from Exchange."); log.Fine("Using PropertyAccessor to get email address."); Microsoft.Office.Interop.Outlook.PropertyAccessor pa = null; try { pa = contact.PropertyAccessor; retEmail = pa.GetProperty(EMAIL1ADDRESS).ToString(); } finally { pa = (Microsoft.Office.Interop.Outlook.PropertyAccessor)OutlookCalendar.ReleaseObject(pa); } } else { retEmail = contact.Email1Address; } } } finally { contact = (ContactItem)OutlookCalendar.ReleaseObject(contact); } } else { log.Fine("Exchange type: " + addressEntry.AddressEntryUserType.ToString()); log.Fine("Using PropertyAccessor to get email address."); Microsoft.Office.Interop.Outlook.PropertyAccessor pa = null; try { pa = recipient.PropertyAccessor; retEmail = pa.GetProperty(OutlookNew.PR_SMTP_ADDRESS).ToString(); } finally { pa = (Microsoft.Office.Interop.Outlook.PropertyAccessor)OutlookCalendar.ReleaseObject(pa); } } } else if (addressEntryType.ToUpper() == "NOTES") { log.Fine("From Lotus Notes"); //Migrated contacts from notes, have weird "email addresses" eg: "James T. Kirk/US-Corp03/enterprise/US" retEmail = EmailAddress.BuildFakeEmailAddress(recipient.Name, out builtFakeEmail); } else { log.Fine("Not from Exchange"); try { if (string.IsNullOrEmpty(addressEntry.Address)) { log.Warn("addressEntry.Address is empty."); retEmail = EmailAddress.BuildFakeEmailAddress(recipient.Name, out builtFakeEmail); } else { retEmail = addressEntry.Address; } } catch (System.Exception ex) { log.Error("Failed accessing addressEntry.Address"); log.Error(ex.Message); retEmail = EmailAddress.BuildFakeEmailAddress(recipient.Name, out builtFakeEmail); } } } if (retEmail != null && retEmail.IndexOf("<") > 0) { retEmail = retEmail.Substring(retEmail.IndexOf("<") + 1); retEmail = retEmail.TrimEnd(Convert.ToChar(">")); } log.Fine("Email address: " + retEmail, retEmail); if (!EmailAddress.IsValidEmail(retEmail) && !builtFakeEmail) { retEmail = EmailAddress.BuildFakeEmailAddress(recipient.Name, out builtFakeEmail); if (!EmailAddress.IsValidEmail(retEmail)) { MainForm.Instance.Logboxout("ERROR: Recipient \"" + recipient.Name + "\" with email address \"" + retEmail + "\" is invalid.", notifyBubble: true); MainForm.Instance.Logboxout("This must be manually resolved in order to sync this appointment."); throw new ApplicationException("Invalid recipient email for \"" + recipient.Name + "\""); } } return(retEmail); } finally { addressEntry = (AddressEntry)OutlookCalendar.ReleaseObject(addressEntry); } }