Outlook 中自定义属性的更改

摘要

为保证自定义属性或字段的一致性使用,Microsoft Office Outlook 2003 Service Pack 2 (SP2) 及更高版本的 Outlook 限制了将自定义属性引入 Outlook 数据存储的某些方式。 例如,可以在 Outlook 个人文件夹 (.pst) 文件中以特定方式引入自定义属性。

简介

本文执行以下操作:

  • 提供自定义属性的概述。
  • 说明自定义属性的行为在 Outlook 2003 SP2 和更高版本的 Outlook 中是如何更改的。
  • 讨论了一些创建新属性的最佳实践以及一些我们不推荐的方法。

详细信息

关于自定义属性

Outlook 等电子邮件程序使用自定义属性向邮件添加更多信息。 通常,这些附加信息由电子邮件程序用于特定目的。 但是,还可以通过其他方式使用自定义属性。 例如,如果使用 Outlook 自定义表单,并且这些表单包含自定义字段,则可以将自定义属性添加到邮件或项目中。 自定义属性常用于添加更多信息以进行跟踪。 自定义属性还用于添加用户不必查看的数据。 自定义解决方案还可以向常规项添加自定义属性。 自定义解决方案以编程方式向邮件或项目添加自定义属性,而无需自定义表单。

在 Outlook 中,自定义属性可以保留为 .msg 文件格式和 .oft 文件格式。 此外,如果发件人使用“ 使用 Outlook 富文本格式发送 ”选项,则可以将自定义属性保留到通过 Internet 发送的电子邮件中。 此选项以传输中性封装格式 (TNEF) 封装消息的 MAPI 部分,然后在收到消息时对 TNEF 进行解码。

在以下情况下,发件人可以发送具有自定义属性的电子邮件:

  • 将发送一次性自定义表单。 在一次性表单中,表单嵌入邮件中。 该表单未在其他地方发布。 有关一次性窗体的详细信息,请参阅以下文章:
    保存包含“项目” (一次性表单) 的窗体
  • 此时将发送已发布的自定义表单。 在这种情况下,不会发送自定义表单,因为该表单未嵌入在邮件中。 但是,窗体上使用的任何自定义属性仍包含在消息中。

注意 引用自定义属性的方法有很多,具体取决于使用自定义属性的上下文。 在 Outlook 用户界面中,如 在字段选择器中,自定义属性称为用户定义的字段或自定义字段。 在 Outlook 对象库中,自定义属性可以称为用户属性,也可以在 UserProperties 集合之后称为用户定义的属性。 在 MAPI 中,自定义字段称为命名属性。 MAPI 提供了一种用于执行以下操作的工具:

  • 将名称分配给属性
  • 将名称映射到唯一标识符
  • 使映射永久化

有关命名属性如何在 MAPI 中实现的更多信息,请访问以下 MSDN 网站:

http://msdn2.microsoft.com/en-us/library/ms529055.aspx 注意 在 Exchange 环境中,本文中使用的术语“存储”是指整个邮箱存储 (数据库) 。 该术语不指单个用户的邮箱存储。 组织中可能有一个或多个 Exchange 邮箱数据库。

Outlook 中的行为更改

Outlook 中 MAPI 的实现已更改,以控制如何创建自定义属性。 为保证自定义属性的一致性使用,必须已在组织或 Outlook 客户端上使用自定义属性。 一旦使用或注册自定义属性,自定义属性就可以自由传输到其他 Outlook 客户端或运行 Exchange Server 的服务器。 还可以通过 Internet 发送自定义属性。

电子邮件通常在 Internet 上以 MIME 格式发送。 Outlook 收到 Internet 电子邮件时,该邮件将转换为 MAPI 表示形式。 以下是一些 Internet 电子邮件协议示例:

  • POP
  • IMAP
  • HTTP (Outlook.com)

