سؤال

نحن نتطور Outlook 2007 الوظيفة الإضافية. لاختبار فئة Outlook Renaming لقد أضفت كتلة التعليمات البرمجية التالية

 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 مرة أخرى - اسم الفئة ليس "اختبار !!!" كما توقعت. إنها "Group1" كما هو الحال قبل إعادة تسمية. هل من الممكن إعادة تسمية فئة Outlook "إلى الأبد" بواسطة الرمز؟ Microsoft.Office.Interop.Outlook.category لا يوجد لديه حفظ () أو تحديث () أو أساليب ().

PS نحن نضع Outlook 2007 الوظيفة الإضافية باستخدام Visual Studio 2008، .NET 3.5، C # 3. المشكلة مستنسخة مع Outlook 2007 SP1 و SP2. لم يتم اختبار إصدارات 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، ففئة التي قمت بإنشائها تمت إزالتها بشكل غير متوقع. تحدث هذه المشكلة بعد تثبيت تحديث Febressative أو SP2. "

هناك إصلاح عاجل متاح منذ 30 يونيو 2009:http://support.microsoft.com/default.aspx/kb/970944/ar.

التحيات، تيم

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top