Properties removed from PropertyAccessor sometimes "resurfacing"?

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

Properties removed from PropertyAccessor sometimes "resurfacing"?
Issue with Sent Items - Outlook 365 - Cached Exchange Mode? 
Andrei Smolin


Add-in Express team


Posts: 16670
Joined: 2006-05-11
You can send it to the support email address; find it in {Add-in Express installation folder}\readme.txt; please make sure your email contains a link to this topic.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 14 Oct, 2019 05:34:49 Top
Pino Carafa




Posts: 81
Joined: 2016-09-28
Hello Andrei,

Thanks for that - I sent same to the support email address.
Posted 14 Oct, 2019 06:39:44 Top
Andrei Smolin


Add-in Express team


Posts: 16670
Joined: 2006-05-11
Thank you. I see. Let's do the following changes:
- don't release oMailItem; this was a mistake; still this doesn't influence the issue
- check oMailItem.Saved and only if it returns true, save the item; otherwise, do not save.

Public Overrides Sub ItemAdd(ByVal Item As Object, ByVal SourceFolder As Object)
    System.Diagnostics.Debug.WriteLine("!!! ItemAdd")
    Dim oMailItem As Outlook.MailItem = CType(Item, Outlook.MailItem)
    Dim oProps As Outlook.UserProperties
    Dim oProp As Outlook.UserProperty
    oProps = oMailItem.UserProperties
    oProp = oProps.Find("MyTestProperty")
    If oProp Is Nothing Then
        System.Diagnostics.Debug.WriteLine("!!! ItemAdd. UP not found")
        oProp = oProps.Add("MyTestProperty", Outlook.OlUserPropertyType.olText)
    End If
    Marshal.ReleaseComObject(oProp)
    Marshal.ReleaseComObject(oProps)

    If Not oMailItem.Saved Then
        oMailItem.Save()
        System.Diagnostics.Debug.WriteLine("!!! ItemAdd. email saved.")
    End If
End Sub


BTW, do you check the debug messages? The change above is made to handle several ItemAdd events occurring for the same item.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 14 Oct, 2019 07:35:31 Top
Pino Carafa




Posts: 81
Joined: 2016-09-28
Hello Andrei,

I took your code and expanded on it a little bit:


        System.Diagnostics.Debug.WriteLine("!!! ItemAdd")
        Dim bAlreadyThere As Boolean = False
        Dim oMailItem As Outlook.MailItem = CType(Item, Outlook.MailItem)
        Dim oProps As Outlook.UserProperties
        Dim oProp As Outlook.UserProperty
        oProps = oMailItem.UserProperties
        oProp = oProps.Find("SentItemChecked")
        If oProp Is Nothing Then
            System.Diagnostics.Debug.WriteLine("!!! ItemAdd. UP not found")
            oProp = oProps.Add("SentItemChecked", Outlook.OlUserPropertyType.olText)
        Else
            bAlreadyThere = True
        End If
        Marshal.ReleaseComObject(oProp)
        Marshal.ReleaseComObject(oProps)

        If Not oMailItem.Saved Then
            If Not bAlreadyThere Then
                System.Diagnostics.Debug.WriteLine("!!! ItemAdd. New Property added and Mailitem not Saved so this should be all good.")
                oMailItem.Save()
                System.Diagnostics.Debug.WriteLine("!!! ItemAdd. email saved.")
            Else
                System.Diagnostics.Debug.WriteLine("!!! ItemAdd. Mail flagged as ""Not Saved"" even though we added no new properties!?!?!?")
            End If
        Else
            If Not bAlreadyThere Then
                System.Diagnostics.Debug.WriteLine("!!! ItemAdd. Mail flagged as already saved even though we added a new Property!?!?!?")
            Else
                System.Diagnostics.Debug.WriteLine("!!! ItemAdd. Property is already there and Mailitem is already Saved so this should be all good.")
            End If
        End If


