none
Heavy call get_Folders RRS feed

  • Question

  • Hi,

    I am developing outlook plugin, following line code takes lot of time, which make outlook loading slow.

    CComQIPtr <Outlook::_Folders> spAccountSubFolder;
    hr = spAccountFolder->get_Folders(&spAccountSubFolder);

    please revert, if i am wrong somewhere.

    Your revert will help me a lot.

    Many thanks.

    Saturday, August 8, 2015 10:44 AM

Answers

  • Hey Many thanks, I am using outlook 2007.

    now 2 question arises:

    1) if i used outlook 2010 files for development?? does it will support for 2007?

    2) if i used 2007 files, how can i get inbox folders?

    your reply will help me a lot.


    1) It is generally,safest to develop using the oldest version. Interfaces and methods generally carry forward from older versions to newer versions but sometimes Microsoft may deprecate something or remove a feature comletely as versions change.  The move to the Ribbon in 2010 and 2013 away CommandBars is one example.

    2) The following example loops through the Stores, retrieves the Inbox folder for each and determines the folder's unread item count.  As usual, error checking has been omitted for the sake of simplicity.

    	CComPtr<Outlook::_Stores> pStores;
    	CComPtr<Outlook::_NameSpace> pNameSpace;
    	CComVariant vInbox(L"Inbox");
    	long	nStores = 0;
    
    	hr = m_pApp->get_Session( &pNameSpace );
    
    	hr = pNameSpace->get_Stores( &pStores );
    
    	hr = pStores->get_Count(&nStores);
    
    	for( long i = 1; i <= nStores; i++)
    	{
    		CComPtr<Outlook::_Store> pStore;
    		CComPtr<Outlook::MAPIFolder> pRootFolder, pInbox;
    		CComPtr<Outlook::_Folders> pFolders;
    		CComBSTR	bstrName;
    		long	nUnread = 0;
    		
    		hr = pStores->Item( CComVariant(i), &pStore);
    
    		hr = pStore->GetRootFolder( &pRootFolder );
    
    		hr = pRootFolder->get_Folders( &pFolders );
    
    		hr = pFolders->Item( vInbox, &pInbox );
    
    		hr = pInbox->get_Name( &bstrName);
    
    		hr = pInbox->get_( &nUnread );
    
    		ATLTRACE("Folder %S in Store %d had %d unread Items", bstrName, i, nUnread );
    
    	}
    
    

    Tuesday, August 11, 2015 11:23 AM

