Outlook behaviour when instanced from Windows Explorer "Send to mail recipient"

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

Outlook behaviour when instanced from Windows Explorer "Send to mail recipient"
 
Subscribe
AdrianP




Posts: 13
Joined: 2024-05-25
Hello,

I'm well aware of the fact that, when invoked from, say, MS Word "send as attachment" feature, Outlook doesn't fire up certain events.

However, when started from Windows Explorer "Send to mail recipient", you're in for even more fun :-) that is, no events seem to be sent to the addin. Well, at least not the ones I'm interested in, anyway :-) (inspector related ADXOutlookApp events, some attachment events from ADXOutlookItemEvents). Even the OutlookProfileName property is empty (which, in a way, is a good thing because we can associate that with this scenario :-) )

The addin loads and unloads correctly, the ribbon controls are created and their events work.

So, is there anything that I can do, or it's a lost cause? Is there any good read on this particular behaviour?

What I could do is to create a "Send" button intercept control (is it possible?) and move my attachment and message check logic on that, if there's no hope :-)

Regards,
Adrian
Posted 06 Jul, 2024 14:45:57 Top
AdrianP




Posts: 13
Joined: 2024-05-25
I tinkered with it a bit bore this weekend, and it seems that at least ADXOutlookAppEvents ItemSend works OK. So no need to intercept Send button anymore (did not seem to find a suitable ID, anyway, I searched in MS IDMso excels and tried SendDefault, but unfortunately doesn't work).

I'm using e.Item from ItemSend arguments as a Outlook.MailItem, and from that I can access attachment list and whatnot.
I check if OutlookProfileName is empty and I set a flag on AddinStartupComplete, so that, when ItemSend comes, I know if there's extra work to be done :-)

Regards,
Adrian
Posted 07 Jul, 2024 17:14:08 Top
Andrei Smolin


Add-in Express team


Posts: 18965
Joined: 2006-05-11
Hello Adrian,

The key words are Simple MAPI inspector; check https://www.add-in-express.com/forum/read.php?FID=5&TID=16454.

You should test two scenarios: 1) Outlook is started and 2) Outlook isn't started when a Simple MAPI inspector opens. In the second scenario your add-in gets loaded too late to be able to do anything.

The Send button is not on the Ribbon; it cannot be intercepted using the Ribbon API.

If your add-in is loaded, clicking the Send button generates the Send event on the MailItem object representing the email being sent. Note that the Send event occurs too early: it is possible that the user gets a dialog before the email is sent - say, in case of improperly typed recipients - and cancel the send. The correct way is to intercept ItemSend.

I don't think it is possible to do something about the Simple MAPI inspector.

Regards from Poland (GMT+2),

Andrei Smolin
Add-in Express Team Leader
Posted 08 Jul, 2024 08:42:07 Top
AdrianP




Posts: 13
Joined: 2024-05-25
Hello Andrei and thanks for your explanation!

I just fininshed checking both scenarios, and here's what I found:

1. When Simple MAPI inspector starts all by itself, OutlookProfileName is empty, ItemLoad and ItemSend events are working, no Inspector events seems to be called.

2. When Simple MAPI inspector starts along an existing normal Outlook instance, OutlookProfileName is set, the rest is same as above. One thing that I noticed, as long as Simple MAPI inspector window is opened, the main Outlook window is frozen. I disabled all COM addins, including mine, and it behaves identically, so I believe it's by design.

I can isolate the situation by checking for empty OutlookProfileName and the absence of any Explorer (or so I think :-) )
I wonder if it would be ok to connect my ADXOutlookItemEvents instance to the item param of ItemLoad? I will try it.

What also works is setting e.Cancel to true on ItemSend, so maybe I'll just be mean to my users and force them to use Outlook the usual way :-))

Thanks again for you time!

Regards,
Adrian
Posted 08 Jul, 2024 17:35:13 Top
Andrei Smolin


Add-in Express team


Posts: 18965
Joined: 2006-05-11
Hello Adrian,

Interesting observations!

AdrianP writes:
as long as Simple MAPI inspector window is opened, the main Outlook window is frozen


That's because the Simple MAPI inspector opens modally.

AdrianP writes:
by checking for empty OutlookProfileName


Here's the source code of that property:


        public string OutlookProfileName
        {
            get
            {
                if (HostType == ADXOfficeHostApp.ohaOutlook)
                {
                    if (this.HostMajorVersion >= 14)
                    {
                        if (this.HostApplication != null)
                        {
                            object _namespace =
                                this.HostApplication.GetType().InvokeMember("GetNamespace", BindingFlags.InvokeMethod, null, this.HostApplication, new object[] { "MAPI" });
                            if (_namespace != null)
                            {
                                return Convert.ToString(_namespace.GetType().InvokeMember("CurrentProfileName", BindingFlags.GetProperty, null, _namespace, null));
                            }
                        }
                    }
                    else
                    {
                        return ADXMapi.GetProfileName();
                    }
                }

                return null;
            }           
        }