默认情况下,Outlook 不再启用 Internet 邮件创建新的自定义属性。 仅为传入电子邮件保留默认邮件传递存储中已创建的属性。 此更改主要影响以封装的 TNEF (Winmail.dat) 发送的邮件,其中发件人使用了“ 使用 Outlook 富文本格式发送 ”选项。 但是,包含 X-message 标头属性的 Internet 消息也会受到影响。

注意:在 Exchange 组织中发送的包含自定义属性的邮件不受这些更改的影响。

自定义属性也可以保存在 .msg 文件和 .oft 文件中。 如果用户打开具有自定义属性的.msg文件,则在保存、转发邮件等时,这些自定义属性不会保存到默认存储中。 通常,.oft 文件用于备份 Outlook 自定义表单。 对于 .oft 文件,新行为适用于所有类型的物品。 不会打开自定义窗体。 相反,消息将以该特定项目类型的默认形式显示。

总之,这种设计更改可能导致发生两件事:

  • Outlook 将忽略不存在的自定义属性。 如果交付存储中不存在自定义属性,则不会创建该属性,并且其值将丢失。 如果自定义属性已存在于交付存储中,则其值将保留。 此更改适用于以下情况:

    • 具有 TNEF 及其嵌入消息的 Internet 电子邮件。
    • S/MIME 消息。
    • 将 .msg 文件拖放到 Outlook 项窗口中以将文件添加到另一个项时.msg文件。 将 .msg 文件拖放到 Outlook 主窗口中以将文件添加到文件夹时,或在将 Word 用作电子邮件编辑器时,此更改也适用于 Microsoft Word 窗口中的.msg文件。
    • .msg用户双击或右键单击打开的文件。
  • Outlook 将忽略一次性窗体定义。 如果一次性窗体指定自定义属性,而该自定义属性在交付存储中不存在,则不会呈现一次性窗体。 相反,用户将看到该特定项目类型的默认窗体。 此更改适用于包含封装在 TNEF 中的一次性表单定义的 Internet 电子邮件。 此更改也适用于用户双击或右键单击以打开的 .oft 文件。

创建新属性的最佳做法和其他方法

可通过多种方式设计和开发自定义解决方案。 其中一些方法被认为是最佳做法。 其他方法也可能有效,但出于一个或多个原因,我们不推荐使用这些方法。

最佳做法:以编程方式添加自定义字段

各种 API 可用于以编程方式向项添加自定义字段。 为此,请使用 Outlook 对象库 (“Outlook.Application”) 中的 UserProperties.Add 方法。 以下代码说明了此最佳做法。


Set myProp = myItem.UserProperties.Add("MyPropName", olText)

还可以使用 CDO 对象库 (“MAPI.会话“) 添加自定义字段。 有关更多信息,请访问以下 MSDN 网站:

http://msdn2.microsoft.com/en-us/library/ms527518.aspx 对于 C++ 开发人员,扩展 MAPI 可用于添加命名属性。 有关更多信息,请访问以下 MSDN 网站:

http://msdn2.microsoft.com/en-us/library/ms529684.aspx

最佳做法:使用包含自定义字段的已发布自定义表单

Outlook 很大程度上信任已发布的自定义表单。 但是,Outlook 不信任未发布的表单或一次性表单。 这包括 .oft 文件。 因此,在设计自定义窗体解决方案时,强烈建议发布自定义窗体。 应设计窗体,使窗体不会成为一次性窗体。 只要表单被发布,表单就不会受到 Outlook 中更改的影响。
 
将 .oft 文件发布到其他存储时,默认存储允许你在该存储中创建属性。 此外,创建具有自定义属性的自定义表单并将其发布到相应的表单库或文件夹时,将在受影响的存储中创建自定义属性。

最佳做法:以编程方式部署自定义表单

如果你正在开发一个其他人要使用的 Outlook 自定义表单,则有几种方法可供你使用。 使用的方法取决于多个因素。 这些因素包括表单的类型、谁将使用该表单、表单将在何处使用等。 通常情况下,如果自定义表单将由许多人使用,我们建议你在组织表单库中发布表单。 但是,如果不可能,则可能需要在共享文件夹或某些用户的个人表单库中发布表单。 可以使用 Outlook 对象库中的 CreateItemFromTemplate 方法以编程方式安装自定义表单。 使用 CreateItemFromTemplate 方法打开 .oft 文件,然后使用 PublishForm 方法发布窗体。 在这种情况下,.oft 文件不受自定义属性更改的影响。