I sent 4 messages. This is the Debug output:
!!! ItemAdd
!!! ItemAdd. UP not found
!!! ItemAdd. New Property added and Mailitem not Saved so this should be all good.
!!! ItemAdd. email saved.
!!! ItemAdd
!!! ItemAdd. UP not found
!!! ItemAdd. New Property added and Mailitem not Saved so this should be all good.
!!! ItemAdd. email saved.
!!! ItemAdd
!!! ItemAdd. UP not found
!!! ItemAdd. New Property added and Mailitem not Saved so this should be all good.
!!! ItemAdd. email saved.
!!! ItemAdd
!!! ItemAdd. UP not found
!!! ItemAdd. New Property added and Mailitem not Saved so this should be all good.
!!! ItemAdd. email saved.

But it still shows that line at the top of sent emails
Posted 14 Oct, 2019 08:57:57 Top
Pino Carafa




Posts: 81
Joined: 2016-09-28
Here's something else that's rather intriguing....

The message is shown at the top of the four emails I sent. Then I exit from Outlook and I start Outlook again. When I then open each e-mail, the message is no longer there.
Posted 14 Oct, 2019 09:01:38 Top
Pino Carafa




Posts: 81
Joined: 2016-09-28
And I am wrong. Immediately after starting Outlook the message wasn't displayed. But I checked again a few minutes later.... and it's back.
Posted 14 Oct, 2019 09:06:55 Top
Pino Carafa




Posts: 81
Joined: 2016-09-28
Oh my word... I'm so sorry Andrei .... Ignore my last couple of comments. I was mixing up my Inbox and my Sent Items folder. Can happen when you test software by sending emails to yourself *grin*

No... Restarting Outlook makes no difference. The "This is the most recent version" message is already there immediately after restarting outlook.

So please ignore the two comments I sent *after* the one in which I posted the Debug output. They were mistaken.
Posted 14 Oct, 2019 09:15:05 Top
Pino Carafa




Posts: 81
Joined: 2016-09-28
Ok Andrei.... "the plot thickens"

I switched to an Outlook Profile with Cached Exchange Mode switched *off*. This led to some very interesting new issues.

Referring back to my comment of Posted 14 Oct, 2019 07:35:31

The statement oMailItem.Save() would sometimes - ONLY sometimes - fail:
"An exception of type 'System.Runtime.InteropServices.COMException' occurred in MyAddin136.dll but was not handled in user code
Additional information: The function cannot be performed because the message has been changed."

While stopped at that statement I tried to run the following command from the Immediate Window
Marshal.ReleaseComObject(oMailItem)
This led to
"Managed Debugging Assistant 'RaceOnRCWCleanup' has detected a problem in 'C:\Program Files (x86)\Microsoft Office\Office15\OUTLOOK.EXE'.
Additional Information: An attempt has been made to free an RCW that is in use. The RCW is in use on the active thread or another thread. Attempting to free an in-use RCW can cause corruption or data loss."

When I try the statement a second time, no error is raised
Before executing Marshal.ReleaseComObject I had done
?oMailItem.EntryID which gave me an Entry ID for the message, so now I tried:

