2010-01-05 130 views
1

我们正在开发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一起再现。其他Outlook版本未经测试。

+0

我不知道这是相关的:http://blogs.officezealot.com/legault/archive/2009 /08/13/21577.aspx – Fionnuala 2010-01-05 17:16:18

+0

Remou,感谢您的评论,但不幸的是,提供的链接中描述的问题与以编程方式添加类别有关,并且仅与Outlook 2007 SP2相关。给定的解决方案并不能解决我们面临的“重命名问题”。 – Kluyg 2010-01-06 06:22:51

回答

1

我已经使用黑客解决了问题(问题本身似乎是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

http://www.outlookcode.com/codedetail.aspx?id=1583 - 几乎相同的代码,但在VBA + Redemption库(200 $用于商业用途)。使用兑换获取类别列表不会抛出OutOfMemoryException。 – Kluyg 2010-01-09 08:44:42

0

这是一个Outlook的错误与Outlook 2007 SP2介绍。

“请考虑以下情形:您可以运行自定义应用程序以在Outlook 2007中创建新类别。 运行应用程序以在Outlook 2007中创建新类别。然后,如果重新启动Outlook 2007,您创建的类别被意外删除。在安装Februarycumulative更新或SP2后,会发生此问题。“

有可用的修复程序自2009年6月30日: http://support.microsoft.com/default.aspx/kb/970944/en

问候, 添

+0

蒂姆,不幸的是,这是相关的,但不是相同的错误。类别重命名的Bug不是SP2,只是我在前面提到的原始问题中提到的。而且Remou在1个月前写了和你一样的内容(请参阅我原来的问题的评论)。创建类别的错误是不同的,它只有SP2,它有修补程序。此修复程序不能解决重命名的问题。 – Kluyg 2010-03-02 12:05:27

相关问题