可以将 Outlook 自定义表单另存为 .oft 文件。 这些窗体可以包含自定义字段、用户界面更改和自定义Microsoft Visual Basic Scripting Edition (VBScript) 代码向窗体添加功能。 尽管 Outlook 已包含阻止 .oft 文件中的 VBScript 代码运行的功能,但 Outlook 现在还限制使用 .oft 文件。 如果 .oft 文件包含自定义属性,而用户以前并未使用这些自定义属性,则自定义属性不在用户的默认存储中。 当用户双击该文件时,Outlook 不会呈现自定义窗体。 但是,要让 Outlook 打开存储为 .oft 文件的自定义表单,请依次单击“ 文件”、“新 建”和 “选择窗体”。 然后,可以将位置更改为 “文件系统中的用户模板”,然后单击“ 浏览 ”打开 .oft 文件。 窗体将打开,你可以将自定义属性保存到默认存储。

某些组织可能有充分的理由在整个组织中提供某些自定义属性。 如果使用多个存储,则可能需要确保可以将一组自定义属性添加到所有存储。 因此,Outlook 2003 SP2 及更高版本支持指定可以创建哪些自定义属性的客户端注册表项。 若要指定应启用哪些自定义属性,请在以下注册表项下定义自定义属性: HKEY_CURRENT_USER\Software\Microsoft\Office\<version>\Outlook\AllowedNamedProps\

注意 在此注册表项中, <version> 是您正在使用的 Outlook 版本的占位符。 对于 Outlook 2003,版本号为 11.0。 对于 Outlook 2007,版本号为 12.0。 更高版本的 Outlook 中,版本号将增加。

注册表项的总体注册表项结构为:

< GUID>

< 属性名称>

“kind” (dword)

“ID” (dword)
“Type” (dword) 注册表项结构中使用以下占位符:

  • < GUID>:包含指定属性集的 GUID。 在 Outlook 自定义表单上使用的 Outlook 自定义字段或属性都具有 GUID {00020329-0000-0000-C000-0000000000046}。 在 MAPI 中,GUID 称为 PS_PULIC_STRINGS。 但是,自定义 MAPI 程序可能具有自己的自定义属性 GUID。
  • < 属性名称>:指定属性的名称。 如果属性由字符串命名,<则“属性名称>”是属性的实际字符串名称。 如果属性由 ID 命名,则忽略此注册表项的值。 但是,您必须为该属性指定一个唯一的名称,以便该属性可以存储在注册表中。 如果 Kind 键设置为 1 或 <> 0,则注册表项名称将确定属性的名称。 如果 Kind 键不等于 1,则将忽略此注册表项名称。
  • “kind” (dword) :指定属性是由 ID 还是字符串命名。 如果值为 0,则属性将由 ID 命名。 名称是由 ID 指定的数值。 如果值为 1,则属性将由字符串命名。 此设置是不存在“种类”时的默认设置。
  • “ID” (dword) :包含由 ID 命名的属性的 ID 名称。 如果 Kind 键设置为 0,则需要此信息。 如果 Kind 键设置为 1,则忽略此信息。
  • “Type” (dword) :指定属性的类型。

此注册表项是必需的,但当前未使用该注册表项。 下表根据 MAPI 类型列出了此注册表项的可能值。

