Outlook Crash when deleting recipient

Add-in Express™ Support Service
That's what is more important than anything else

Outlook Crash when deleting recipient
 
Alex Carter




Posts: 59
Joined: 2019-02-21
Hi,
I've got a snippet of code from that's fired when any of the To, Cc, Bcc properties are changed in an outlook item:

    Private Function HasExternalRecipients(ByVal recipients As Outlook.Recipients) As Boolean
        If recipients.Count Then
            For Each recipient As Outlook.Recipient In recipients
                Dim entry As Outlook.AddressEntry = recipient.AddressEntry
                If entry IsNot Nothing Then
                    Dim smtpAddress As String = ""

                    If (entry.Type = "EX") Then
                        smtpAddress = GetSMTPAddressViaOutlookObjectModel(entry)
                    Else
                        smtpAddress = entry.Address
                    End If

                    Marshal.ReleaseComObject(entry)
                    Marshal.ReleaseComObject(recipient)

                    If IsExternalRecipient(smtpAddress) = True Then
                        Return True
                    End If
                End If
            Next
        End If

        Return False
    End Function


Essentially it checks the recipients of the email to see whether they are external and returns a bool based on this.

The problem I am having at the moment is when opening an email via a mailto link, I then go to remove a recipient and it crashes the whole of outlook with the following item in event viewer:


Faulting application name: OUTLOOK.EXE, version: 16.0.11328.20468, time stamp: 0x5dbb4e2f
Faulting module name: RICHED20.DLL, version: 16.0.11328.20468, time stamp: 0x5dbb4d59
Exception code: 0xc0000005
Fault offset: 0x000a52a0
Faulting process ID: 0x6dfc
Faulting application start time: 0x01d74bcf0aefe66a
Faulting application path: C:Program Files (x86)Microsoft Office
ootOffice16OUTLOOK.EXE
Faulting module path: C:Program Files (x86)Microsoft Office
ootfsProgramFilesCommonX86Microsoft SharedOFFICE16RICHED20.DLL
Report ID: 36cad1e4-e0ef-4879-8110-4e3f88ad3fb1
Faulting package full name: 
Faulting package-relative application ID: 


Any help with this would be massively appreciated as i've been banging my head against the wall all morning!
Posted 18 May, 2021 06:17:55 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Hello Alex,

Check section Wait a little; see the PDF file in the folder {Add-in Express}\Docs on your development PC. Use that approach to create a small delay before deleting the recipient.


Andrei Smolin
Add-in Express Team Leader
Posted 18 May, 2021 06:22:35 Top
Alex Carter




Posts: 59
Joined: 2019-02-21
Morning Andrei,
Thanks for the quick reply, I am actually using the GUI to remove a recipient rather than doing it programmatically, is this still the correct approach to take?

If this is the case, am I just going to be listening for a receipient delete event and then using the OnSendMessage approach to delay the actual deletion from occurring?
Posted 19 May, 2021 02:53:15 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Hello Alex,

I might misunderstand your description. So, you open an email by clicking a mailto link and then delete a recipient right in the UI, correct?

Note that using a mailto link opens a modal inspector (this is a so-called Simple MAPI inspector). Not sure how this influences the issue though. I don't understand how that code fragment returning a Boolean is invoked and how you process that Boolean.

Also, I'd suggest that you use debug messages to find out when Outlook crashes. Use System.Diagnostics.Debug.Writeline.


Andrei Smolin
Add-in Express Team Leader
Posted 19 May, 2021 03:29:41 Top
Alex Carter




Posts: 59
Joined: 2019-02-21
Sorry Andrei, I probably haven't explained myself very well!

Yes I am using a mailto link to simulate opening an email from an external program. When I delete the recipient using the UI this is when outlook crashes.

The above snippet is invoked by using an OutlookItemEvents class, it uses the ProcessPropertyChange method to check whether the To,Cc,Bcc or Subject are changed and then updates my plugins UI accordingly. I wonder whether the application is in the middle of resolving the recipient and that's why it is crashing.

See the ProcessPropertyChange method below:

    Public Overrides Sub ProcessPropertyChange(ByVal Name As String)
        Dim props() As String = {"TO", "CC", "BCC", "SUBJECT"}
        If Name IsNot Nothing And Not String.IsNullOrEmpty(Name) Then
            Dim found As String = Array.Find(props, Function(x) (x.Equals(Name.ToUpper)))

            If found IsNot Nothing Then
                If TypeOf Me.ItemObj Is Outlook._MailItem Then
                    Dim mailItem As Object = Marshal.GetUniqueObjectForIUnknown(Marshal.GetIUnknownForObject(Me.ItemObj))
                    If Not mailItem.Sent Then
                        am.DoPropertyChange(Name, mailItem)
                    End If

                    If mailItem IsNot Nothing Then
                        Marshal.ReleaseComObject(mailItem)
                    End If
                End If
            End If
        End If
    End Sub