That is, if all conditions are met, Add-in Express calls Application.GetNamespace("MAPI").CurrentProfileName. I'd like to understand what condition fails in that scenario so that the property returns null.

Using an item from the ItemLoad event should be okay but you must identify this scenario because ItemLoad occurs when any code read an item.

Regards from Poland (GMT+2),

Andrei Smolin
Add-in Express Team Leader
Posted 09 Jul, 2024 12:54:09 Top
AdrianP




Posts: 13
Joined: 2024-05-25
Hello Andrei,

Reading your reply, it suddenly hit me: I'm checking OutlookProfileName one time only, in the AddinStartupComplete event, so that could be the cause. And it is, because I just wired a MessageBox to one of the ribbon butttons of my addin, and sure enough, AddinStartupComplete isn't empty anymore :-)

So, when Simple MAPI inspector is all by itself, chcecking for Outlook profile in AddinStartupComplete is not a good idea if you actually need it for something :-)
Could it be that, when AddinStartupComplete is fired up, something from HostApplication is not ready yet?

As mentioned, this does not happen when Outlook is already started before Simple MAPI shows up.

Thanks for the code and your observations!

Regards,
Adrian
Posted 09 Jul, 2024 15:02:36 Top
Andrei Smolin


Add-in Express team


Posts: 18965
Joined: 2006-05-11
AdrianP writes:
Could it be that, when AddinStartupComplete is fired up, something from HostApplication is not ready yet?


For me, it works normally. Check if the output this sample property produces gives some hints.


        private void AddinModule_AddinStartupComplete(object sender, EventArgs e)
        {
            string result = string.Format(" profile name 0 - {0}", MyOutlookProfileName);
            Debug.WriteLine("!!! AddinModule_AddinStartupComplete " + result);

        }
        public string MyOutlookProfileName
        {
            get
            {
                Debug.WriteLine("!!! MyOutlookProfileName 0");
                if (HostType == ADXOfficeHostApp.ohaOutlook)
                {
                    Debug.WriteLine("!!! MyOutlookProfileName 1");
                    if (this.HostMajorVersion >= 14)
                    {
                        Debug.WriteLine("!!! MyOutlookProfileName 2");
                        if (this.HostApplication != null)
                        {
                            Debug.WriteLine("!!! MyOutlookProfileName 3");
                            object _namespace =
                                this.HostApplication.GetType().InvokeMember("GetNamespace", BindingFlags.InvokeMethod, null, this.HostApplication, new object[] { "MAPI" });
                            if (_namespace != null)
                            {
                                Debug.WriteLine("!!! MyOutlookProfileName 4");
                                return Convert.ToString(_namespace.GetType().InvokeMember("CurrentProfileName", BindingFlags.GetProperty, null, _namespace, null));
                            }
                            else
                                Debug.WriteLine("!!! MyOutlookProfileName 5");
                        }
                        else
                            Debug.WriteLine("!!! MyOutlookProfileName 6");
                    }
                    else
                    {
                        Debug.WriteLine("!!! MyOutlookProfileName 7");
                        return "TestTestTest";
                    }
                }
                else
                {
                    Debug.WriteLine("!!! MyOutlookProfileName 8");
                }
                Debug.WriteLine("!!! MyOutlookProfileName 9");
                return null;
            }
        }


Also, I feel like my previous description of ItemLoad isn't complete. I should have pointed out to this fact: if there is an add-in(s) scan items in some folder(s), every item read by such an add-in(s) would cause ItemLoad to occur. also, it would occur for an item shown in the Reading Pane.

Regards from Poland (GMT+2),

Andrei Smolin
Add-in Express Team Leader
Posted 10 Jul, 2024 11:21:41 Top
AdrianP




Posts: 13
Joined: 2024-05-25
Hello Andrei,

Andrei Smolin writes:
For me, it works normally


Did you start it by right-clicking a file in Windows Explorer and chosing "Send to->mail recipient" with Outlook closed?
As mentioned, it works ok when mail client is already opened.

Andrei Smolin writes:
Check if the output this sample property produces gives some hints


