Вопрос

Мы разрабатываем надстройку Outlook 2007.Для тестирования переименования категорий Outlook я добавил следующий блок кода

 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);

до конца надстройки private void ThisAddIn_Startup(object sender, EventArgs e) способ.Категория переименовывается, но если Outlook закрыт, приведенные выше строки комментируются, и Outlook запускается снова - название категории не "TEST!!!", как я ожидал.Это "Group1", какой она была до переименования.Можно ли переименовать категорию outlook "навсегда" с помощью кода?Майкрософт.Офис.Взаимодействие.Outlook.Категория не имеет методов Save (), Update () или Persist().

P.S.Мы разрабатываем надстройку Outlook 2007 с использованием Visual Studio 2008, .net 3.5, C # 3.Проблема воспроизводится в Outlook 2007 с пакетом обновления 1 и пакетом обновления 2.Другие версии Outlook не тестировались.

Это было полезно?

Решение

Я решил проблему (сама проблема, похоже, связана с ошибкой Outlook 2007) с помощью взлома.Следующие ссылки помогли мне создать хак (упс, недостаточно репутации, чтобы опубликовать более 1 ссылки):

Сам взлом показан ниже:

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

Этот вспомогательный метод должен быть вызван перед переименованием категории, например:

 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);

Другие советы

Это ошибка Outlook, возникающая в Outlook 2007 SP2.

"Рассмотрим следующий сценарий.У вас есть пользовательское приложение, которое можно запустить для создания новых категорий в Outlook 2007.Вы запускаете приложение для создания новой категории в Outlook 2007.Затем, если вы перезапустите Outlook 2007, созданная вами категория неожиданно будет удалена.Эта проблема возникает после установки февральского накопительного обновления или SP2."

Исправление доступно с 30 июня 2009 года:http://support.microsoft.com/default.aspx/kb/970944/en

С уважением, Тим

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top