|
|
Pino Carafa
Posts: 103
Joined: 2016-09-28
|
Hello Andrei,
Ok this is just getting weird. Just out of curiosity I made some modifications to the test add-in. Instead of SETTING the Property in the PropertyAccessor in the Button1_Click event handler and then trying to RETRIEVE it in the _ItemSend, I tried retrieving it immediately after setting it. Now you'd expect that to be "stupidly" trivial and it should work as a matter of course, now, or at least I would:
Dim oPA As Outlook.PropertyAccessor = Nothing
Try
oPA = oItem.PropertyAccessor
Catch
End Try
If Not oPA Is Nothing Then
Try
oPA.SetProperty("http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/CaseReference}", oItem.Subject)
Catch ex As Exception
System.Diagnostics.Debug.WriteLine("Error setting Case Reference: " + ex.Message)
End Try
'Uncommenting this makes no difference
Try
Marshal.ReleaseComObject(oPA)
Catch
End Try
oPA = Nothing
End If
Try
oPA = oItem.PropertyAccessor
Catch
End Try
If Not oPA Is Nothing Then
Try
'Just to prove that IN HERE and AT THIS POINT the property is still normally accessible
MsgBox(oPA.GetProperty("http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/CaseReference}"))
Catch ex As Exception
System.Diagnostics.Debug.WriteLine("Error Getting Case Reference in Button1_Click: " + ex.Message)
End Try
Try
Marshal.ReleaseComObject(oPA)
Catch
End Try
oPA = Nothing
End If
and......
"Exception thrown: 'System.Runtime.InteropServices.COMException' in MyAddin136.dll
Error Getting Case Reference in Button1_Click: The property "http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/CaseReference}" is unknown or cannot be found."
What is going on.....???? |
|
Posted 17 Oct, 2019 02:47:49
|
|
Top
|
|
Pino Carafa
Posts: 103
Joined: 2016-09-28
|
by the way - once again this is using a Profile with "Cached Exchange Mode" switched OFF and connected to an online Exchange (Outlook 365) |
|
Posted 17 Oct, 2019 02:53:51
|
|
Top
|
|
Pino Carafa
Posts: 103
Joined: 2016-09-28
|
MORE craziness in NON-Cached Exchange Mode..... Start composing an email and hit Button1 ... and the error happens as stated in the previous comment.
Leave the message open. Don't send it. Walk away and make yourself a cup of coffee. Come back.
Hit Button1 again.
No error this time. The messagebox shows. And once the messagebox shows you can keep changing the message subject and you can keep hitting Button1. The messagebox will show every time.
I've timed this. In NON-cached exchange mode:
When you start composing the message and hit Button1 the error happens.
If you click Button1 again after 1 minute the error happens.
If you click Button1 again after 2 minutes the error happens.
If you click Button1 again after 3 minutes, no error. The messagebox shows.
If there was a 5, even 10 second "delay" in Non-cached exchange mode before Retrieving the Property succeeds, I could build that into the Add-in, check the ConnectionMode and leave the button disabled for that interval. But I can't do that for a delay of up to 3 minutes. At this stage it's starting to look like I'm going to have to restrict functionality unless the user switches to Cached Exchange Mode. I had rather hoped I could avoid that. |
|
Posted 17 Oct, 2019 03:03:07
|
|
Top
|
|
Andrei Smolin
Add-in Express team
Posts: 17493
Joined: 2006-05-11
|
Hello Pino,
Pino Carafa writes:
No error this time.
This is AutoSave! You need to save the item. Check MailItem.Saved to find whether it is saved or not.
I also suppose you'll see the very same issue if you use a PST.
Regards from Belarus (GMT+3),
Andrei Smolin
Add-in Express Team Leader |
|
Posted 17 Oct, 2019 04:16:39
|
|
Top
|
|
Pino Carafa
Posts: 103
Joined: 2016-09-28
|
You're correct (of course!) - after 3 minutes the item was autosaved and the problem no longer occurs. Which leaves me with a problem.
Here is the "workflow" of our Add-in:
1) The user starts composing an email. They click on a button to select a "case" from our "case management system". They select the case and we set the CaseReference Property in the PropertyAccessor
2) The user hits Send
At this point the software enters the _ItemSend procedure and we retrieve the CaseReference Property. This fails because the Mailitem is not Saved. As you suggest, I could first Save the mailitem. Now I no longer have a problem retrieving the CaseReference.... but now I have a NEW problem.
The mailitem is now Saved in Drafts.
In our REAL add-in, when I have the CaseReference I now go and get the email recipients. Each "case" in our "Case Management System" has people stored against it as so-called "Case Associates". I go and check each Recipient and make sure that the e-mail address is stored as an e-mail address for a "Case Associate" belonging to that "Case Reference". If there is an email address that doesn't belong in there, the user gets a warning and they can choose do click "OK" at which point the e.Cancel property is set to True and the email is not sent.
...
And then the User decided "to *bleep* with this" and X-es out of the email.
Now I have an item sitting in the Drafts folder.
Repeat this behaviour 1000 times.
Now I have 1000 items sitting in the Drafts folder.
Next thing I have a customer on the phone screaming at me that they have 1000 emails in their Drafts folder and they can't find the draft they *deliberately* created 2 months ago and "why are you creating all this junk in my mail folder?"
I have no way of knowing that the user didn't do what I just outlined, and at some point cancelled and instead of X-ing out of the email made a few more changes and then *deliberately* decided to save the email as a Draft. So I can't even set a property on the email and automatically remove drafts containing that property.
So many chickens. So many eggs.
This is why I originally asked for a way of knowing the user has clicked the Send button. Because if I can do THAT, instead of storing the CaseReference in the PropertyAccessor, I can store it in properties on the ADXOlForm without setting anything in the PropertyAccessor. I can then set the properties in the PropertyAccessor ONLY when the user hits "Send" and before processing enters the _ItemSend procedure. I could check the Recipients at that point, too, and do all the checking associated with those. And in fact I would not need the _ItemSend procedure at all anymore ...
But as you said.... there is no native way of doing that. You *did*, however, mention an API solution. As dirty as that is.... I may need to seriously think of implementing that. Would you have an example of such a thing? |
|
Posted 17 Oct, 2019 04:45:49
|
|
Top
|
|
Andrei Smolin
Add-in Express team
Posts: 17493
Joined: 2006-05-11
|
Pino Carafa writes:
Now I no longer have a problem retrieving the CaseReference.... but now I have a NEW problem.
The mailitem is now Saved in Drafts.
You can save mail items when in ItemSend event, after you validate the email (BTW, this can be a meeting request, remember?) and you need that property to handle it.
Pino Carafa writes:
This is why I originally asked for a way of knowing the user has clicked the Send button.
Use the fact that clicking Send ends with the ItemSend event (unless the send process is cancelled on an earlier stage). Save the required data to ADXOlForm. When in ItemSend, get MailItem.Inspector, scan ADXOlForms opened by that ADXOlFormsCollectionItem, compare the Inspector with ADXOlForm.InspectorObj to find *the* ADXOlForm and retrieve the data.
Regards from Belarus (GMT+3),
Andrei Smolin
Add-in Express Team Leader |
|
Posted 17 Oct, 2019 09:03:38
|
|
Top
|
|
Pino Carafa
Posts: 103
Joined: 2016-09-28
|
Hello Andrei,
Ok I think I got it! I added a CaseReference property to the ADXOlForm and I'm setting it instead of the PropertyAccessor, and then I change the ItemSend as follows. Can you just cast your eye over this to see if I am now doing it correctly, especially with regard to marshaling - for example I am Releasing an oInspector object here and I'm getting the Inspector through e.Item.GetInspector() - just want to make sure I'm leaving nothing hanging ... ?
The good news is - when I'm testing it it appears to be working fine!
Private Sub AdxOutlookAppEvents1_ItemSend(sender As Object, e As ADXOlItemSendEventArgs) Handles AdxOutlookAppEvents1.ItemSend
Dim sCaseReference As String = String.Empty
Dim oInspector As Outlook.Inspector = Nothing
Try
oInspector = TryCast(e.Item.GetInspector(), Outlook.Inspector)
Catch ex As Exception
End Try
If Not oInspector Is Nothing Then
Dim oADXForm As ADXOlForm1 = Nothing
Try
Dim nForms As Integer = Me.AdxOlFormsCollectionItem1.FormInstanceCount
Dim nForm As Integer = 0
While nForm < nForms
Try
oADXForm = TryCast(Me.AdxOlFormsCollectionItem1.FormInstances(nForm), ADXOlForm1)
If Not oADXForm Is Nothing Then
sCaseReference = oADXForm.CaseReference
End If
Catch ex As Exception
End Try
nForm = nForm + 1 '0-based index
End While
Catch
End Try
Try
Marshal.ReleaseComObject(oInspector)
Catch
End Try
oInspector = Nothing
End If
If sCaseReference = "CancelThis" Then
e.Cancel = True
Exit Sub
End If
Dim oPA As Outlook.PropertyAccessor = Nothing
Try
oPA = e.Item.PropertyAccessor
Catch
End Try
If Not oPA Is Nothing Then
Try
oPA.SetProperty("http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/CaseReference}", sCaseReference)
Catch ex As Exception
System.Diagnostics.Debug.WriteLine("ItemSend: Error setting Case Reference: " + ex.Message)
End Try
Try
Marshal.ReleaseComObject(oPA)
Catch
End Try
oPA = Nothing
End If
Try
e.Item.Save()
Catch ex As Exception
End Try
End Sub
|
|
Posted 18 Oct, 2019 06:11:27
|
|
Top
|
|
Pino Carafa
Posts: 103
Joined: 2016-09-28
|
Corrected:
Private Sub AdxOutlookAppEvents1_ItemSend(sender As Object, e As ADXOlItemSendEventArgs) Handles AdxOutlookAppEvents1.ItemSend
Dim sCaseReference As String = String.Empty
Dim oInspector As Outlook.Inspector = Nothing
Try
oInspector = TryCast(e.Item.GetInspector(), Outlook.Inspector)
Catch ex As Exception
End Try
If Not oInspector Is Nothing Then
Dim oADXForm As ADXOlForm1 = Nothing
Try
Dim nForms As Integer = Me.AdxOlFormsCollectionItem1.FormInstanceCount
Dim nForm As Integer = 0
While nForm < nForms
Try
oADXForm = TryCast(Me.AdxOlFormsCollectionItem1.FormInstances(nForm), ADXOlForm1)
If Not oADXForm Is Nothing Then
If oADXForm.InspectorObj Is oInspector Then
sCaseReference = oADXForm.CaseReference
Exit While
End If
End If
Catch ex As Exception
End Try
nForm = nForm + 1 '0-based index
End While
Catch
End Try
Try
Marshal.ReleaseComObject(oInspector)
Catch
End Try
oInspector = Nothing
End If
If sCaseReference = "CancelThis" Then
e.Cancel = True
Exit Sub
End If
Dim oPA As Outlook.PropertyAccessor = Nothing
Try
oPA = e.Item.PropertyAccessor
Catch
End Try
If Not oPA Is Nothing Then
Try
oPA.SetProperty("http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/CaseReference}", sCaseReference)
Catch ex As Exception
System.Diagnostics.Debug.WriteLine("ItemSend: Error setting Case Reference: " + ex.Message)
End Try
Try
Marshal.ReleaseComObject(oPA)
Catch
End Try
oPA = Nothing
End If
Try
e.Item.Save()
Catch ex As Exception
End Try
End Sub
|
|
Posted 18 Oct, 2019 06:13:28
|
|
Top
|
|
Andrei Smolin
Add-in Express team
Posts: 17493
Joined: 2006-05-11
|
Hello Pino,
It looks correct. I would add logging to all Catch blocks to get informed when something goes wrong.
Regards from Belarus (GMT+3),
Andrei Smolin
Add-in Express Team Leader |
|
Posted 18 Oct, 2019 06:21:14
|
|
Top
|
|
Pino Carafa
Posts: 103
Joined: 2016-09-28
|
Thanks Andrei.... I will do in our "real" Add-in :-)
I think at this stage, if you ever make it to Ireland I owe you a pint. |
|
Posted 18 Oct, 2019 06:27:03
|
|
Top
|
|
Posts 11 - 20 of 21
First | Prev. | 1 2 3 | Next | Last
|