oMailItem = DirectCast(AddinModule.CurrentInstance().HostApplication, Outlook.Application).GetNamespace("MAPI").GetItemFromID(....

This gives me a new oMailItem object. I then go through the steps again, and I find that now the .Find succeeds. And oMailItem.Saved is *False*.

Interesting.
Posted 14 Oct, 2019 09:45:15 Top
Pino Carafa




Posts: 81
Joined: 2016-09-28
It seems like, when I switch to NON-Cached Exchange Mode, I run into something similar to this:

https://www.add-in-express.com/forum/read.php?TID=8961
Posted 14 Oct, 2019 10:00:30 Top
Pino Carafa




Posts: 81
Joined: 2016-09-28
Ok - I thought I saw a topic on this forum once where a similar issue was resolved by using a "wait a while" method or something like that?

So in light of that vague memory I added a bit of code to your sample, Andrei - in the ItemAdd I simply take note of the Entry ID (I took Option Strict off, by the way)


    Public Overrides Sub ItemAdd(ByVal Item As Object, ByVal SourceFolder As Object)

        Dim sEntryID As String = String.Empty
        Try
            sEntryID = Item.EntryID
        Catch

        End Try

        If Not String.IsNullOrEmpty(sEntryID) Then
            Dim oFoo As System.Windows.Forms.Timer
            oFoo = New Timer
            oFoo.Interval = 20000
            oFoo.Tag = sEntryID
            AddHandler oFoo.Tick, AddressOf FooTimer_Tick
            oFoo.Start()
        End If

        'Marshal.ReleaseComObject(oMailItem)
    End Sub


The code that was originally in the ItemAdd I moved to the Tick event handler


    Private Shared Sub FooTimer_Tick(sender As Object, e As EventArgs)

        Dim oTimer As Windows.Forms.Timer = Nothing
        Dim sEntryID As String

        oTimer = TryCast(sender, Windows.Forms.Timer)

        If Not oTimer Is Nothing Then
            oTimer.Stop()
            Try
                sEntryID = oTimer.Tag
            Catch

            End Try
            oTimer.Dispose()
            oTimer = Nothing
        End If

        If Not String.IsNullOrEmpty(sEntryID) Then
            Dim oMailitem As Object = Nothing

            Try
                oMailitem = DirectCast(AddinModule.CurrentInstance().HostApplication, Outlook.Application).GetNamespace("MAPI").GetItemFromID(sEntryID)
            Catch

            End Try
            If Not oMailitem Is Nothing Then
                System.Diagnostics.Debug.WriteLine("!!! ItemAdd")
                Dim bAlreadyThere As Boolean = False

                Dim oProps As Outlook.UserProperties
                Dim oProp As Outlook.UserProperty
                oProps = oMailitem.UserProperties
                oProp = oProps.Find("SentItemChecked")
                If oProp Is Nothing Then
                    System.Diagnostics.Debug.WriteLine("!!! ItemAdd. UP not found")
                    oProp = oProps.Add("SentItemChecked", Outlook.OlUserPropertyType.olText)
                Else
                    bAlreadyThere = True
                End If
                If Not oProp Is Nothing Then
                    oProp.Value = "2"
                End If
                Marshal.ReleaseComObject(oProp)
                Marshal.ReleaseComObject(oProps)

                If Not oMailitem.Saved Then
                    If Not bAlreadyThere Then
                        System.Diagnostics.Debug.WriteLine("!!! ItemAdd. New Property added and Mailitem not Saved so this should be all good.")
                        oMailitem.Save()
                        System.Diagnostics.Debug.WriteLine("!!! ItemAdd. email saved.")
                    Else
                        System.Diagnostics.Debug.WriteLine("!!! ItemAdd. Mail flagged as ""Not Saved"" even though we added no new properties!?!?!?")
                    End If
                Else
                    If Not bAlreadyThere Then
                        System.Diagnostics.Debug.WriteLine("!!! ItemAdd. Mail flagged as already saved even though we added a new Property!?!?!?")
                    Else
                        System.Diagnostics.Debug.WriteLine("!!! ItemAdd. Property is already there and Mailitem is already Saved so this should be all good.")
                    End If
                    'Dim oMailItemCopy As Outlook.MailItem = DirectCast(oMailItem.Copy, Outlook.MailItem)
                    'oMailItem.Delete()
                    'Marshal.ReleaseComObject(oMailItem)
                    'DeleteDeletedItem()
                    'oMailItem = oMailItemCopy
                End If

                'If Not oMailitem.Saved Then
                '    Try
                '        oMailitem.Save()
                '    Catch ex As Exception

                '    End Try
                'End If
                Try
                    Marshal.ReleaseComObject(oMailitem)
                Catch

                End Try
                oMailitem = Nothing
            End If
        End If
    End Sub


The good news is that everything seems to be working perfectly after that. The bad news is that our clients are so trigger happy that they are quite likely to be clicking on Sent Items before the 20 seconds are up. They also expect a dialog giving them various options to handle a Sent Item immediately after sending so if this is delayed as it is in this example, they will be screaming at us. So this would not be an acceptable solution. Not sure where that leaves me as a developer.
Posted 14 Oct, 2019 10:51:18 Top