none
Ask about set custom icon for folders error? RRS feed

  • Question

  • Hi team,

    When we set folder's icon, sometimes the add-in throws excetption below:
    System.Runtime.InteropServices.COMException (0x80004005): Custom folder icon is not allowed for a folder not displayed in the Outlook user interface.
    at Microsoft.Office.Interop.Outlook.MAPIFolder.SetCustomIcon(StdPicture Picture)

    I have found a solution from the url below:

    http://social.msdn.microsoft.com/Forums/office/en-US/33efbbe9-3214-4ec7-8f17-ab2da8e53b3e/custom-icon-for-folders?forum=outlookdev

    When i  set the folder to current folder, then i could set the icon.However sometimes this solution does not work.

    Is there other solutions could fix this?


    Thursday, April 3, 2014 6:01 AM

All replies

  • Hello,

    What folder is used when get such exception? Outlook version? Did you try to install the latest Outlook updates and service packs?

    A custom icon cannot be added to the following groups of folders in Outlook:

    As you might have noticed there are no search folders on the list, which means you can set custom icons for Search folders. The same technique is used for solutions module folders.

    But sometimes you may get this error if the folder is not the current folder in the explorer window. As a workaround, you can temporarily set the ActiveExplorer.CurrentFolder property to the folder where you want to set the icon.

    Thursday, April 3, 2014 12:08 PM
  • Hi Eugene,

    Thanks for your reply.I am here waiting for you.My outlook version is SW_DVD5_Office_Professional_Plus_2010w_SP1_W32_English_CORE_MLF_X17-76748.ISO.
    Did this error a known issue or have been fixed by the recent service packs? I just use a callback to remove sub folders, then create new sub folders(using folder.Folders.Add(foldername)) and set a custom icon, so the exception occurs.
    Actually set the folder to current folder does not work, i can still have the error after setting.

    • Edited by 董建华 Thursday, April 3, 2014 1:42 PM
    Thursday, April 3, 2014 12:50 PM
  • It looks like this is an Outlook feature, not a bug ;)

    Could you please specify the build number of your Outlook?

    Please make sure that you release all underlying COM objects before doing anything with icons. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. Set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. Read more about this in the Systematically Releasing Objects article.


    Where are your problematic folders located? Could you please specify the folder path?
    Thursday, April 3, 2014 2:44 PM
  • The build number of outlook is SP1.

    I have not release any outlook object actually.Though i released the other temp folder object, the error still exist.Besides i found i can set folder icon after try many times.

    My folder path is below:




    • Edited by 董建华 Thursday, April 3, 2014 3:43 PM
    Thursday, April 3, 2014 3:02 PM
  • It looks like you forgot to answer my questions:

    Where are your problematic folders located? Could you please specify the folder path?

    Try installing Service Pack 2 for Microsoft Office 2010:

    Service Pack 2 for Microsoft Office 2010 (KB2687455) 32-Bit Edition

    Service Pack 2 for Microsoft Office 2010 (KB2687455) 64-Bit Edition

    Thursday, April 3, 2014 3:31 PM
  • Hi Eugene,

    I have uploaded a picture which contains the folder path.The folder path is like \\\\pst file\\custom folder.I will try to install service pack 2 for office 2010 tomorrow.

    Thanks very much for your suggestions.


    • Edited by 董建华 Thursday, April 3, 2014 3:49 PM
    Thursday, April 3, 2014 3:49 PM
  • I don't see any folder structure in Outlook.
    Thursday, April 3, 2014 3:55 PM
  • The folder path is like the picture below.(Though it is created by manually). 

    I will go to bed now, thanks eugene.




    • Edited by 董建华 Thursday, April 3, 2014 4:15 PM
    Thursday, April 3, 2014 4:04 PM
  • Try to install the SP2 and let me know the results.
    Thursday, April 3, 2014 4:15 PM
  • I have installed SP2, the result is still exist as before.
    • Edited by 董建华 Friday, April 4, 2014 8:20 AM
    Friday, April 4, 2014 2:18 AM
  • I have noticed that you use the MAPIFolder class. Did you try using the Folder class instead?

    Do you have any other add-ins installed for Outlook?

    Friday, April 4, 2014 6:46 PM
  • Hi Eugene,

    I have changed the code as you say, but it does not work.I can still easily reproduce the error.Besides, i found that we can set the custom icon through many times(1, 2, 500, 8700 times for setting a folder icon),  which takes a long and uncertain time.I wonder how outlook add-in developers to use this unstable API.I have uploaded the code and the screen shots, hoping these things would be helpful to resolve this issue.

    We have other add-ins installed for outlook, though we disabled them or uninstalled the error still exist.I can reproduce this error at any OutLook2010 environment.

    Thanks.

    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.Drawing;
    using System.Runtime.InteropServices;
    using Microsoft.Office.Interop.Outlook;

    namespace OutlookAddIn7
    {
        public partial class ThisAddIn
        {
            private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {
                this.Application.Session.Stores.StoreAdd += Stores_StoreAdd;
                string path = "c:\\my.pst";
                this.Application.Session.AddStore(path);
            }

            void Stores_StoreAdd(Outlook.Store Store)
            {
                MAPIFolder my = Store.GetRootFolder();
                if (my.Folders.Count > 0)
                {
                    my.Folders.Remove(2);
                }
                MAPIFolder favourites = my.Folders.Add("favourites");
                for (int i = 0; i < 10; i++)
                {
                    MAPIFolder temp = favourites.Folders.Add(i.ToString());
                    SetIcon(temp);
                }
            }

            private void SetIcon(MAPIFolder folder)
            {
                Icon icon = null;
                try
                {
                    Outlook.Folder outlookfolder = folder as Outlook.Folder;
                    icon = Properties.Resources._1396780671_5276;
                    stdole.StdPicture iconPictureDisp = PictureDispConverter.ToIPictureDisp(icon) as stdole.StdPicture;
                    outlookfolder.SetCustomIcon(iconPictureDisp);
                }
                catch (System.Exception ex)
                {

                }
                finally
                {
                    icon.Dispose();
                }

            }

            private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
            {
            }

            #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
        }

        public static class PictureDispConverter
        {
            //IPictureDisp GUID. 
            public static Guid iPictureDispGuid = typeof(stdole.IPictureDisp).GUID;

            // Converts an Icon into an IPictureDisp. 
            public static stdole.IPictureDisp ToIPictureDisp(Icon icon)
            {
                PICTDESC.Icon pictIcon = new PICTDESC.Icon(icon);
                return PictureDispConverter.OleCreatePictureIndirect(pictIcon, ref iPictureDispGuid, true);
            }

            // Converts an image into an IPictureDisp. 
            public static stdole.IPictureDisp ToIPictureDisp(Image image)
            {
                Bitmap bitmap = (image is Bitmap) ? (Bitmap)image : new Bitmap(image);
                PICTDESC.Bitmap pictBit = new PICTDESC.Bitmap(bitmap);
                return PictureDispConverter.OleCreatePictureIndirect(pictBit, ref iPictureDispGuid, true);
            }


            [DllImport("OleAut32.dll", EntryPoint = "OleCreatePictureIndirect", ExactSpelling = true,
            PreserveSig = false)]
            private static extern stdole.IPictureDisp OleCreatePictureIndirect(
            [MarshalAs(UnmanagedType.AsAny)] object picdesc, ref Guid iid, bool fOwn);

            private readonly static HandleCollector handleCollector =
            new HandleCollector("Icon handles", 1000);

            // WINFORMS COMMENT: 
            // PICTDESC is a union in native, so we'll just 
            // define different ones for the different types 
            // the "unused" fields are there to make it the right 
            // size, since the struct in native is as big as the biggest 
            // union. 
            private static class PICTDESC
            {
                //Picture Types 
                public const short PICTYPE_UNINITIALIZED = -1;
                public const short PICTYPE_NONE = 0;
                public const short PICTYPE_BITMAP = 1;
                public const short PICTYPE_METAFILE = 2;
                public const short PICTYPE_ICON = 3;
                public const short PICTYPE_ENHMETAFILE = 4;

                [StructLayout(LayoutKind.Sequential)]
                public class Icon
                {
                    internal int cbSizeOfStruct = Marshal.SizeOf(typeof(PICTDESC.Icon));
                    internal int picType = PICTDESC.PICTYPE_ICON;
                    internal IntPtr hicon = IntPtr.Zero;
                    internal int unused1 = 0;
                    internal int unused2 = 0;

                    internal Icon(System.Drawing.Icon icon)
                    {
                        this.hicon = icon.ToBitmap().GetHicon();
                    }
                }

                [StructLayout(LayoutKind.Sequential)]
                public class Bitmap
                {
                    internal int cbSizeOfStruct = Marshal.SizeOf(typeof(PICTDESC.Bitmap));
                    internal int picType = PICTDESC.PICTYPE_BITMAP;
                    internal IntPtr hbitmap = IntPtr.Zero;
                    internal IntPtr hpal = IntPtr.Zero;
                    internal int unused = 0;
                    internal Bitmap(System.Drawing.Bitmap bitmap)
                    {
                        this.hbitmap = bitmap.GetHbitmap();
                    }
                }
            }
        }
    }










    • Edited by 董建华 Sunday, April 6, 2014 6:35 AM
    Sunday, April 6, 2014 2:30 AM