Pregunta

Estamos desarrollando Outlook 2007 complemento. Para la prueba de categoría perspectivas de cambio de nombre que he añadido el siguiente bloque de código

 var session = Application.Session;
 var categories = session.Categories;
 var category1 = session.Categories[1];

 //catefory1.Name is "Group1" before executing line below
 category1.Name = "TEST!!!";

 Marshal.ReleaseComObject(category1);
 Marshal.ReleaseComObject(categories);
 Marshal.ReleaseComObject(session);

hasta el final de complemento método private void ThisAddIn_Startup(object sender, EventArgs e). Categoría se cambia el nombre, pero si Outlook está cerrado, se comentan las líneas anteriores, y las perspectivas se inicia de nuevo - el nombre de la categoría no es "TEST !!!" como yo esperaba. Es "Grupo 1" tal cual era antes de cambiar el nombre. ¿Es posible cambiar el nombre de la categoría perspectivas "para siempre" por el código? Microsoft.Office.Interop.Outlook.Category no tiene Save () o Update () o persistir () métodos.

P.S. Estamos desarrollando Outlook 2007 complemento utilizando Visual Studio 2008, .NET 3.5, C # 3. El problema se reproduce con Outlook 2007 SP1 y SP2. Otras versiones de Outlook no se ensayaron.

¿Fue útil?

Solución

He resuelto el problema (el problema en sí parece ser Outlook 2007 bug) usando un truco. Los siguientes enlaces me han ayudado a crear el hack (perdón, no es suficiente reputación para enviar más de 1 link):

El truco en sí mismo es mostrar a continuación:

using System;
using System.Text;
using System.Xml;
using System.IO;
using Microsoft.Office.Interop.Outlook;

namespace OutlookHack
{
    public static class OutlookCategoryHelper
    {
        private const string CategoryListStorageItemIdentifier = "IPM.Configuration.CategoryList";
        private const string CategoryListPropertySchemaName = @"http://schemas.microsoft.com/mapi/proptag/0x7C080102";
        private const string CategoriesXmlElementNamespace = "CategoryList.xsd";
        private const string XmlNamespaceAttribute = "xmlns";
        private const string CategoryElement = "category";
        private const string NameAttribute = "name";

        public static void RenameCategory(string oldName, string newName, Application outlookApplication)
        {
            MAPIFolder calendarFolder = outlookApplication.Session.GetDefaultFolder(
                OlDefaultFolders.olFolderCalendar);
            StorageItem categoryListStorageItem = calendarFolder.GetStorage(
                CategoryListStorageItemIdentifier, OlStorageIdentifierType.olIdentifyByMessageClass);

            if (categoryListStorageItem != null)
            {
                PropertyAccessor categoryListPropertyAccessor = categoryListStorageItem.PropertyAccessor;
                string schemaName = CategoryListPropertySchemaName;
                try
                {
                    // next statement raises Out of Memory error if property is too big
                    var xmlBytes = (byte[])categoryListPropertyAccessor.GetProperty(schemaName);

                    // the byte array has to be translated into a string and then the XML has to be parsed
                    var xmlReader = XmlReader.Create(new StringReader(Encoding.UTF8.GetString(xmlBytes)));

                    // xmlWriter will write new category list xml with renamed category
                    XmlWriterSettings settings = new XmlWriterSettings { Indent = true, IndentChars = ("\t") };
                    var stringWriter = new StringWriter();
                    var xmlWriter = XmlWriter.Create(stringWriter, settings);

                    xmlReader.Read(); // read xml declaration
                    xmlWriter.WriteNode(xmlReader, true);
                    xmlReader.Read(); // read categories
                    xmlWriter.WriteStartElement(xmlReader.Name, CategoriesXmlElementNamespace);
                    while (xmlReader.MoveToNextAttribute())
                    {
                        if (xmlReader.Name != XmlNamespaceAttribute) // skip namespace attr
                        {
                            xmlWriter.WriteAttributeString(xmlReader.Name, xmlReader.Value);
                        }
                    }
                    while (xmlReader.Read())
                    {
                        switch (xmlReader.NodeType)
                        {
                            case XmlNodeType.Element: // read category
                                xmlWriter.WriteStartElement(CategoryElement);
                                while (xmlReader.MoveToNextAttribute())
                                {
                                    if ((xmlReader.Name == NameAttribute) && (xmlReader.Value == oldName))
                                    {
                                        xmlWriter.WriteAttributeString(NameAttribute, newName);
                                    }
                                    else
                                    {
                                        xmlWriter.WriteAttributeString(xmlReader.Name, xmlReader.Value);
                                    }
                                }
                                xmlWriter.WriteEndElement();
                                break;
                            case XmlNodeType.EndElement: // categories ended
                                xmlWriter.WriteEndElement();
                                break;
                        }
                    }
                    xmlReader.Close();
                    xmlWriter.Close();

                    xmlBytes = Encoding.UTF8.GetBytes(stringWriter.ToString());
                    categoryListPropertyAccessor.SetProperty(schemaName, xmlBytes);
                    categoryListStorageItem.Save();
                }
                catch (OutOfMemoryException)
                {
                    // if error is "out of memory error" then the XML blob was too big
                }
            }
        }
    }
}

Este método ayudante debe ser llamado antes de la categoría de cambio de nombre, por ejemplo:.

 var session = Application.Session;
 var categories = session.Categories;
 var category1 = session.Categories[1];

 //catefory1.Name is "Group1" before executing line below
 OutlookCategoryHelper.RenameCategory(category1.Name, "TEST!!!", Application);
 category1.Name = "TEST!!!";

 Marshal.ReleaseComObject(category1);
 Marshal.ReleaseComObject(categories);
 Marshal.ReleaseComObject(session);

Otros consejos

Este es un error de Outlook introduce con Outlook 2007 SP2.

"Considere el siguiente escenario. Tiene una aplicación personalizada que se puede ejecutar para crear nuevas categorías en Outlook 2007. Ejecutar la aplicación para crear una nueva categoría en Outlook 2007. A continuación, si reinicia Outlook 2007, la categoría que ha creado se elimina de forma inesperada. Este problema se produce después de instalar la actualización o SP2 Februarycumulative ".

Hay una revisión disponible desde el 30 de junio de 2009: http://support.microsoft.com/default.aspx/kb/970944/ en

Saludos, Tim

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top