MAPI 类型 值 说明
PT_UNSPECIFIED 0 保留用于接口使用, (类型对调用方) 并不重要
PT_NULL 1 NULL 属性值
PT_I2 2 有符号的 16 位值
PT_LONG 3 有符号 32 位值
PT_R4 4 4 字节浮点
PT_DOUBLE 5 浮点双精度
PT_CURRENCY 6 带符号 64 位整数 (十进制 w/4 位十进制 pt) 右侧
PT_APPTIME 7 申请时间
PT_ERROR 10 32 位错误值
PT_BOOLEAN 11 16 位布尔值 (非零真)
PT_OBJECT 1.3 属性中的嵌入对象
PT_I8 20 8 字节有符号整数
PT_STRING8 30 以 Null 结尾的 8 位字符串
PT_UNICODE 31 以 null 结尾的 Unicode 字符串
PT_SYSTIME 64 FILETIME 自 1601 年 1 月 1 日起具有 100ns 周期数的 64 位整数
PT_CLSID 72 OLE GUID
PT_BINARY 258 未解释的 (计数字节数组)
PT_MV_UNSPECIFIED 4096
PT_MV_NULL 4097
PT_MV_I2 4098
PT_MV_LONG 4099
PT_MV_R4 4100
PT_MV_DOUBLE 4101
PT_MV_CURRENCY 4102
PT_MV_APPTIME 4103
PT_MV_ERROR 4106
PT_MV_BOOLEAN 4107
PT_MV_OBJECT 4109
PT_MV_I8 4116
PT_MV_STRING8 4126
PT_MV_UNICODE 4127
PT_MV_SYSTIME 4160
PT_MV_CLSID 4168
PT_MV_BINARY 4354

以下示例介绍如何设置 named-by-string 属性:

名称:“MyStringFieldName1”

类型:PT_LONG

[HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Outlook\AllowedNamedProps\{00020329-0000-0000-C000-000000000046}\MyStringFieldName1]“Type”=dword:00000003
下面是如何设置按 ID 命名属性的示例:

ID:0x0330

类型:PT_LONG

[HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Outlook\AllowedNamedProps\{00020329-0000-0000-C000-000000000046}\MyMAPIProp1]“kind”=dword:00000000 “ID”=dword:00000330 “type”=dword:00000003

对于这两个示例,注册表在注册表编辑器中类似于以下内容:

{00020329-0000-0000-C000-0000000000046}
 

MyStringFieldName1

类型 = 3
MyStringFieldName2

类型 = 3
{00020329-0000-0000-C000-0000000000046}

MyMAPIProp1

kind = 0
ID = 330

类型 = 3
MyMAPIProp2

kind = 0
ID = 331
类型 = 3

可以将三个注册表项部署到客户端计算机,以禁用对自定义属性的阻止,并将 Outlook 还原为以前的行为。 组策略支持这些注册表项。 以下注册表项可以还原 Outlook 2003 为以前的行为:

注意:以下注册表项不会还原 Outlook 2007 的先前行为。

  • AllowTNEFtoCreateProps (HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Outlook\Options\Mail] “AllowTNEFtoCreateProps”=dword:00000000) : 如果值为 0,则 TNEF/MIME 无法创建新的非 Outlook 自定义属性。 此值为默认值。 如果值为 1,则 TNEF/MIME 可以创建新的非 Outlook 自定义属性。

  • AllowMSGFilestoCreateProps:如果值为 0,则.msg文件和 .oft 文件无法创建新的非 Outlook 自定义属性。 此值为默认值。 如果值为 1,则.msg文件和 .oft 文件可以创建新的非 Outlook 自定义属性。

  • DisallowTNEFPreservation:为了便于迁移到此新行为,Outlook 在未创建自定义属性时保留原始 TNEF。 原始 TNEF 保存在所保存项目的二进制流中。 Outlook 使用以下属性标记保存流:
    PR_TNEF_UNPROCESSED_PROPS PROG_TAG (PT_BINARY,0x0e9C) 。 The HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Outlook\Options\Mail] “DisallowTNEFPreservation ”=dword:00000000
    注册表设置控制 Outlook 是否创建 PR_TNEF_UNPROCESSED_PROPS 属性。

    注意 将邮件作为附件嵌入到另一封邮件中时,将从邮件中删除 PR_TNEF_UNPROCESSED_PROPS 属性。 转发邮件或回复邮件时,也会删除 PR_TNEF_UNPROCESSED_PROPS 属性。