1

我正在尝试在用户属性中存储一些数据,然后将邮件写入 .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,但在这种情况下,用户属性也是 null ...

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

4

3 回答 3

2

这篇论坛帖子准确地描述了您的问题 -用户属性没有保留在 MSG 中。我也经历了同样的行为,微软早在 2007 年就改变了这种行为。

作为一种解决方法,我只是使用一个隐藏的 Outlook 文件夹来存储我MailItem的用户属性,而不是将其导出到磁盘并重新导入。

如果您无法使用此解决方法,您可能需要使用 EWS 将其存储在共享邮箱中并以这种方式访问​​用户属性,而不是将 MSG 导出到磁盘。

于 2012-05-21T14:04:13.117 回答
2

好的,我找到了一个似乎可行的解决方案。为此,我需要使用第 3 方: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;
}

就是这样

警告:我尚未在实际情况下测试此代码,它仅适用于与我的问题中发布的测试用例相同的测试用例

于 2012-05-25T08:17:53.680 回答
0

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

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

于 2014-09-11T21:17:27.560 回答