Outlook OpenSharedItem丢失用户属性

时间:2012-05-18 23:14:24

标签: c# outlook outlook-addin

我试图在用户属性中存储一些数据,然后将邮件写入.msg文件,然后(以后)重新加载.msg文件以读取用户属性。

问题是:重新加载文件后,我再也没有任何用户属性了。

我正在使用Outlook 2010 32位

以下是一段显示行为的代码:

Outlook.MailItem originalItem = ((MailItemWrapper)this.Item)._item;

var path = System.IO.Path.GetTempFileName() + ".msg";
var propName = "ActionId123456789";

// Set a user property "ActionId" with value "test"
var ps = originalItem.UserProperties;
var p = ps.Find(propName);
if (p == null)
    p = ps.Add(propName, Outlook.OlUserPropertyType.olText, Type.Missing);
p.Value = "test";

// Save to a temp file
originalItem.Save(); // --> I also tried without this line
originalItem.SaveAs(path);

// Chech the the property is correctly set
p = originalItem.UserProperties[propName];
if (p != null)
    Console.WriteLine(p.Value); // ---> Show 'test'

// Open the temp file
Outlook.MailItem newItem = AddinModule.CurrentInstance.OutlookApp.Session.OpenSharedItem(path) as Outlook.MailItem;

// Check that the property still exists
p = newItem.UserProperties[propName];
if (p != null)
    Console.WriteLine(p.Value); // ---> Not executed: p is NULL !

有人知道怎么做吗?

我没有使用OpenSharedItem,而是尝试使用Process.Start打开邮件,但在这种情况下,用户属性也为空...

顺便说一句,这段代码是一个测试样本,所以它并没有dispose正确地引用所有COM引用。

3 个答案:

答案 0 :(得分:2)

This forum post完全描述了您的问题 - 用户属性不会在MSG中保留。我也遇到了同样的行为changed by Microsoft back in 2007

作为一种解决方法,我只使用hidden Outlook folderMailItem存储为用户属性,而不是将其导出到磁盘并将其重新导入。

如果您无法使用此解决方法,则可能需要work with EWS to store it in a shared mailbox并以此方式访问用户属性,而不是将MSG导出到磁盘。

答案 1 :(得分:2)

好的,我找到了似乎有效的解决方案。为此,我需要使用第三方:Redemption

解决方案是使用自定义MAPI属性,而不是UserProperties集合。在下面的代码中,“this._item”引用了获取/设置属性所需的Outlook.MailItem对象

要做到这一点,你需要一个Guid,对于你的插件总是一样的

private const string customPropId = "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}";

设置属性

public void SetCustomProperty(string propertyName, string propertyValue)
{
    var sfe = new SafeMailItem() { Item = this._item };
    var propId = sfe.GetIDsFromNames(customPropId, propertyName);
    sfe.set_Fields(propId, propertyValue);
}

获取财产:

public string GetCustomProperty(string propertyName)
{
    var sfe = new SafeMailItem() { Item = this._item };
    var propId = sfe.GetIDsFromNames(customPropId, propertyName);

    var value = sfe.get_Fields(propId);
    if (value != null)
        return value.ToString();

    return null;
}

就是这样

警告:我还没有在实际情况下测试过此代码,它只能在与我的问题中发布的相同的测试用例中运行

答案 2 :(得分:0)

如果您使用的是C ++或Delphi,则可以使用OpenIMsgOnIStg方法直接打开MSG文件。

您还可以使用Redemption及其RDOSession。GetMessageFromMsgFile - 它会直接打开MSG文件,并允许您读取其所有用户属性。