Outlook 的 OpenSharedItem 方法保存已签名的 .msg 文件的文件句柄

原始 KB 编号:   2633737

症状

在 Outlook 获得一些空闲时间之前,Microsoft Outlook 对象模型中的 方法不会释放 OpenSharedItem .msg 文件的文件句柄。

原因

如果基于 SMIME 的邮件对 .msg 文件进行签名或加密, (此行为) 。 这是 Outlook 内部管理基于 SMIME 的 .msg 文件的处理和文件句柄的方式的一个限制。 Outlook 对邮件上的签名执行后台验证,当 Outlook 获得一些空闲时间时,将文件句柄释放到 .msg 文件。 只有在 Outlook 完成所有必需的处理并释放文件句柄后,才能删除 .msg 文件。

您可以延迟删除文件的尝试,但无法直接确定 Outlook 何时释放文件锁定。

解决方案

没有计划更改此行为。

更多信息

Office Outlook 2007 和 Outlook 2010 提供了打开 OpenSharedItem iCalendar (.ics) 约会文件、vCard (.vcf) 文件和 Outlook 邮件 (.msg) 文件的方法。 此方法返回的对象种类取决于打开的共享项目类型。

在下面的示例中的 Microsoft Visual Basic for Applications (VBA) ,代码使用 方法打开 SignedMessage.msg OpenSharedItem 文件。 然后,代码在关闭邮件项目后尝试删除 .msg 文件。 如果 .msg 文件已签名或加密,则代码将导致 "权限被拒绝" 错误。 但是,如果打开未签名或非加密的 .msg 文件,则代码将如期删除 .msg 文件。

Public Sub TestOpenSharedItem()
    Dim oNamespace As Outlook.NameSpace
    Dim oSharedItem As Outlook.MailItem
    Dim oFolder As Outlook.Folder
    On Error GoTo ErrRoutine

    ' Get a reference to a NameSpace object.
    Set oNamespace = Application.GetNamespace("MAPI")'Open the Signed Message (.msg) file containing the shared item.
    Set oSharedItem = oNamespace.OpenSharedItem("C:\Temp\SignedMessage.msg")'Open the Regular Message (.msg) file containing the shared item.
    'Set oSharedItem = oNamespace.OpenSharedItem("C:\Temp\RegularMessage.msg")

    oSharedItem.Close (olDiscard)
    Set oSharedItem = Nothing

    'Add a reference to Microsoft Scripting Runtime
    Dim oFSO As New FileSystemObject

    ' Try to delete the Signed Message
    oFSO.DeleteFile ("C:\Temp\SignedMessage.msg")'Try to delete the Regular Message
    'oFSO.DeleteFile ("C:\Temp\RegularMessage.msg")

EndRoutine:
    On Error GoTo 0
    Set oSharedItem = Nothing
    Set oFSO = Nothing
    Set oNamespace = Nothing
Exit Sub
ErrRoutine:
Select Case Err.Number
    Case -2147024894 ' &H80070002
        ' Occurs if the specified file or URL could not
        ' be found, or the file or URL cannot be
        ' processed by the OpenSharedItem method.
        MsgBox Err.Description, _
        vbOKOnly, _
        Err.Number & " - " & Err.Source
    Case Else
        ' Any other error that may occur.
        MsgBox Err.Description, _
        vbOKOnly, _
        Err.Number & " - " & Err.Source
End Select
GoTo EndRoutine
End Sub