All replies

  • Can you give us some more information about what you are trying to do?  Are you trying to recurse through the entire folder tree?  We can't tell much from the one line of code shown.
    Saturday, August 8, 2015 11:29 AM
  • Hello,

    Do you have an Exchange account configured in Outlook? If so, did you enable the cached mode? 

    What folder exactly do you try to access?

    Saturday, August 8, 2015 2:14 PM
  • Thanks RLWA32, i am having more than 1 account configured, it takes time for one of my account.

    i need, Inbox folders, to catch item change event.

    how can i optimize it?

     
    Monday, August 10, 2015 9:37 AM
  • If you are just trying to get the Inbox folders then you can retrieve them directly by using the GetDefaultFolder method of the NameSpace object with a value of olFolderInbox.  If the profile has more than one store, you can use the GetDefaultFolder of each Store object to retrieve the Inbox for that Store. From the documentation about using the Store object --

    This method is similar to the GetDefaultFolder method of the NameSpace object. The difference is that this method gets the default folder on the delivery store that is associated with the account, whereas NameSpace.GetDefaultFolder returns the default folder on the default store for the current profile.


    • Edited by RLWA32 Monday, August 10, 2015 10:09 AM fix typo
    Monday, August 10, 2015 10:08 AM
  • very nice reply RLWA32... let me check with this.

    Thanks a lot.

    Monday, August 10, 2015 11:07 AM
  • Thanks RLWA32, i can get all stores, but how can i get default folder for each stores??

    Below is my code snippet.

    CComPtr<Outlook::_Stores> pStores;
    hr = pNameSpace->get_Stores(&pStores);

    if (FAILED(hr))
            {
    return false;
    }

    hr = pStores->get_Count(&lStoreCount);
    if(FAILED(hr))
            {
    return false;
    }

    for (int iIndex = 0; iIndex < lStoreCount; iIndex++)
    {
    CComPtr<Outlook::_Store> pStore;
    VARIANT vIndex;
    vIndex.iVal = iIndex;
    hr = pStores->Item(vIndex, &pStore);
    if(SUCCEEDED(hr))
    {
    CComQIPtr<Outlook::MAPIFolder> spIBox;

    //Here i am unable to get default folder.
    pStore->GetDe????
    }
    }

    how can i get default folder from store?

    you reply will help me a lot.

    Monday, August 10, 2015 11:55 AM
  • hr = pStore->GetDefaultFolder(olFolderInbox, &spIBox);

    The method takes a MAPIFolder ** as the second parameter so you don't have to use CComQIPtr for spIBox,  CComPtr will work just fine.

    • Edited by RLWA32 Monday, August 10, 2015 12:08 PM
    Monday, August 10, 2015 12:03 PM
  • hr = pStore->GetDefaultFolder(olFolderInbox, &spIBox);

    compilation error:

    error C2039: 'GetDefaultFolder' : is not a member of 'ATL::_NoAddRefReleaseOnCComPtr<T>'
    1>          with
    1>          [
    1>              T=Outlook::_Store
    1>          ]
    Monday, August 10, 2015 12:25 PM
  • I see that most of the questions are related to using C++, not Outlook. So, why do you need to use C++ for developing an Outlook add-in?
    Monday, August 10, 2015 12:39 PM
  • See https://msdn.microsoft.com/EN-US/library/office/ff869924.aspx

    What version of Outlook are you using?  How are you obtaining the interface definitions for the Outlook namespace?  I can't tell where the problem is located from the snippet that you posted. Following is a snippet that shows what the #import directive generates from the Outlook 2013 type library for the Store object on my system.

    struct __declspec(uuid("000630c7-0000-0000-c000-000000000046"))
    _Store : IDispatch
    {
        //
        // Raw methods provided by interface
        //
    
          virtual HRESULT __stdcall get_Application (
            /*[out,retval]*/ struct _Application * * Application ) = 0;
          virtual HRESULT __stdcall get_Class (
            /*[out,retval]*/ enum OlObjectClass * Class ) = 0;
          virtual HRESULT __stdcall get_Session (
            /*[out,retval]*/ struct _NameSpace * * Session ) = 0;
          virtual HRESULT __stdcall get_Parent (
            /*[out,retval]*/ IDispatch * * Parent ) = 0;
          virtual HRESULT __stdcall get_DisplayName (
            /*[out,retval]*/ BSTR * DisplayName ) = 0;
          virtual HRESULT __stdcall get_StoreID (
            /*[out,retval]*/ BSTR * StoreID ) = 0;
          virtual HRESULT __stdcall get_ExchangeStoreType (
            /*[out,retval]*/ enum OlExchangeStoreType * ExchangeStoreType ) = 0;
          virtual HRESULT __stdcall get_FilePath (
            /*[out,retval]*/ BSTR * FilePath ) = 0;
          virtual HRESULT __stdcall get_IsCachedExchange (
            /*[out,retval]*/ VARIANT_BOOL * IsCachedExchange ) = 0;
          virtual HRESULT __stdcall get_IsDataFileStore (
            /*[out,retval]*/ VARIANT_BOOL * IsDataFileStore ) = 0;
          virtual HRESULT __stdcall GetRootFolder (
            /*[out,retval]*/ struct MAPIFolder * * RootFolder ) = 0;
          virtual HRESULT __stdcall GetSearchFolders (
            /*[out,retval]*/ struct _Folders * * SearchFolders ) = 0;
          virtual HRESULT __stdcall get_IsOpen (
            /*[out,retval]*/ VARIANT_BOOL * IsOpen ) = 0;
          virtual HRESULT __stdcall get_MAPIOBJECT (
            /*[out,retval]*/ IUnknown * * MAPIOBJECT ) = 0;
          virtual HRESULT __stdcall GetRules (
            /*[out,retval]*/ struct _Rules * * Rules ) = 0;
          virtual HRESULT __stdcall get_PropertyAccessor (
            /*[out,retval]*/ struct _PropertyAccessor * * PropertyAccessor ) = 0;
          virtual HRESULT __stdcall GetSpecialFolder (
            /*[in]*/ enum OlSpecialFolders FolderType,
            /*[out,retval]*/ struct MAPIFolder * * Folder ) = 0;
          virtual HRESULT __stdcall get_IsInstantSearchEnabled (
            /*[out,retval]*/ VARIANT_BOOL * IsInstantSearchEnabled ) = 0;
          virtual HRESULT __stdcall RefreshQuotaDisplay ( ) = 0;
          virtual HRESULT __stdcall GetDefaultFolder (
            /*[in]*/ enum OlDefaultFolders FolderType,
            /*[out,retval]*/ struct MAPIFolder * * Folder ) = 0;
          virtual HRESULT __stdcall get_IsConversationEnabled (
            /*[out,retval]*/ VARIANT_BOOL * IsConversationEnabled ) = 0;
          virtual HRESULT __stdcall get_Categories (
            /*[out,retval]*/ struct _Categories * * Categories ) = 0;
    };
    
    
    You can see that the GetDefaultFolder method  is present.


    Monday, August 10, 2015 12:49 PM
  • i can not change design, as it is pre-developed.
    Monday, August 10, 2015 2:19 PM
  • i can not change design, as it is pre-developed.

    I don't understand this comment.
    Monday, August 10, 2015 2:20 PM
  • I am not sure, why raw methods providing only following methods on my machine:


    struct __declspec(uuid("000630c7-0000-0000-c000-000000000046"))
    _Store : IDispatch
    {
        //
        // Raw methods provided by interface
        //

          virtual HRESULT __stdcall get_Application (
            /*[out,retval]*/ struct _Application * * Application ) = 0;
          virtual HRESULT __stdcall get_Class (
            /*[out,retval]*/ enum OlObjectClass * Class ) = 0;
          virtual HRESULT __stdcall get_Session (
            /*[out,retval]*/ struct _NameSpace * * Session ) = 0;
          virtual HRESULT __stdcall get_Parent (
            /*[out,retval]*/ IDispatch * * Parent ) = 0;
          virtual HRESULT __stdcall get_DisplayName (
            /*[out,retval]*/ BSTR * DisplayName ) = 0;
          virtual HRESULT __stdcall get_StoreID (
            /*[out,retval]*/ BSTR * StoreID ) = 0;
          virtual HRESULT __stdcall get_ExchangeStoreType (
            /*[out,retval]*/ enum OlExchangeStoreType * ExchangeStoreType ) = 0;
          virtual HRESULT __stdcall get_FilePath (
            /*[out,retval]*/ BSTR * FilePath ) = 0;
          virtual HRESULT __stdcall get_IsCachedExchange (
            /*[out,retval]*/ VARIANT_BOOL * IsCachedExchange ) = 0;
          virtual HRESULT __stdcall get_IsDataFileStore (
            /*[out,retval]*/ VARIANT_BOOL * IsDataFileStore ) = 0;
          virtual HRESULT __stdcall GetRootFolder (
            /*[out,retval]*/ struct MAPIFolder * * RootFolder ) = 0;
          virtual HRESULT __stdcall GetSearchFolders (
            /*[out,retval]*/ struct _Folders * * SearchFolders ) = 0;
          virtual HRESULT __stdcall get_IsOpen (
            /*[out,retval]*/ VARIANT_BOOL * IsOpen ) = 0;
          virtual HRESULT __stdcall get_MAPIOBJECT (
            /*[out,retval]*/ IUnknown * * MAPIOBJECT ) = 0;
          virtual HRESULT __stdcall GetRules (
            /*[out,retval]*/ struct _Rules * * Rules ) = 0;
          virtual HRESULT __stdcall get_PropertyAccessor (
            /*[out,retval]*/ struct _PropertyAccessor * * PropertyAccessor ) = 0;
          virtual HRESULT __stdcall GetSpecialFolder (
            /*[in]*/ enum OlSpecialFolders FolderType,
            /*[out,retval]*/ struct MAPIFolder * * Folder ) = 0;
          virtual HRESULT __stdcall get_IsInstantSearchEnabled (
            /*[out,retval]*/ VARIANT_BOOL * IsInstantSearchEnabled ) = 0;
    };

    it dont have GetDefaultFolder

    Monday, August 10, 2015 2:21 PM
  • What version of Outlook are you using for development?  The GetDefaultFolder method of the Store object was not available in Outlook 2007.
    Monday, August 10, 2015 2:25 PM
  • Hey Many thanks, I am using outlook 2007.

    now 2 question arises:

    1) if i used outlook 2010 files for development?? does it will support for 2007?

    2) if i used 2007 files, how can i get inbox folders?

    your reply will help me a lot.


    Tuesday, August 11, 2015 5:50 AM
  • Hey Many thanks, I am using outlook 2007.

    now 2 question arises:

    1) if i used outlook 2010 files for development?? does it will support for 2007?

    2) if i used 2007 files, how can i get inbox folders?

    your reply will help me a lot.


    1) It is generally,safest to develop using the oldest version. Interfaces and methods generally carry forward from older versions to newer versions but sometimes Microsoft may deprecate something or remove a feature comletely as versions change.  The move to the Ribbon in 2010 and 2013 away CommandBars is one example.

    2) The following example loops through the Stores, retrieves the Inbox folder for each and determines the folder's unread item count.  As usual, error checking has been omitted for the sake of simplicity.

    	CComPtr<Outlook::_Stores> pStores;
    	CComPtr<Outlook::_NameSpace> pNameSpace;
    	CComVariant vInbox(L"Inbox");
    	long	nStores = 0;
    
    	hr = m_pApp->get_Session( &pNameSpace );
    
    	hr = pNameSpace->get_Stores( &pStores );
    
    	hr = pStores->get_Count(&nStores);
    
    	for( long i = 1; i <= nStores; i++)
    	{
    		CComPtr<Outlook::_Store> pStore;
    		CComPtr<Outlook::MAPIFolder> pRootFolder, pInbox;
    		CComPtr<Outlook::_Folders> pFolders;
    		CComBSTR	bstrName;
    		long	nUnread = 0;
    		
    		hr = pStores->Item( CComVariant(i), &pStore);
    
    		hr = pStore->GetRootFolder( &pRootFolder );
    
    		hr = pRootFolder->get_Folders( &pFolders );
    
    		hr = pFolders->Item( vInbox, &pInbox );
    
    		hr = pInbox->get_Name( &bstrName);
    
    		hr = pInbox->get_( &nUnread );
    
    		ATLTRACE("Folder %S in Store %d had %d unread Items", bstrName, i, nUnread );
    
    	}
    
    

    Tuesday, August 11, 2015 11:23 AM
  • Hi Thanks for your reply.

    but does following line of code will work for outlook version for other languages??

    CComVariant vInbox(L"Inbox");

    Tuesday, August 11, 2015 12:17 PM
  • CComVariant is a standard ATL class.

    What do you mean "other languages"?

    Tuesday, August 11, 2015 12:36 PM
  • L"Inbox"

    the default folder i seen for german language with name as Posteingang


    Tuesday, August 11, 2015 12:39 PM
  • I believe that you should use the same text that Outlook uses to display a folder name.  If you examine the name property of a Folder item using OutlookSpy or MFCMapi do you see "Posteingang" or "Inbox"?
    Tuesday, August 11, 2015 12:51 PM
  • i can see mails came in Posteingang folder
    Tuesday, August 11, 2015 12:55 PM
  • Then that's the text that you should use in the CComVariant.
    Tuesday, August 11, 2015 1:08 PM
  • Yeah thanks for your reply.

    But following line of code take more time in outlook 2010:

    hr = pRootFolder->get_Folders( &pFolders );

    I am have developed plugin using 2007 files, Does it make any difference? i dont think so because 2007 is back version.

    Thursday, August 13, 2015 1:57 PM
  • You could use different code to retrieve the inbox folders from the Stores collection if you check the version of Outlook on which the code is running.  On Outlook 2010 and higher use the code I provided to call GetDefaultFolder.  On Outlook 2007 use the other code that I provided.  It is up to you to make sure that you don't try to call the GetDefaultFolder method on Outlook 2007 because that would probably cause a crash.

    I believe that I've given you the best alternatives within Outlook Object model framework for the different versions of Outlook that are currently supported and that your question has been answered.

    Thursday, August 13, 2015 2:22 PM