VSTO:Outlook要求“保存更改?”3次......为什么?

时间:2016-06-24 07:48:38

标签: outlook vsto outlook-addin

以下是使用以下代码解决问题的简单步骤...

  1. 运行项目
  2. 创建新邮件
  3. 添加attacment
  4. 关闭邮件 - 我第一次要求保存更改 - 我选择否
  5. 关闭Outlook应用程序 - 我被问过两次保存更改...为什么?
  6. 这是我的示例代码......

    Imports System.Runtime.InteropServices
    
    Public Class ThisAddIn
    
        Private Shared _currentMailItem As Outlook.MailItem
    
    
        Private Sub ThisAddIn_Startup() Handles Me.Startup
            AddHandler Me.Application.ItemLoad, AddressOf LoadMail
        End Sub
    
    
        Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown
        End Sub
    
    
        Private Shared Sub LoadMail(Item As Object)
            If TypeOf Item Is Outlook.MailItem Then
                _currentMailItem = TryCast(Item, Outlook.MailItem)
                AddHandler _currentMailItem.Open, AddressOf OpenMail
            End If
        End Sub
    
    
        Private Shared Sub OpenMail(ByRef Cancel As Boolean)
            If String.IsNullOrEmpty(_currentMailItem.EntryID) Then
                AddHandler _currentMailItem.AttachmentAdd, AddressOf MailItem_AttachementAdded
                AddHandler _currentMailItem.Close, AddressOf MailItem_Close
            End If
        End Sub
    
    
        Private Shared Sub MailItem_AttachementAdded(e As Outlook.Attachment)
            For Each a As Outlook.Attachment In _currentMailItem.Attachments
            Next
        End Sub
    
    
        Private Shared Sub MailItem_Close(ByRef cancel As Boolean)
            If String.IsNullOrEmpty(_currentMailItem.EntryID) Then
                RemoveHandler _currentMailItem.AttachmentAdd, AddressOf MailItem_AttachementAdded
                RemoveHandler _currentMailItem.Close, AddressOf MailItem_Close
            End If
        End Sub
    
    End Class
    

    在关闭应用程序以保存更改时,你能看出为什么它会问我两次吗?

    此外,我不确定何时使用Marshal.ReleaseComObject() - 就像在我的For Each a As Outlook.Attachment In _currentMailItem.Attachments中一样......在循环中我是Marshal.ReleaseComObject(a)吗?

    由于

    ... UPDATE

    尽管我试图释放对象,但是这段代码仍然失败......

    Imports System.Runtime.InteropServices
    
    Public Class ThisAddIn
    
        Private _currentMailItem As Outlook.MailItem
    
    
        Private Sub ThisAddIn_Startup() Handles Me.Startup
            AddHandler Me.Application.ItemLoad, AddressOf LoadMail
        End Sub
    
    
        Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown
        End Sub
    
    
        Private Sub LoadMail(Item As Object)
            If TypeOf Item Is Outlook.MailItem Then
                _currentMailItem = TryCast(Item, Outlook.MailItem)
                AddHandler _currentMailItem.Open, AddressOf OpenMail
            End If
        End Sub
    
    
        Private Sub OpenMail(ByRef Cancel As Boolean)
            If String.IsNullOrEmpty(_currentMailItem.EntryID) Then
                AddHandler _currentMailItem.AttachmentAdd, AddressOf MailItem_AttachementAdded
                AddHandler _currentMailItem.Close, AddressOf MailItem_Close
            End If
        End Sub
    
    
        Private Sub MailItem_AttachementAdded(e As Outlook.Attachment)
            For i As Integer = 0 To _currentMailItem.Attachments.Count - 1
                Dim a As Outlook.Attachment = _currentMailItem.Attachments(i + 1)
                Marshal.ReleaseComObject(a)
                a = Nothing
            Next
        End Sub
    
    
        Private Sub MailItem_Close(ByRef cancel As Boolean)
            If String.IsNullOrEmpty(_currentMailItem.EntryID) Then
                RemoveHandler _currentMailItem.AttachmentAdd, AddressOf MailItem_AttachementAdded
                RemoveHandler _currentMailItem.Close, AddressOf MailItem_Close
            End If
            Marshal.ReleaseComObject(_currentMailItem)
            _currentMailItem = Nothing
        End Sub
    
    End Class
    

1 个答案:

答案 0 :(得分:0)

看起来您不会立即在代码中释放基础COM对象。保持对用户关闭的对象的引用会导致这样的对话。

完成使用后,使用System.Runtime.InteropServices.Marshal.ReleaseComObject释放Outlook对象。然后在Visual Basic中将变量设置为Nothing(C#中为null)以释放对该对象的引用。请在Systematically Releasing Objects文章中详细了解相关内容。

使用For循环代替ForEach循环。后者不允许立即释放所有底层COM对象。您可能会发现When to release COM objects in Office add-ins developed in .NET页面很有用。