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) {
                OGCSexception.LogAsFail(ref 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.")
                {
                    OGCSexception.Analyse("This Outlook recurrence instance has become inaccessible, probably due to caching", ex);
                }
                else
                {
                    OGCSexception.Analyse("Error when determining if Outlook recurrence is deleted or not.", ex);
                }
                return(true);
            } finally {
                ai = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(ai);
            }
        }
        public static void OpenBrowser(String url)
        {
            try {
                System.Diagnostics.Process.Start(url);
                return;
            } catch (System.Exception ex) {
                OGCSexception.Analyse("Could not open default browser.", OGCSexception.LogAsFail(ex));
            }

            //OK, let's try and determine the default browser from the registry and then directly invoke it. Why is this so much work!
            String browserPath = getDefaultBrowserPath();

            if (string.IsNullOrEmpty(browserPath))
            {
                log.Error("No default browser discovered in the registry.");
            }
            else
            {
                try {
                    log.Debug("Browsing using " + browserPath);
                    System.Diagnostics.Process.Start(browserPath, url);
                } catch (System.Exception ex) {
                    log.Fail("Could not navigate to " + url);
                    log.Error("Could not open browser with " + browserPath, ex);
                }
            }
        }
        private static void isNewVersion(Boolean isSquirrelInstall)
        {
            string settingsVersion = string.IsNullOrEmpty(Settings.Instance.Version) ? "Unknown" : Settings.Instance.Version;

            if (settingsVersion != Application.ProductVersion)
            {
                log.Info("New version detected - upgraded from " + settingsVersion + " to " + Application.ProductVersion);
                try {
                    Program.ManageStartupRegKey(recreate: true);
                } catch (System.Exception ex) {
                    if (ex is System.Security.SecurityException)
                    {
                        OGCSexception.LogAsFail(ref ex);                                          //User doesn't have rights to access registry
                    }
                    OGCSexception.Analyse("Failed accessing registry for startup key.", ex);
                }
                Settings.Instance.Version = Application.ProductVersion;
                if (Application.ProductVersion.EndsWith(".0"))   //Release notes not updated for hotfixes.
                {
                    System.Diagnostics.Process.Start("https://github.com/phw198/OutlookGoogleCalendarSync/blob/master/docs/Release%20Notes.md");
                    if (isSquirrelInstall)
                    {
                        Telemetry.Send(Analytics.Category.squirrel, Analytics.Action.upgrade, "from=" + settingsVersion + ";to=" + Application.ProductVersion);
                    }
                }
            }

            //Check upgrade to Squirrel release went OK
            try {
                if (isSquirrelInstall)
                {
                    Int32  upgradedFrom       = Int16.MaxValue;
                    String expectedInstallDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
                    expectedInstallDir = Path.Combine(expectedInstallDir, "OutlookGoogleCalendarSync");
                    String paddedVersion = "";
                    if (settingsVersion != "Unknown")
                    {
                        foreach (String versionBit in settingsVersion.Split('.'))
                        {
                            paddedVersion += versionBit.PadLeft(2, '0');
                        }
                        upgradedFrom = Convert.ToInt32(paddedVersion);
                    }
                    if ((settingsVersion == "Unknown" || upgradedFrom < 2050000) &&
                        !System.Windows.Forms.Application.ExecutablePath.ToString().StartsWith(expectedInstallDir))
                    {
                        log.Warn("OGCS is running from " + System.Windows.Forms.Application.ExecutablePath.ToString());
                        OgcsMessageBox.Show("A suspected improper install location has been detected.\r\n" +
                                            "Click 'OK' for further details.", "Improper Install Location",
                                            MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        System.Diagnostics.Process.Start("https://github.com/phw198/OutlookGoogleCalendarSync/issues/265");
                    }
                }
            } catch (System.Exception ex) {
                log.Warn("Failed to determine if OGCS is installed in the correct location.");
                log.Error(ex.Message);
            }
        }
 private static void purgeLogFiles(Int16 retention)
 {
     log.Info("Purging log files older than " + retention + " days...");
     foreach (String file in System.IO.Directory.GetFiles(UserFilePath, "*.log.????-??-??", SearchOption.TopDirectoryOnly))
     {
         if (System.IO.File.GetLastWriteTime(file) < DateTime.Now.AddDays(-retention))
         {
             try {
                 System.IO.File.Delete(file);
                 log.Debug("Deleted " + MaskFilePath(file));
             } catch (System.Exception ex) {
                 OGCSexception.Analyse("Could not delete file " + file, OGCSexception.LogAsFail(ex));
             }
         }
     }
     log.Info("Purge complete.");
 }
        /// <returns>True if the user has upgraded</returns>
        private async Task <Boolean> githubCheck()
        {
            log.Debug("Checking for Squirrel update...");
            UpdateManager updateManager = null;

            isBusy = true;
            try {
                String installRootDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
                if (string.IsNullOrEmpty(nonGitHubReleaseUri))
                {
                    updateManager = await Squirrel.UpdateManager.GitHubUpdateManager("https://github.com/phw198/OutlookGoogleCalendarSync", "OutlookGoogleCalendarSync", installRootDir,
                                                                                     new Squirrel.FileDownloader(new Extensions.OgcsWebClient()), prerelease : Settings.Instance.AlphaReleases);
                }
                else
                {
                    updateManager = new Squirrel.UpdateManager(nonGitHubReleaseUri, "OutlookGoogleCalendarSync", installRootDir);
                }

                UpdateInfo updates = await updateManager.CheckForUpdate();

                if (updates.ReleasesToApply.Any())
                {
                    if (updates.CurrentlyInstalledVersion != null)
                    {
                        log.Info("Currently installed version: " + updates.CurrentlyInstalledVersion.Version.ToString());
                    }
                    log.Info("Found " + updates.ReleasesToApply.Count() + " newer releases available.");
                    log.Info("Download directory = " + updates.PackageDirectory);

                    DialogResult dr = DialogResult.Cancel;
                    String       squirrelAnalyticsLabel = "";
                    String       releaseNotes           = "";
                    String       releaseVersion         = "";
                    String       releaseType            = "";

                    foreach (ReleaseEntry update in updates.ReleasesToApply.OrderBy(x => x.Version).Reverse())
                    {
                        log.Info("New " + update.Version.SpecialVersion + " version available: " + update.Version.Version.ToString());

                        if (!this.isManualCheck && update.Version.Version.ToString() == Settings.Instance.SkipVersion)
                        {
                            log.Info("The user has previously requested to skip this version.");
                            break;
                        }

                        String localFile = updates.PackageDirectory + "\\" + update.Filename;
                        if (updateManager.CheckIfAlreadyDownloaded(update, localFile))
                        {
                            log.Debug("This has already been downloaded.");
                        }
                        else
                        {
                            try {
                                //"https://github.com/phw198/OutlookGoogleCalendarSync/releases/download/v2.8.6-alpha"
                                String nupkgUrl = "https://github.com/phw198/OutlookGoogleCalendarSync/releases/download/v" + update.Version + "/" + update.Filename;
                                log.Debug("Downloading " + nupkgUrl);
                                new Extensions.OgcsWebClient().DownloadFile(nupkgUrl, localFile);
                                log.Debug("Download complete.");
                            } catch (System.Exception ex) {
                                OGCSexception.Analyse("Failed downloading release file for " + update.Version, ex);
                                throw new ApplicationException("Failed upgrading OGCS.", ex);
                            }
                        }

                        if (string.IsNullOrEmpty(releaseNotes))
                        {
                            log.Debug("Retrieving release notes.");
                            releaseNotes           = update.GetReleaseNotes(updates.PackageDirectory);
                            releaseVersion         = update.Version.Version.ToString();
                            releaseType            = update.Version.SpecialVersion;
                            squirrelAnalyticsLabel = "from=" + Application.ProductVersion + ";to=" + update.Version.Version.ToString();
                        }
                    }

                    var t = new System.Threading.Thread(() => new Forms.UpdateInfo(releaseVersion, releaseType, releaseNotes, out dr));
                    t.SetApartmentState(System.Threading.ApartmentState.STA);
                    t.Start();
                    t.Join();

                    if (dr == DialogResult.No)
                    {
                        log.Info("User chose not to upgrade right now.");
                        Telemetry.Send(Analytics.Category.squirrel, Analytics.Action.upgrade, squirrelAnalyticsLabel + ";later");
                    }
                    else if (dr == DialogResult.Ignore)
                    {
                        Telemetry.Send(Analytics.Category.squirrel, Analytics.Action.upgrade, squirrelAnalyticsLabel + ";skipped");
                    }
                    else if (dr == DialogResult.Yes)
                    {
                        try {
                            Telemetry.Send(Analytics.Category.squirrel, Analytics.Action.download, squirrelAnalyticsLabel + ";successful");
                            log.Info("Applying the updated release(s)...");
                            //updateManager.UpdateApp().Wait();

                            int ApplyAttempt = 1;
                            while (ApplyAttempt <= 5)
                            {
                                try {
                                    updateManager.ApplyReleases(updates).Wait();
                                    break;
                                } catch (System.AggregateException ex) {
                                    ApplyAttempt++;
                                    if (OGCSexception.GetErrorCode(ex.InnerException) == "0x80070057")   //File does not exist
                                    //File does not exist: C:\Users\Paul\AppData\Local\OutlookGoogleCalendarSync\packages\OutlookGoogleCalendarSync-2.8.4-alpha-full.nupkg
                                    //Extract the nupkg filename
                                    {
                                        String regexMatch = ".*" + updates.PackageDirectory.Replace(@"\", @"\\") + @"\\(.*?([\d\.]+-\w+).*)$";
                                        System.Text.RegularExpressions.Match match = System.Text.RegularExpressions.Regex.Match(ex.InnerException.Message, regexMatch);

                                        if (match?.Groups?.Count == 3)
                                        {
                                            log.Warn("Could not update as missing file " + match.Groups[1]);
                                            String nupkgUrl = "https://github.com/phw198/OutlookGoogleCalendarSync/releases/download/v" + match.Groups[2] + "/" + match.Groups[1];
                                            log.Debug("Downloading " + nupkgUrl);
                                            new Extensions.OgcsWebClient().DownloadFile(nupkgUrl, updates.PackageDirectory + "\\" + match.Groups[1]);
                                            log.Debug("Download complete.");
                                        }
                                    }
                                    else
                                    {
                                        throw;
                                    }
                                }
                            }

                            log.Info("The application has been successfully updated.");
                            OgcsMessageBox.Show("The application has been updated and will now restart.",
                                                "OGCS successfully updated!", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            restartUpdateExe = updateManager.RootAppDirectory + "\\Update.exe";
                            return(true);
                        } catch (System.AggregateException ae) {
                            foreach (System.Exception ex in ae.InnerExceptions)
                            {
                                OGCSexception.Analyse(ex, true);
                                ex.Data.Add("analyticsLabel", squirrelAnalyticsLabel);
                                throw new ApplicationException("Failed upgrading OGCS.", ex);
                            }
                        } catch (System.Exception ex) {
                            OGCSexception.Analyse(ex, true);
                            ex.Data.Add("analyticsLabel", squirrelAnalyticsLabel);
                            throw new ApplicationException("Failed upgrading OGCS.", ex);
                        }
                    }
                }
                else
                {
                    log.Info("Already running the latest version of OGCS.");
                    if (this.isManualCheck)   //Was a manual check, so give feedback
                    {
                        OgcsMessageBox.Show("You are already running the latest version of OGCS.", "Latest Version", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
            } catch (ApplicationException ex) {
                Telemetry.Send(Analytics.Category.squirrel, Analytics.Action.download, ex.Data["analyticsLabel"] + ";failed");
                throw;
            } catch (System.AggregateException ae) {
                log.Fail("Failed checking for update.");
                foreach (System.Exception ex in ae.InnerExceptions)
                {
                    OGCSexception.Analyse(OGCSexception.LogAsFail(ex), true);
                    throw;
                }
            } catch (System.Exception ex) {
                OGCSexception.Analyse("Failed checking for update.", OGCSexception.LogAsFail(ex), true);
                throw;
            } finally {
                isBusy = false;
                updateManager.Dispose();
            }
            return(false);
        }
        /// <returns>True if the user has upgraded</returns>
        private async Task <Boolean> githubCheck()
        {
            log.Debug("Checking for Squirrel update...");
            UpdateManager updateManager = null;

            isBusy = true;
            try {
                String installRootDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
                if (string.IsNullOrEmpty(nonGitHubReleaseUri))
                {
                    updateManager = await Squirrel.UpdateManager.GitHubUpdateManager("https://github.com/phw198/OutlookGoogleCalendarSync", "OutlookGoogleCalendarSync", installRootDir,
                                                                                     prerelease : Settings.Instance.AlphaReleases);
                }
                else
                {
                    updateManager = new Squirrel.UpdateManager(nonGitHubReleaseUri, "OutlookGoogleCalendarSync", installRootDir);
                }

                UpdateInfo updates = await updateManager.CheckForUpdate();

                if (updates.ReleasesToApply.Any())
                {
                    if (updates.CurrentlyInstalledVersion != null)
                    {
                        log.Info("Currently installed version: " + updates.CurrentlyInstalledVersion.Version.ToString());
                    }
                    log.Info("Found " + updates.ReleasesToApply.Count() + " newer releases available.");

                    foreach (ReleaseEntry update in updates.ReleasesToApply.OrderBy(x => x.Version).Reverse())
                    {
                        log.Info("Found a new " + update.Version.SpecialVersion + " version: " + update.Version.Version.ToString());

                        if (!this.isManualCheck && update.Version.Version.ToString() == Settings.Instance.SkipVersion)
                        {
                            log.Info("The user has previously requested to skip this version.");
                            break;
                        }

                        String releaseNotes = "";
                        if (nonGitHubReleaseUri != null)
                        {
                            releaseNotes = update.GetReleaseNotes(nonGitHubReleaseUri);
                        }
                        else
                        {
                            //Somewhat annoyingly we have to download the release in order to get the release notes, as they are embedded in the .nupkg upgrade file(s)
                            try {
                                updateManager.DownloadReleases(new[] { update }).Wait(30 * 1000);
                                System.Collections.Generic.Dictionary <ReleaseEntry, String> allReleaseNotes = updates.FetchReleaseNotes();
                                releaseNotes = allReleaseNotes[update];
                            } catch (System.Exception ex) {
                                OGCSexception.Analyse(ex);
                                log.Error("Failed pre-fetching release notes. " + ex.Message);
                                releaseNotes = null;
                            }
                        }

                        DialogResult dr = DialogResult.Cancel;
                        if (!string.IsNullOrEmpty(releaseNotes))
                        {
                            log.Debug("Release notes retrieved.");
                        }
                        var t = new System.Threading.Thread(() => new Forms.UpdateInfo(update.Version.Version.ToString(), update.Version.SpecialVersion, releaseNotes, out dr));
                        t.SetApartmentState(System.Threading.ApartmentState.STA);
                        t.Start();
                        t.Join();

                        String squirrelAnalyticsLabel = "from=" + Application.ProductVersion + ";to=" + update.Version.Version.ToString();
                        if (dr == DialogResult.No)
                        {
                            log.Info("User chose not to upgrade right now.");
                            Telemetry.Send(Analytics.Category.squirrel, Analytics.Action.upgrade, squirrelAnalyticsLabel + ";later");
                        }
                        else if (dr == DialogResult.Ignore)
                        {
                            Telemetry.Send(Analytics.Category.squirrel, Analytics.Action.upgrade, squirrelAnalyticsLabel + ";skipped");
                        }
                        else if (dr == DialogResult.Yes)
                        {
                            log.Debug("Download started...");
                            if (!updateManager.DownloadReleases(new[] { update }).Wait(60 * 1000))
                            {
                                log.Warn("The download failed to completed within 60 seconds.");
                                Telemetry.Send(Analytics.Category.squirrel, Analytics.Action.download, squirrelAnalyticsLabel + ";timedout");
                                if (MessageBox.Show("The update failed to download.", "Download timed out", MessageBoxButtons.RetryCancel, MessageBoxIcon.Exclamation) == DialogResult.Retry)
                                {
                                    if (!updateManager.DownloadReleases(new[] { update }).Wait(60 * 1000))
                                    {
                                        Telemetry.Send(Analytics.Category.squirrel, Analytics.Action.download, squirrelAnalyticsLabel + ";retry-timedout");
                                        if (MessageBox.Show("The update failed to download again.\nTo download from the project website, click Yes.", "Download timed out", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes)
                                        {
                                            Telemetry.Send(Analytics.Category.squirrel, Analytics.Action.download, squirrelAnalyticsLabel + ";from-website");
                                            System.Diagnostics.Process.Start("https://phw198.github.io/OutlookGoogleCalendarSync/");
                                        }
                                        else
                                        {
                                            Telemetry.Send(Analytics.Category.squirrel, Analytics.Action.download, squirrelAnalyticsLabel + ";gave-up");
                                        }
                                        break;
                                    }
                                }
                                else
                                {
                                    if (MessageBox.Show("Would you like to download directly from the project website?", "Go to OGCS website", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes)
                                    {
                                        Telemetry.Send(Analytics.Category.squirrel, Analytics.Action.download, squirrelAnalyticsLabel + ";from-website");
                                        System.Diagnostics.Process.Start("https://phw198.github.io/OutlookGoogleCalendarSync/");
                                    }
                                    else
                                    {
                                        Telemetry.Send(Analytics.Category.squirrel, Analytics.Action.download, squirrelAnalyticsLabel + ";gave-up");
                                    }
                                    break;
                                }
                            }

                            try {
                                log.Debug("Download complete.");
                                Telemetry.Send(Analytics.Category.squirrel, Analytics.Action.download, squirrelAnalyticsLabel + ";successful");
                                log.Info("Applying the updated release...");
                                updateManager.ApplyReleases(updates).Wait();

                                log.Info("The application has been successfully updated.");
                                MessageBox.Show("The application has been updated and will now restart.",
                                                "OGCS successfully updated!", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                restartUpdateExe = updateManager.RootAppDirectory + "\\Update.exe";
                                return(true);
                            } catch (System.AggregateException ae) {
                                foreach (System.Exception ex in ae.InnerExceptions)
                                {
                                    OGCSexception.Analyse(ex, true);
                                    ex.Data.Add("analyticsLabel", squirrelAnalyticsLabel);
                                    throw new ApplicationException("Failed upgrading OGCS.", ex);
                                }
                            } catch (System.Exception ex) {
                                OGCSexception.Analyse(ex, true);
                                ex.Data.Add("analyticsLabel", squirrelAnalyticsLabel);
                                throw new ApplicationException("Failed upgrading OGCS.", ex);
                            }
                        }
                        break;
                    }
                }
                else
                {
                    log.Info("Already running the latest version of OGCS.");
                    if (this.isManualCheck)   //Was a manual check, so give feedback
                    {
                        MessageBox.Show("You are already running the latest version of OGCS.", "Latest Version", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
            } catch (ApplicationException ex) {
                Telemetry.Send(Analytics.Category.squirrel, Analytics.Action.download, ex.Data["analyticsLabel"] + ";failed");
                throw ex;
            } catch (System.AggregateException ae) {
                log.Fail("Failed checking for update.");
                foreach (System.Exception ex in ae.InnerExceptions)
                {
                    OGCSexception.Analyse(OGCSexception.LogAsFail(ex), true);
                    throw ex;
                }
            } catch (System.Exception ex) {
                OGCSexception.Analyse("Failed checking for update.", OGCSexception.LogAsFail(ex), true);
                throw ex;
            } finally {
                isBusy = false;
                updateManager.Dispose();
            }
            return(false);
        }