我们正在开发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类别? Microsoft.Office.Interop.Outlook.Category没有Save()或Update()或Persist()方法。
P.S。我们正在使用Visual Studio 2008,.net 3.5,C#3开发Outlook 2007加载项。 Outlook 2007 SP1和SP2重现此问题。其他展望版本未经过测试。
答案 0 :(得分:1)
我已经使用黑客解决了问题(问题本身似乎是Outlook 2007的错误)。 以下链接帮助我创建了hack(oops,没有足够的声誉发布超过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);
答案 1 :(得分:0)
这是Outlook 2007 SP2中引入的Outlook错误。
“请考虑以下情形。您可以运行自定义应用程序以在Outlook 2007中创建新类别。 您运行该应用程序以在Outlook 2007中创建新类别。然后,如果您重新启动Outlook 2007,您创建的类别将被意外删除。安装Februarycumulative更新或SP2后会出现此问题。“
自2009年6月30日起,有一个修补程序: http://support.microsoft.com/default.aspx/kb/970944/en
此致 添