private void btSave_Click(object sender, EventArgs e) { try { Settings.Instance.TimezoneMaps.Clear(); foreach (DataGridViewRow row in tzGridView.Rows) { if (row.Cells[0].Value == null || row.Cells[0].Value.ToString().Trim() == "") { continue; } try { Settings.Instance.TimezoneMaps.Add(row.Cells[0].Value.ToString(), row.Cells[1].Value.ToString()); } catch (System.ArgumentException ex) { if (OGCSexception.GetErrorCode(ex) == "0x80070057") { //An item with the same key has already been added } else { throw; } } } } catch (System.Exception ex) { OGCSexception.Analyse("Could not save timezone mappings to Settings.", ex); } finally { this.Close(); } }
private void btOK_Click(object sender, EventArgs e) { log.Fine("Checking no duplicate mappings exist."); SettingsStore.Calendar profile = Forms.Main.Instance.ActiveCalendarProfile; try { List <String> oColValues = new List <String>(); List <String> gColValues = new List <String>(); foreach (DataGridViewRow row in colourGridView.Rows) { oColValues.Add(row.Cells["OutlookColour"].Value.ToString()); gColValues.Add(row.Cells["GoogleColour"].Value.ToString()); } String oDuplicates = string.Join("\r\n", oColValues.GroupBy(v => v).Where(g => g.Count() > 1).Select(s => "- " + s.Key).ToList()); String gDuplicates = string.Join("\r\n", gColValues.GroupBy(v => v).Where(g => g.Count() > 1).Select(s => "- " + s.Key).ToList()); if (!string.IsNullOrEmpty(oDuplicates) && (profile.SyncDirection.Id == Sync.Direction.OutlookToGoogle.Id || profile.SyncDirection.Id == Sync.Direction.Bidirectional.Id)) { OgcsMessageBox.Show("The following Outlook categories cannot be mapped more than once:-\r\n\r\n" + oDuplicates, "Duplicate Outlook Mappings", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } else if (!string.IsNullOrEmpty(gDuplicates) && (profile.SyncDirection.Id == Sync.Direction.GoogleToOutlook.Id || profile.SyncDirection.Id == Sync.Direction.Bidirectional.Id)) { OgcsMessageBox.Show("The following Google colours cannot be mapped more than once:-\r\n\r\n" + gDuplicates, "Duplicate Google Mappings", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } } catch (System.Exception ex) { OGCSexception.Analyse("Failed looking for duplicating mappings before storing in Settings.", ex); OgcsMessageBox.Show("An error was encountered storing your custom mappings.", "Cannot save mappings", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } try { log.Fine("Storing colour mappings in Settings."); profile.ColourMaps.Clear(); foreach (DataGridViewRow row in colourGridView.Rows) { if (row.Cells["OutlookColour"].Value == null || row.Cells["OutlookColour"].Value.ToString().Trim() == "") { continue; } try { profile.ColourMaps.Add(row.Cells["OutlookColour"].Value.ToString(), GoogleOgcs.EventColour.Palette.GetColourId(row.Cells["GoogleColour"].Value.ToString())); } catch (System.ArgumentException ex) { if (OGCSexception.GetErrorCode(ex) == "0x80070057") { //An item with the same key has already been added } else { throw; } } } } catch (System.Exception ex) { OGCSexception.Analyse("Could not save colour/category mappings to Settings.", ex); } finally { this.Close(); } }
private void ogcsPushTimer_Tick(object sender, EventArgs e) { if (Forms.ErrorReporting.Instance.Visible) { return; } log.Fine("Push sync triggered."); try { System.Collections.Generic.List <Microsoft.Office.Interop.Outlook.AppointmentItem> items = OutlookOgcs.Calendar.Instance.GetCalendarEntriesInRange(true); if (items.Count < this.lastRunItemCount || items.FindAll(x => x.LastModificationTime > this.lastRunTime).Count > 0) { log.Debug("Changes found for Push sync."); Forms.Main.Instance.NotificationTray.ShowBubbleInfo("Autosyncing calendars: " + Settings.Instance.SyncDirection.Name + "..."); if (!Sync.Engine.Instance.SyncingNow) { Forms.Main.Instance.Sync_Click(sender, null); } else { log.Debug("Busy syncing already. No need to push."); } } else { log.Fine("No changes found."); } failures = 0; } catch (System.Exception ex) { failures++; log.Warn("Push Sync failed " + failures + " times to check for changed items."); String hResult = OGCSexception.GetErrorCode(ex); if ((ex is System.InvalidCastException && hResult == "0x80004002" && ex.Message.Contains("0x800706BA")) || //The RPC server is unavailable (ex is System.Runtime.InteropServices.COMException && ( ex.Message.Contains("0x80010108(RPC_E_DISCONNECTED)") || //The object invoked has disconnected from its clients hResult == "0x800706BE" || //The remote procedure call failed hResult == "0x800706BA")) //The RPC server is unavailable ) { OGCSexception.Analyse(OGCSexception.LogAsFail(ex)); try { OutlookOgcs.Calendar.Instance.Reset(); } catch (System.Exception ex2) { OGCSexception.Analyse("Failed resetting Outlook connection.", ex2); } } else { OGCSexception.Analyse(ex); } if (failures == 10) { Forms.Main.Instance.Console.UpdateWithError("Push Sync is failing.", ex, notifyBubble: true); } } }
private void findCalendars(Folders folders, Dictionary <string, MAPIFolder> calendarFolders, String excludeDeletedFolder, MAPIFolder defaultCalendar = null) { //Initiate progress bar (red line underneath "Getting calendars" text) System.Drawing.Graphics g = Forms.Main.Instance.tabOutlook.CreateGraphics(); System.Drawing.Pen p = new System.Drawing.Pen(System.Drawing.Color.Red, 3); System.Drawing.Point startPoint = new System.Drawing.Point(Forms.Main.Instance.lOutlookCalendar.Location.X, Forms.Main.Instance.lOutlookCalendar.Location.Y + Forms.Main.Instance.lOutlookCalendar.Size.Height + 3); double stepSize = Forms.Main.Instance.lOutlookCalendar.Size.Width / folders.Count; int fldCnt = 0; foreach (MAPIFolder folder in folders) { fldCnt++; System.Drawing.Point endPoint = new System.Drawing.Point(Forms.Main.Instance.lOutlookCalendar.Location.X + Convert.ToInt16(fldCnt * stepSize), Forms.Main.Instance.lOutlookCalendar.Location.Y + Forms.Main.Instance.lOutlookCalendar.Size.Height + 3); try { g.DrawLine(p, startPoint, endPoint); } catch { /*May get GDI+ error if g has been repainted*/ } System.Windows.Forms.Application.DoEvents(); try { OlItemType defaultItemType = folder.DefaultItemType; if (defaultItemType == OlItemType.olAppointmentItem) { if (defaultCalendar == null || (folder.EntryID != defaultCalendar.EntryID)) { calendarFolderAdd(folder.Name, folder); } } if (folder.EntryID != excludeDeletedFolder && folder.Folders.Count > 0) { findCalendars(folder.Folders, calendarFolders, excludeDeletedFolder, defaultCalendar); } } catch (System.Exception ex) { OGCSexception.Analyse(ex); if (oApp.Session.ExchangeConnectionMode.ToString().Contains("Disconnected") || ex.Message.StartsWith("Network problems are preventing connection to Microsoft Exchange.") || OGCSexception.GetErrorCode(ex, 0x000FFFFF) == "0x00040115") { log.Info("Currently disconnected from Exchange - unable to retrieve MAPI folders."); Forms.Main.Instance.ToolTips.SetToolTip(Forms.Main.Instance.cbOutlookCalendars, "The Outlook calendar to synchonize with.\nSome may not be listed as you are currently disconnected."); } else { log.Error("Failed to recurse MAPI folders."); log.Error(ex.Message); MessageBox.Show("A problem was encountered when searching for Outlook calendar folders.", "Calendar Folders", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } } p.Dispose(); try { g.Clear(System.Drawing.Color.White); } catch { } g.Dispose(); System.Windows.Forms.Application.DoEvents(); }
/// <summary> /// Handles non-unique calendar names by recursively adding parent folders to the name /// </summary> /// <param name="name">Name/path of calendar (dictionary key)</param> /// <param name="folder">The target folder (dictionary value)</param> /// <param name="parentFolder">Recursive parent folder - leave null on initial call</param> private void calendarFolderAdd(String name, MAPIFolder folder, MAPIFolder parentFolder = null) { try { calendarFolders.Add(name, folder); } catch (System.ArgumentException ex) { if (OGCSexception.GetErrorCode(ex) == "0x80070057") { //An item with the same key has already been added. //Let's recurse up to the parent folder, looking to make it unique object parentObj = (parentFolder != null ? parentFolder.Parent : folder.Parent); if (parentObj is NameSpace) { //We've traversed all the way up the folder path to the root and still not unique log.Warn("MAPIFolder " + name + " does not have a unique name - so cannot use!"); } else if (parentObj is MAPIFolder) { String parentFolderName = (parentObj as MAPIFolder).FolderPath.Split('\\').Last(); calendarFolderAdd(System.IO.Path.Combine(parentFolderName, name), folder, parentObj as MAPIFolder); } } } }
private static void backupSettingsFile() { if (string.IsNullOrEmpty(settingsVersion)) { log.Debug("The settings file is a vanilla template. No need to back it up."); return; } String backupFile = ""; try { log.Info("Backing up '" + Settings.ConfigFile + "' for v" + settingsVersion); backupFile = System.Text.RegularExpressions.Regex.Replace(Settings.ConfigFile, @"(\.\w+)$", "-v" + settingsVersion + "$1"); File.Copy(Settings.ConfigFile, backupFile, false); log.Info(backupFile + " created."); } catch (System.IO.IOException ex) { if (OGCSexception.GetErrorCode(ex) == "0x80070050") //File already exists { log.Warn("The backfile already exists, not overwriting " + backupFile); } } catch (System.Exception ex) { OGCSexception.Analyse("Failed to create backup settings file", ex); } }
private void getGaccountEmail(String accessToken) { String jsonString = ""; log.Debug("Retrieving email address associated with Google account."); try { System.Net.WebClient wc = new System.Net.WebClient(); wc.Headers.Add("user-agent", Settings.Instance.Proxy.BrowserUserAgent); jsonString = wc.DownloadString("https://www.googleapis.com/plus/v1/people/me?fields=emails&access_token=" + accessToken); JObject jo = Newtonsoft.Json.Linq.JObject.Parse(jsonString); JToken jtEmail = jo["emails"].Where(e => e.Value <String>("type") == "account").First(); String email = jtEmail.Value <String>("value"); if (Settings.Instance.GaccountEmail != email) { if (!String.IsNullOrEmpty(Settings.Instance.GaccountEmail)) { log.Debug("Looks like the Google account username value has been tampering with? :-O"); } Settings.Instance.GaccountEmail = email; log.Debug("Updating Google account username: "******"Inner exception: " + ex.InnerException.Message); } if (ex.Response != null) { log.Debug("Reading response."); System.IO.Stream stream = ex.Response.GetResponseStream(); System.IO.StreamReader sr = new System.IO.StreamReader(stream); log.Error(sr.ReadToEnd()); } if (OGCSexception.GetErrorCode(ex) == "0x80131509") { log.Warn(ex.Message); System.Text.RegularExpressions.Regex rgx = new System.Text.RegularExpressions.Regex(@"\b(403|Forbidden|Prohibited|Insufficient Permission)\b", System.Text.RegularExpressions.RegexOptions.IgnoreCase); if (rgx.IsMatch(ex.Message)) { if (Settings.Instance.UsingPersonalAPIkeys()) { String msg = "If you are using your own API keys, you must also enable the Google+ API."; MessageBox.Show(msg, "Missing API Service", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation); throw new System.ApplicationException(msg); } else { if (getEmailAttempts > 1) { log.Error("Failed to retrieve Google account username."); log.Debug("Using previously retrieved username: "******"access denied")) { MainForm.Instance.Console.Update("Failed to obtain Calendar access from Google - it's possible your access has been revoked." + "<br/>Try disconnecting your Google account and reauthorising OGCS.", Console.Markup.error); } throw ex; } catch (System.Exception ex) { log.Debug("JSON: " + jsonString); log.Error("Failed to retrieve Google account username."); OGCSexception.Analyse(ex); log.Debug("Using previously retrieved username: " + Settings.Instance.GaccountEmail_masked()); } }
private SyncResult synchronize() { Console console = Forms.Main.Instance.Console; console.Update("Finding Calendar Entries", Console.Markup.mag_right, newLine: false); List <AppointmentItem> outlookEntries = null; List <Event> googleEntries = null; try { #region Read Outlook items console.Update("Scanning Outlook calendar..."); outlookEntries = OutlookOgcs.Calendar.Instance.GetCalendarEntriesInRange(false); console.Update(outlookEntries.Count + " Outlook calendar entries found.", Console.Markup.sectionEnd, newLine: false); if (CancellationPending) { return(SyncResult.UserCancelled); } #endregion #region Read Google items console.Update("Scanning Google calendar..."); try { googleEntries = GoogleOgcs.Calendar.Instance.GetCalendarEntriesInRange(); } catch (AggregateException agex) { OGCSexception.AnalyseAggregate(agex); } catch (Google.Apis.Auth.OAuth2.Responses.TokenResponseException ex) { OGCSexception.AnalyseTokenResponse(ex, false); return(SyncResult.Fail); } catch (System.Net.Http.HttpRequestException ex) { OGCSexception.Analyse(ex); ex.Data.Add("OGCS", "ERROR: Unable to connect to the Google calendar. Please try again."); throw ex; } catch (System.Exception ex) { OGCSexception.Analyse(ex); ex.Data.Add("OGCS", "ERROR: Unable to connect to the Google calendar."); if (OGCSexception.GetErrorCode(ex) == "0x8013153B") //ex.Message == "A task was canceled." - likely timed out. { ex.Data["OGCS"] += " Please try again."; } throw ex; } Recurrence.Instance.SeparateGoogleExceptions(googleEntries); if (Recurrence.Instance.GoogleExceptions != null && Recurrence.Instance.GoogleExceptions.Count > 0) { console.Update(googleEntries.Count + " Google calendar entries found."); console.Update(Recurrence.Instance.GoogleExceptions.Count + " are exceptions to recurring events.", Console.Markup.sectionEnd, newLine: false); } else { console.Update(googleEntries.Count + " Google calendar entries found.", Console.Markup.sectionEnd, newLine: false); } if (CancellationPending) { return(SyncResult.UserCancelled); } #endregion #region Normalise recurring items in sync window console.Update("Total inc. recurring items spanning sync date range..."); //Outlook returns recurring items that span the sync date range, Google doesn't //So check for master Outlook items occurring before sync date range, and retrieve Google equivalent for (int o = outlookEntries.Count - 1; o >= 0; o--) { log.Fine("Processing " + (o + 1) + "/" + outlookEntries.Count); AppointmentItem ai = null; try { if (outlookEntries[o] is AppointmentItem) { ai = outlookEntries[o]; } else if (outlookEntries[o] is MeetingItem) { log.Info("Calendar object appears to be a MeetingItem, so retrieving associated AppointmentItem."); MeetingItem mi = outlookEntries[o] as MeetingItem; outlookEntries[o] = mi.GetAssociatedAppointment(false); ai = outlookEntries[o]; } else { log.Warn("Unknown calendar object type - cannot sync it."); skipCorruptedItem(ref outlookEntries, outlookEntries[o], "Unknown object type."); outlookEntries[o] = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(outlookEntries[o]); continue; } } catch (System.Exception ex) { log.Warn("Encountered error casting calendar object to AppointmentItem - cannot sync it."); log.Debug(ex.Message); skipCorruptedItem(ref outlookEntries, outlookEntries[o], ex.Message); outlookEntries[o] = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(outlookEntries[o]); ai = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(ai); continue; } //Now let's check there's a start/end date - sometimes it can be missing, even though this shouldn't be possible!! String entryID; try { entryID = outlookEntries[o].EntryID; DateTime checkDates = ai.Start; checkDates = ai.End; } catch (System.Exception ex) { log.Warn("Calendar item does not have a proper date range - cannot sync it."); log.Debug(ex.Message); skipCorruptedItem(ref outlookEntries, outlookEntries[o], ex.Message); outlookEntries[o] = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(outlookEntries[o]); ai = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(ai); continue; } if (ai.IsRecurring && ai.Start.Date < Settings.Instance.SyncStart && ai.End.Date < Settings.Instance.SyncStart) { //We won't bother getting Google master event if appointment is yearly reoccurring in a month outside of sync range //Otherwise, every sync, the master event will have to be retrieved, compared, concluded nothing's changed (probably) = waste of API calls RecurrencePattern oPattern = ai.GetRecurrencePattern(); try { if (oPattern.RecurrenceType.ToString().Contains("Year")) { log.Fine("It's an annual event."); Boolean monthInSyncRange = false; DateTime monthMarker = Settings.Instance.SyncStart; while (Convert.ToInt32(monthMarker.ToString("yyyyMM")) <= Convert.ToInt32(Settings.Instance.SyncEnd.ToString("yyyyMM")) && !monthInSyncRange) { if (monthMarker.Month == ai.Start.Month) { monthInSyncRange = true; } monthMarker = monthMarker.AddMonths(1); } log.Fine("Found it to be " + (monthInSyncRange ? "inside" : "outside") + " sync range."); if (!monthInSyncRange) { outlookEntries.Remove(ai); log.Fine("Removed."); continue; } } Event masterEv = Recurrence.Instance.GetGoogleMasterEvent(ai); if (masterEv != null && masterEv.Status != "cancelled") { Event cachedEv = googleEntries.Find(x => x.Id == masterEv.Id); if (cachedEv == null) { googleEntries.Add(masterEv); } else { if (masterEv.Updated > cachedEv.Updated) { log.Debug("Refreshing cache for this Event."); googleEntries.Remove(cachedEv); googleEntries.Add(masterEv); } } } } catch (System.Exception ex) { console.Update("Failed to retrieve master for Google recurring event outside of sync range.", Console.Markup.error); throw ex; } finally { oPattern = (RecurrencePattern)OutlookOgcs.Calendar.ReleaseObject(oPattern); } } //Completely dereference object and retrieve afresh (due to GetRecurrencePattern earlier) ai = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(ai); OutlookOgcs.Calendar.Instance.IOutlook.GetAppointmentByID(entryID, out ai); outlookEntries[o] = ai; } console.Update("Outlook " + outlookEntries.Count + ", Google " + googleEntries.Count); GoogleOgcs.Calendar.ExportToCSV("Outputting all Events.", "google_events.csv", googleEntries); OutlookOgcs.Calendar.ExportToCSV("Outputting all Appointments.", "outlook_appointments.csv", outlookEntries); if (CancellationPending) { return(SyncResult.UserCancelled); } #endregion Boolean success = true; String bubbleText = ""; if (Settings.Instance.SyncDirection != Direction.GoogleToOutlook) { success = outlookToGoogle(outlookEntries, googleEntries, ref bubbleText); if (CancellationPending) { return(SyncResult.UserCancelled); } } if (!success) { return(SyncResult.Fail); } if (Settings.Instance.SyncDirection != Direction.OutlookToGoogle) { if (bubbleText != "") { bubbleText += "\r\n"; } success = googleToOutlook(googleEntries, outlookEntries, ref bubbleText); if (CancellationPending) { return(SyncResult.UserCancelled); } } if (bubbleText != "") { Forms.Main.Instance.NotificationTray.ShowBubbleInfo(bubbleText); } return(SyncResult.OK); } finally { for (int o = outlookEntries.Count() - 1; o >= 0; o--) { outlookEntries[o] = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(outlookEntries[o]); outlookEntries.RemoveAt(o); } } }
/// <summary> /// Get the Outlook category name for a given category colour. /// If category not yet used, new one added of the form "OGCS [colour]" /// </summary> /// <param name="olCategory">The Outlook category to search by</param> /// <param name="categoryName">Optional: The Outlook category name to also search by</param> /// <param name="createMissingCategory">Optional: Create unused category colour?</param> /// <returns>The matching category name</returns> public String FindName(Outlook.OlCategoryColor?olCategory, String categoryName = null, Boolean createMissingCategory = true) { if (olCategory == null || olCategory == Outlook.OlCategoryColor.olCategoryColorNone) { return(""); } Outlook.Category failSafeCategory = null; foreach (Outlook.Category category in this.categories) { try { if (category.Color == olCategory) { if (categoryName == null) { if (category.Name.StartsWith("OGCS ")) { return(category.Name); } else if (!createMissingCategory) { return(category.Name); } } else { if (category.Name == categoryName) { return(category.Name); } if (category.Name.StartsWith("OGCS ")) { failSafeCategory = category; } } } } catch (System.Runtime.InteropServices.COMException ex) { if (OGCSexception.GetErrorCode(ex, 0x0000FFFF) == "0x00004005") //The operation failed. { log.Warn("It seems a category has been manually removed in Outlook."); OutlookOgcs.Calendar.Instance.IOutlook.RefreshCategories(); } else { throw; } } } if (failSafeCategory != null) { log.Warn("Failed to find Outlook category " + olCategory.ToString() + " with name '" + categoryName + "'"); log.Debug("Using category with name \"" + failSafeCategory.Name + "\" instead."); return(failSafeCategory.Name); } log.Debug("Did not find Outlook category " + olCategory.ToString() + (categoryName == null ? "" : " \"" + categoryName + "\"")); String newCategoryName = "OGCS " + FriendlyCategoryName(olCategory); if (!createMissingCategory) { createMissingCategory = System.Windows.Forms.OgcsMessageBox.Show("There is no matching Outlook category.\r\nWould you like to create one of the form '" + newCategoryName + "'?", "Create new Outlook category?", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes; } if (createMissingCategory) { Outlook.Category newCategory = categories.Add(newCategoryName, olCategory); log.Info("Added new Outlook category \"" + newCategory.Name + "\" for " + newCategory.Color.ToString()); return(newCategory.Name); } return(""); }
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 (!Forms.Main.Instance.IsHandleCreated && (DateTime.Now - triggerOOMsecurity).TotalSeconds > 1) { log.Warn(">1s delay possibly due to Outlook security popup."); OutlookOgcs.Calendar.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)OutlookOgcs.Calendar.ReleaseObject(oNS); Disconnect(); OutlookOgcs.Calendar.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)OutlookOgcs.Calendar.ReleaseObject(currentUser); if (releaseNamespace) { oNS = (NameSpace)OutlookOgcs.Calendar.ReleaseObject(oNS); } } return(oNS); }
public static void Initialise() { if (Program.StartedWithSquirrelArgs && !(Environment.GetCommandLineArgs()[1].ToLower().Equals("--squirrel-firstrun"))) { return; } if (Program.InDeveloperMode) { return; } //Note, logging isn't actually initialised yet, so log4net won't log any lines within this function String cloudCredsURL = "https://raw.githubusercontent.com/phw198/OutlookGoogleCalendarSync/master/docs/keyring.md"; String html = null; String line = null; String placeHolder = "###"; String cloudID = null; String cloudKey = null; log.Debug("Getting credential attributes"); try { try { html = new Extensions.OgcsWebClient().DownloadString(cloudCredsURL); html = html.Replace("\n", ""); } catch (System.Exception ex) { log.Error("Failed to retrieve data: " + ex.Message); } if (string.IsNullOrEmpty(html)) { throw new ApplicationException("Not able to retrieve error reporting credentials."); } Regex rgx = new Regex(@"### Error Reporting.*\|ID\|(.*)\|\|Key\|(.*?)\|", RegexOptions.IgnoreCase); MatchCollection keyRecords = rgx.Matches(html); if (keyRecords.Count == 1) { cloudID = keyRecords[0].Groups[1].ToString(); cloudKey = keyRecords[0].Groups[2].ToString(); } else { throw new ApplicationException("Unexpected parse of error reporting credentials."); } List <String> newLines = new List <string>(); StreamReader sr = new StreamReader(templateCredFile); while ((line = sr.ReadLine()) != null) { if (line.IndexOf(placeHolder) > 0) { if (line.IndexOf("private_key_id") > 0) { line = line.Replace(placeHolder, cloudID); } else if (line.IndexOf("private_key") > 0) { line = line.Replace(placeHolder, cloudKey); } } newLines.Add(line); } try { File.WriteAllLines(credFile, newLines.ToArray()); } catch (System.IO.IOException ex) { if (OGCSexception.GetErrorCode(ex) == "0x80070020") { log.Warn("ErrorReporting.json is being used by another process (perhaps multiple instances of OGCS are being started on system startup?)"); } else { throw; } } Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", credFile); } catch (ApplicationException ex) { log.Warn(ex.Message); Initialised = false; //} catch (System.Exception ex) { //Logging isn't initialised yet, so don't catch this error - let it crash out so user is aware and hopefully reports it! //System.Windows.Forms.OgcsMessageBox.Show(ex.Message); //log.Debug("Failed to initialise error reporting."); //OGCSexception.Analyse(ex); } }
public void Connect() { if (!OutlookOgcs.Calendar.InstanceConnect) { return; } OutlookOgcs.Calendar.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()); 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 (Forms.Main.Instance.IsHandleCreated) { log.Fine("Resetting connection, so re-selecting calendar from GUI dropdown"); Forms.Main.Instance.cbOutlookCalendars.SelectedIndexChanged -= Forms.Main.Instance.cbOutlookCalendar_SelectedIndexChanged; Forms.Main.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) { Forms.Main.Instance.SetControlPropertyThreadSafe(Forms.Main.Instance.cbOutlookCalendars, "SelectedIndex", c); } c++; } if ((int)Forms.Main.Instance.GetControlPropertyThreadSafe(Forms.Main.Instance.cbOutlookCalendars, "SelectedIndex") == -1) { Forms.Main.Instance.SetControlPropertyThreadSafe(Forms.Main.Instance.cbOutlookCalendars, "SelectedIndex", 0); } KeyValuePair <String, MAPIFolder> calendar = (KeyValuePair <String, MAPIFolder>)Forms.Main.Instance.GetControlPropertyThreadSafe(Forms.Main.Instance.cbOutlookCalendars, "SelectedItem"); useOutlookCalendar = calendar.Value; Forms.Main.Instance.cbOutlookCalendars.SelectedIndexChanged += Forms.Main.Instance.cbOutlookCalendar_SelectedIndexChanged; } OutlookOgcs.Calendar.Categories = new OutlookOgcs.Categories(); Calendar.Categories.Get(oApp, useOutlookCalendar); //Set up event handlers explorerWatcher = new ExplorerWatcher(oApp); } catch (System.Runtime.InteropServices.COMException ex) { if (OGCSexception.GetErrorCode(ex) == "0x84120009") //Cannot complete the operation. You are not connected. [Issue #514, occurs on GetNamespace("mapi")] { log.Warn(ex.Message); throw new ApplicationException("A problem was encountered with your Office install.\r\n" + "Please perform an Office Repair or reinstall Outlook and then try running OGCS again."); } else { throw ex; } } finally { // Done. Log off. if (oNS != null) { oNS.Logoff(); } oNS = (NameSpace)OutlookOgcs.Calendar.ReleaseObject(oNS); } }