2010-01-05 117 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

相關問題