我试图在用户属性中存储一些数据,然后将邮件写入.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引用。
答案 0 :(得分:2)
This forum post完全描述了您的问题 - 用户属性不会在MSG中保留。我也遇到了同样的行为changed by Microsoft back in 2007。
作为一种解决方法,我只使用hidden Outlook folder将MailItem
存储为用户属性,而不是将其导出到磁盘并将其重新导入。
如果您无法使用此解决方法,则可能需要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文件,并允许您读取其所有用户属性。