To be honest, I don't know how to debug the addin in the specific condition described above.
But, I created a new Adx COM addin project and scribbled the following in the AddinStartupComplete event:


        private void AddinModule_AddinStartupComplete(object sender, EventArgs e)
        {
            string logfilename = Path.Combine(Environment.GetFolderPath
                (Environment.SpecialFolder.MyDocuments), "AdxTestAddin.log");
            
            StreamWriter _mWriter = new StreamWriter(logfilename, false);
            
            _mWriter?.WriteLine($"Host details: {this.HostName} {this.HostMajorVersion} version {this.HostVersion}");

            _mWriter?.WriteLine("In step 0 - BEGIN");

            if (HostType == ADXOfficeHostApp.ohaOutlook)
            {
                _mWriter?.WriteLine("In step 1 - HostType == ADXOfficeHostApp.ohaOutlook");
                if (this.HostMajorVersion >= 14)
                {
                    _mWriter?.WriteLine("In step 2 - HostMajorVersion >= 14");
                    if (this.HostApplication != null)
                    {
                        _mWriter?.WriteLine("In step 3 - HostApplication != null");

                        object _namespace = this.HostApplication.GetType().InvokeMember
                            ("GetNamespace", BindingFlags.InvokeMethod, null, 
                                this.HostApplication, new object[] { "MAPI" });
                        
                        if (_namespace != null)
                        {
                            _mWriter?.WriteLine("In step 4 - _namespace != null");

                            string s = Convert.ToString
                                (_namespace.GetType().InvokeMember("CurrentProfileName", 
                                    BindingFlags.GetProperty, null, _namespace, null));

                            _mWriter?.WriteLine($"Profile name is: {s}");
                            goto __end;
                        }
                        else
                            _mWriter?.WriteLine("In step 5 - _namespace == null");
                    }
                    else
                        _mWriter?.WriteLine("In step 6 - HostApplication == null");
                }
                else
                {
                    _mWriter?.WriteLine("In step 7 - HostMajorVersion < 14");
                    _mWriter?.WriteLine("TestTestTest");
                }
            }
            else
            {
                _mWriter?.WriteLine("In step 8 - HostType != ADXOfficeHostApp.ohaOutlook");
            }

            _mWriter?.WriteLine("In step 9 - END");

        __end:
            _mWriter?.Flush();
            _mWriter?.Close();
        }


Do you think it's ok?
When run under "Send to" scenarion, with no Outlook opened, I get

Host details: Outlook 16 version 16.0.0.17726
In step 0 - BEGIN
In step 1 - HostType == ADXOfficeHostApp.ohaOutlook
In step 2 - HostMajorVersion >= 14
In step 3 - HostApplication != null
In step 4 - _namespace != null
Profile name is:


When Outlook is already up, I get

Host details: Outlook 16 version 16.0.0.17726
In step 0 - BEGIN
In step 1 - HostType == ADXOfficeHostApp.ohaOutlook
In step 2 - HostMajorVersion >= 14
In step 3 - HostApplication != null
In step 4 - _namespace != null
Profile name is: outlook.com


The way I see it, the problem lies within


Convert.ToString(_namespace.GetType().InvokeMember("CurrentProfileName", BindingFlags.GetProperty, null, _namespace, null));


...or maybe

object _namespace = this.HostApplication.GetType().InvokeMember("GetNamespace", BindingFlags.InvokeMethod, null, this.HostApplication, new object[] { "MAPI" });


...which most likely has little to do with ADX :-)

What do you think?

Regards,
Adrian
Posted 10 Jul, 2024 16:01:25 Top
Andrei Smolin


Add-in Express team


Posts: 18965
Joined: 2006-05-11
Hello Adrian,

In the current Outlook version - which is Version 2406 (Build 17726.20126 Click-to-Run) delivered through the Current Channel - the behavior is different from previous Outlook versions.

If Outlook isn't started and I right-click a file and choose Send To | Mail Recipient, this starts Outlook, it loads my add-in and shows a modal Outlook Inspector window showing an email where the file is attached. In previous versions, my add-in wasn't loaded at this stage.

In the code of the add-in I get OutlookProfileName in two events: AddinStartupComplete and OnRibbonBeforeLoad. The results are different: in AddinStartupComplete I get a string consisting of a number of space symbols; in OnRibbonBeforeLoad, the string contains the name of the current profile.

As you can see, OutlookProfileName calls Namespace.CurrentProfileName to get the result. Obviously, the issue is produced by that property which isn't properly initialized in this scenario. As this is a bug - at least it looks so - this behavior can change sooner or later.

Regards from Poland (GMT+2),

Andrei Smolin
Add-in Express Team Leader
Posted 11 Jul, 2024 10:45:46 Top
AdrianP




Posts: 13
Joined: 2024-05-25
Hi Andrei,

OnRibbonBeforeLoad seems like a good idea for ckecking OutlookProfileName. I just checked and it works (Outlook 2016 and 2019)
Thanks for all!

Regards,
Adrian
Posted 11 Jul, 2024 15:03:30 Top