none
At what point are shared calendars initialized? RRS feed

  • Question

  • OS: 64-Bit or 32-Bit Windows 7 Professional SP1.  This issue occurs on both plat forms

    Outlook: 2010 14.0.7127.500 SP2  | MSO 14.0.7128.5000

    Whenever I try and access the NavigationFolder.Folder property I get the exception "Operation Failed".

    This is a known Outlook 2010 issue. http://support.microsoft.com/kb/2265515/en-US 0 is

    I translated the code provided by Microsoft in the article into C#.  I notice that the error will only intermittently now.

    As an experiment, I through my code into an event that would only be fired long after Outlook was done with it's initialization process.  I was able to access NavigationFolder.Folder every time without a problem.  Unfortunately, I need access to shared calendars long before this.

    THE QUESTION:  So when can I safely access the NavigationFolder.Folder property?  Basically, when is Outlook done with it's startup process.

    WHAT I'VE TRIED SO FAR

    Application_MAPILogonComplete was no help.  This function's highly misrepresented.  Outlook is doing stuff even after this event fires.

    Explorer_SelectionChange was a little better.  Sometimes it would take a few tries before the exception was no longer thrown.

    I noticed that when I did a folder switch that I was able to access the NavigationFolder.Folder consistently. 


    Friday, August 8, 2014 5:03 PM

Answers

  • SelectionChange() is your best bet for that. Most of the UI is finished by the time it first fires. Before accessing the folders from the NavigtaionFolder object have you tried forcing Outlook to open all the folders by iterating the Stores collection of NameSpace? You could use the GetDefaultFolder() method for each Store, and then accessing the Items collection should force the initializations of the store. It's similar to a trick to get Public Folders set when Outlook opens.

    Ken Slovak MVP - Outlook

    • Marked as answer by Germán_MSO Friday, August 15, 2014 7:15 PM
    Friday, August 15, 2014 2:09 PM
    Moderator
  • I brought this thread, and the other one you have on BeforeItemMove, to the attemtion of the Outlook product group and the Supportability PM for Outlook. At least now both issues are directly in front of the product group.

    Ken Slovak MVP - Outlook

    • Marked as answer by Germán_MSO Thursday, August 21, 2014 5:45 PM
    Monday, August 18, 2014 2:00 PM
    Moderator