DoPropertyChange method below:


    Public Sub DoPropertyChange(ByVal PropName As String, Optional ByVal mail As Outlook.MailItem = Nothing)
        Dim form As EmailAutoFilingHost = CType(Me.AdxOlFormsCollectionItem1.GetCurrentForm(), EmailAutoFilingHost)
        Dim mailItem As Object = Marshal.GetUniqueObjectForIUnknown(Marshal.GetIUnknownForObject(mail))

        If mailItem IsNot Nothing And form IsNot Nothing Then
            Dim shouldFile As Boolean = WillBeFiled(mailItem, form.FileInternal, form.ShouldNotFile)
            form.DoBackgroundPaint(shouldFile, OfficeColorScheme)
        End If

        If PropName.ToUpper = "SUBJECT" Then
            Dim Subject As String = mailItem.Subject
            Dim Viewable = CasecodeViewableLookup(Subject)
            form.OcisViewable = Viewable
        End If

        If mailItem IsNot Nothing Then
            Marshal.ReleaseComObject(mailItem)
        End If
    End Sub


And finally the WillBeFiled method that calls the HasExtrernalRecipients method:

    Public Function WillBeFiled(ByVal mail As Outlook.MailItem, ByVal internalFile As Boolean, ByVal shouldNotFile As Boolean) As Boolean
        If mail IsNot Nothing And Not shouldNotFile Then
            Dim recipients As Outlook.Recipients = mail.Recipients
            If recipients.Count > 0 Then
                Dim hasExtRecipients As Boolean = HasExternalRecipients(recipients)
                Marshal.ReleaseComObject(recipients)

                If (hasExtRecipients Or internalFile) And StringHasCaseCodes(mail.Subject) Then
                    Return True
                End If
            End If
        End If

        Return False
    End Function


Apologies for all the code pastes, I know it may be a little difficult to see the wood for the trees! If you'd like I can try and get a demo project together? I will try and stick some debug messages in now to find the exact point of crash.
Posted 19 May, 2021 03:54:45 Top
Alex Carter




Posts: 59
Joined: 2019-02-21
Hi Andrei,
I've managed to re-create the issue in a demo project. See https://hgfltd-my.sharepoint.com/:u:/g/personal/acarter_hgf_com/EZQueVZ8-sNMvY6fnDyUWrIBwSwREWRLxtP_IP3uWUxGng?e=3h0DiI for download.

The problem looks to be occurring because I fire off the WillBeFiled method upon opening a message. If I remove the code in the ProcessOpen event of the OutlookItemEvents class, the email opens fine and allows recipient removals. Do you know if there's a way around this problem?
Posted 19 May, 2021 07:57:48 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Hello Alex,

Thank you for the project.

I've found these issues:

- WillBeFiled leaves the recipients variable unreleased if there's no recipients on the email being opened.
- HasExternalRecipients uses foreach (instead of for) and leaves unreleased 1) recipient, 2) entry.

Check if the above helps. If not, what scenario do you test?

Also, OutlookItemEvents is left connected to an email's events in this scenario: you open the email and close it. I suggest that you use ExplorerActivate to disconnect from events:

        If OutlookItemEvents.IsConnected Then
            OutlookItemEvents.RemoveConnection()
        End If



Andrei Smolin
Add-in Express Team Leader
Posted 20 May, 2021 02:07:26 Top
Alex Carter




Posts: 59
Joined: 2019-02-21
Good Afternoon Andrei,
As suggested above, i've made the changes. This doesn't seem to of fixed the crash issue though. Please see an updated link with the latest changes: https://hgfltd-my.sharepoint.com/:u:/g/personal/acarter_hgf_com/EairLMArcWVPstwKTumYHLgBsy0V6IwnGbElMP99Aog1Tg?e=msxCMS

I have actually emailed myself an with a mailto link in to click on for testing. The mailto link is as follows: mailto:alexcarter404@msn.com?cc=john.doe@msn.com&subject=Test%20P100006

If it helps I can forward this to you? Once I click this an email opens, when I remove the recipient it then crashes outlook.
Posted 20 May, 2021 08:00:41 Top
Andrei Smolin


Add-in Express team


Posts: 18829
Joined: 2006-05-11
Hello Alex,

Add debug messages to find out how the events work and how all your methods are invokes.

In my tests, the ProcessOpen call (= MailItem.Open event) isn't finished yet when three series of ProcessPropertyChange calls (=MailItem.PropertyChange event) occur: each series handles changes in To, CC, Bcc; I didn't study the actual changes, though. After that the ProcessOpen call completes. I've tried to use a Boolean flag to bypass handling these ProcessPropertyChange calls in this case. This may not be correct though: whether this is so or not depends on the actual changes these three series of ProcessPropertyChange calls perform. Anyway, this didn't help. I would suggest that you try a different approach: do not handle the ProcessOpen call at all.


Andrei Smolin
Add-in Express Team Leader
Posted 21 May, 2021 02:06:24 Top