Можно ли программно переименовать категорию Outlook? - PullRequest
1 голос
/ 05 января 2010

Мы разрабатываем надстройку для 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 закрыт, вышеприведенные строки комментируются, и внешний вид запускается снова - имя категории не «ТЕСТ !!!» как я и предполагал. Это «Group1», как было до переименования. Можно ли переименовать категорию outlook "навсегда" кодом? Microsoft.Office.Interop.Outlook.Category не имеет методов Save () или Update () или Persist ().

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

Ответы [ 2 ]

1 голос
/ 06 января 2010

Я решил проблему (сама проблема, похоже, ошибка 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);
0 голосов
/ 02 марта 2010

Это ошибка Outlook, представленная в Outlook 2007 с пакетом обновления 2 (SP2).

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

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

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

...