All replies

  • Hello German,

    It looks like you are interested in the Startup event of the Application class. Also take a look at the AutoDiscoverComplete event of the Namespace class. The Outlook object model doesn't provide any other events for this.



    Friday, August 8, 2014 5:10 PM
  • My apologies for the late response.  I have been buried in Outlook Issues as you can tell.

    I've been using Application_ItemLoad event with some success.  However, it seems to need to fire a few times before I get a successful run.

    I will try your suggestion today and see how it goes.  it sounds pretty good.

    Friday, August 15, 2014 12:40 PM
  • The last resort is to use the System.Windows.Forms.Timer class to get the event with some delay.
    Friday, August 15, 2014 1:05 PM
  • SelectionChange() is your best bet for that. Most of the UI is finished by the time it first fires. Before accessing the folders from the NavigtaionFolder object have you tried forcing Outlook to open all the folders by iterating the Stores collection of NameSpace? You could use the GetDefaultFolder() method for each Store, and then accessing the Items collection should force the initializations of the store. It's similar to a trick to get Public Folders set when Outlook opens.

    Ken Slovak MVP - Outlook

    • Marked as answer by Germán_MSO Friday, August 15, 2014 7:15 PM
    Friday, August 15, 2014 2:09 PM
    Moderator
  • AtuoDiscoverComplete never even fired.

        public partial class ThisAddIn
        {
    
            Outlook.NameSpace _ns = null;
    
    
            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {
    
                
                _ns = Application.Session;
    
    
                _ns.AutoDiscoverComplete += new Outlook.NameSpaceEvents_AutoDiscoverCompleteEventHandler(_ns_AutoDiscoverComplete);
    
    ...
    
    }
    
            void _ns_AutoDiscoverComplete()
            {
                System.Diagnostics.Trace.WriteLine("[--_ns_AutoDiscoverComplete--]");
            }

    Friday, August 15, 2014 7:07 PM
  • Interesting what you say about getting the default folder for each store.

    The problem was that I would get "The operation failed." exception when accessing the NavigationFolder.Folder object.  Doing a GetSharedDefaultFolder call on each store would alleviate the need to call NavigationFolder.Folder altogether.

    Thanks!!!

    Friday, August 15, 2014 7:14 PM
  • I'd try something like this, called from the SelectionChange() handler:

    void LoopOverStores()

    {

    // no error handling, object release and whatever. just an example

    Outlook.Stores stores = ns.Stores;

    Outlook.Store store = null;

    Outlook.Folder folder = null;

    Outlook.Items items = null;

    int c = 0;

    for (int I = 1; I <= stores.Count; I++)

    {

         store = stores[I] as Outlook.Store;

         folder = store.GetDefaultFolder(olFolderCalendar);

         items = folder.Items;

         c = items.Count;

         // clean up objects here for loop

    }

    // final cleanup

    }

    That way you're forcing Outlook to open each store and to open the calendar folders. See if after that you can access what you want consistently.


    Ken Slovak MVP - Outlook

    Friday, August 15, 2014 8:19 PM
    Moderator
  • I'll try that ASAP
    Friday, August 15, 2014 8:47 PM
  •             if (bSharedCalendarsInitialized == false)
                {
                    Outlook.Stores stores = _ns.Stores;
                    Outlook.Store store = null;
                    Outlook.Folder folder = null;
                    Outlook.Items items = null;
                    int count = 0;
    
                    for (int i = 1; i <= stores.Count; i++)
                    {
                        store = stores[i] as Outlook.Store;
                        folder = store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar) as Outlook.Folder;
                        items = folder.Items;
                        count = items.Count;
    
                        Marshal.ReleaseComObject(items); items = null;
                        Marshal.ReleaseComObject(folder); folder = null;
                        Marshal.ReleaseComObject(store); store = null;
                    }
    
                    Marshal.ReleaseComObject(stores); stores = null;
                }

    It looks like I still get the same result.  By that I mean, I have to run my initialization code a couple of times until I stop getting the exception "The operation failed."

    Shown is how I implanted the code you gave.  After the loop I make my calls to get the shared calendars.

    Friday, August 15, 2014 9:06 PM
  • Are you able to access the folder and items from the Stores collection without error in that initial loop? If so just try using that object reference.

    Also, take a look at Dmitry's old post on this: http://social.msdn.microsoft.com/Forums/office/de-DE/d3a70f7f-ce95-49f2-9fe8-165c6d3e0d14/how-to-get-the-entryids-of-the-shared-calendars-via-mapi-outlook-2010?forum=outlookdev

    It doesn't provide information on when the folders are initialized, but it's interesting nonetheless.


    Ken Slovak MVP - Outlook

    Saturday, August 16, 2014 5:19 PM
    Moderator
  • The call to GetDefaultFolder throws the following Exception

    The attempted operation failed.  An object could not be found.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml.Linq;
    using Outlook = Microsoft.Office.Interop.Outlook;
    using Office = Microsoft.Office.Core;
    using System.Runtime.InteropServices;
    
    namespace BeforeItemMoveBug
    {
        public partial class ThisAddIn
        {
            Dictionary<string /*storeID*/, CalendarWrapper > SharedCalendars;
            Outlook.NameSpace _ns = null;
            Outlook.Explorer _explorer = null;
            bool bSharedCalendarsInitialized = false;
    
            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {
                System.Diagnostics.Trace.WriteLine("[--ThisAddIn_Startup--]"); 
                
                _ns = Application.Session;
                _explorer = Application.ActiveExplorer();
    
                SharedCalendars = new Dictionary<string, CalendarWrapper>();
    
                _explorer.SelectionChange += new Outlook.ExplorerEvents_10_SelectionChangeEventHandler(_explorer_SelectionChange);
                ((Outlook.ApplicationEvents_11_Event)Application).Quit += new Outlook.ApplicationEvents_11_QuitEventHandler(ThisAddIn_Quit);
            }
    
    
    
            void ThisAddIn_Quit()
            {
                System.Diagnostics.Trace.WriteLine("[--ThisAddIn_Quit--]");
            }
    
            /// <summary>
            /// GetSharedCalendars()
            /// 
            /// This code iterates through the shared calendars listed in the Navigation Pane of your Calendar Folder
            /// It is normal to get "The operation failed." a few times while Outlook is loading.
            /// 
            /// </summary>
            /// <returns></returns>
            bool GetSharedCalendars()
            {
                   
    
                // Process for getting shared calendars
                return true; 
    
            }
            void _explorer_SelectionChange()
            {
                System.Diagnostics.Trace.WriteLine("[--_explorer_SelectionChange--]");
    
    
                if (bSharedCalendarsInitialized == false)
                {
                    Outlook.Stores stores = _ns.Stores;
                    Outlook.Store store = null;
                    Outlook.Folder folder = null;
                    Outlook.Items items = null;
                    int count = 0;
    
                    try
                    {
                        for (int i = 1; i <= stores.Count; i++)
                        {
                            store = stores[i] as Outlook.Store;
                            folder = store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar) as Outlook.Folder;
                            items = folder.Items;
                            count = items.Count;
    
                            Marshal.ReleaseComObject(items); items = null;
                            Marshal.ReleaseComObject(folder); folder = null;
                            Marshal.ReleaseComObject(store); store = null;
                        }
                    }
                    catch (Exception _e)
                    {
                        System.Diagnostics.Trace.WriteLine("Exception [SelectionChange]: " + _e.Message);
                    }
                    finally
                    {
                        if (items != null) { Marshal.ReleaseComObject(items); items = null; }
                        if (folder != null) { Marshal.ReleaseComObject(folder); folder = null; }
                        if (store != null) { Marshal.ReleaseComObject(store); store = null; }
                    }
                   
                    Marshal.ReleaseComObject(stores); stores = null;
                }
    
                Outlook.View view = _explorer.CurrentView;
                if (view.Name == "Calendar")
                {
                    if (bSharedCalendarsInitialized == false)
                    {
                        bSharedCalendarsInitialized = GetSharedCalendars();
                    }
                }
                Marshal.ReleaseComObject(view); view = null;
    
    
    
            }
    
            private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
            {
                System.Diagnostics.Trace.WriteLine("[--ThisAddIn_Shutdown--]");
            }
    
            #region VSTO generated code
    
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InternalStartup()
            {
                this.Startup += new System.EventHandler(ThisAddIn_Startup);
                this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
            }
            
            #endregion
        }
    }
    

    Sunday, August 17, 2014 12:48 PM
  • Good article by Dimitry.  Thanks!!
    Sunday, August 17, 2014 12:50 PM
  • It's looking like what's missing is an initial call to GetRootFolder.

                            store = stores[i] as Outlook.Store;
                            rootFolder = store.GetRootFolder() as Outlook.Folder; 
                            items = rootFolder.Items;
                            count = items.Count;

    That call returns no errors.  I can then iterate through the subfolders. 

    I'll give that a try and get back to you with a code sample.

    Sunday, August 17, 2014 2:32 PM
  • I brought this thread, and the other one you have on BeforeItemMove, to the attemtion of the Outlook product group and the Supportability PM for Outlook. At least now both issues are directly in front of the product group.

    Ken Slovak MVP - Outlook

    • Marked as answer by Germán_MSO Thursday, August 21, 2014 5:45 PM
    Monday, August 18, 2014 2:00 PM
    Moderator
  • I asked to be updated on your case on this. Please update this thread with the results if possible, so others can be aware of what's going on.

    Ken Slovak MVP - Outlook

    Monday, August 18, 2014 8:14 PM
    Moderator
  • Thank you Ken.

    Eventually what we ended up doing was using Application_ItemLoad to call my folder initialization code.

    WHY NOT SelectionChange?  The problem was basically a decision about what to do if the Item got opened in an Inspector Window before my initialization happened (I've seen it take happen on the 1st try and I've seen it happen on the 10th).  If the user decides to do something with that Inspector object before I've added it to the appropriate calendar collection then I've lost a whole transaction.

    We're not all that thrilled with Application_ItemLoad either, but calling the initialization routine from there has been consistently allowing us to initialize shared calendars before anything else.

    I've played with some other scenarios as well, but I simply ran out of time on this project.  Everything else I'll be doing will have to go into a Hotfix.

    For now we have a workable solution.  Again, your notes have proved invaluable.  I'll be using that "Explorer[1]" instead of ActiveExplorer().  that's been another source of frustration for us.

    Thursday, August 21, 2014 5:44 PM
  • I'm glad I could help some at any rate, even if there's no actual answer at this point. I'm curious what I'll find out when I get the report on the case and its disposition when it's closed.

    Ken Slovak MVP - Outlook

    Thursday, August 21, 2014 5:52 PM
    Moderator