هل من الممكن إعادة تسمية فئة Outlook برمجيا؟
-
18-09-2019 - |
سؤال
نحن نتطور 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):
- http: //blogs.officezealot.com/legault/archive/2009/08/13/21577.aspx.
- http://www.officekb.com/uwe/forum.aspx/outlook-prog-addins/3142/apply- الفئات-الأجزاء-users-uslook-2007.
- http: //help.wugnet.com/office/set-master-category-list-outlook-2007-ftopict1095935.html
- http: //forums.slipstick.com/showthread.php؟ T = 18189
- http: //msdn.microsoft.com/en-us/library/ee203806٪28exchg.80٪29.aspx.
الاختراق نفسه يعرض أدناه:
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.
التحيات، تيم