com wrapper

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

com wrapper
 
mathieu ladroue




Posts: 4
Joined: 2016-10-21
Hi,

I'm having really hard time trying to get back my object from the com addins of outlook
i need to get the managed object of my addin for unit test but i'm stuck because of this message :
This operation failed because the QueryInterface call on the COM component for the interface with IID '{DA40263A-1CA2-4CED-8517-B5463A9EC4CC}' failed due to the following error: No such interface supported



            Ol._Application outlookApplication = null;
            // Check whether there is an Outlook process running.
            if (Process.GetProcessesByName("OUTLOOK").Count() > 0)
            {
                // If so, use the GetActiveObject method to obtain the process and cast it to an Application object.
                outlookApplication = Marshal.GetActiveObject("Outlook.Application") as Ol._Application;
            }
            else
            {
                // If not, create a new instance of Outlook and log on to the default profile.
                outlookApplication = new Ol.Application();
                Ol.NameSpace nameSpace = outlookApplication.GetNamespace("MAPI");
                nameSpace.Logon("", "", Missing.Value, Missing.Value);
                nameSpace = null;
            }
            object progId = "Myaddin";
            var comAddin = outlookApplication.COMAddIns.Item(ref progId);
            var comObject = comAddin.Object;

            // always return null :-(
            AddinModule addinModule = AddinExpress.MSO.ADXAddinModule.CurrentInstance as AddinModule;

            /* only to test and try to get 2 important object
            public ILoader getILoader_forTest()
            {
                return this;
            }
            public IMainModule getIMainModule_forTest()
            {
                return this.mainModule;
            }
            */
            var comAddinType = comObject.GetType(); 
            var ComILoader = comAddinType.InvokeMember("getILoader_forTest", BindingFlags.InvokeMethod, null, comObject, new object[] { });
            var ComIMainModule = comAddinType.InvokeMember("getIMainModule_forTest", BindingFlags.InvokeMethod, null, comObject, new object[] { });

            ILoader loader = (ILoader)ComILoader;
            IMainModule main = (IMainModule)ComIMainModule;

also the interface

    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIDispatch), Guid("DA40263A-1CA2-4CED-8517-B5463A9EC4CC")]
    public interface IMainModule : IDisposable


i also tried with this function

        public int getInt_forTest()
        {
            return DateTime.Now.Second;
        }

it work perfectly so i know the way is good it's just that i don't know how to cast the comobject to the original managed object.

thank you very much
Posted 21 Oct, 2016 12:15:26 Top
Andrei Smolin


Add-in Express team


Posts: 18844
Joined: 2006-05-11
Hello Mathieu,

mathieu ladroue writes:
var comAddin = outlookApplication.COMAddIns.Item(ref progId);
var comObject = comAddin.Object;


Starting from this moment, you use late binding on the comObject variable to access public methods/properties that the add-in module provides.

Writing test methods to test the functionality that an add-in module provides doesn't seem really correct. The point is: in addition to the these methods the test area will also include programs (and their settings) that participate in Outlook starting, showing its UI and providing its functionality (including the Outlook object model). To test the business logic of your add-in, isolate it in a class library and test the class library outside of Outlook. You will be completely sure that a given method failed due to a bug in its code, not as a result of non-reproducible factors such as settings of a third-party program or add-in which was started/loaded (or *not* started/loaded). Or, you may encounter an Outlook bug that only occurs in certain environment. Or...


Andrei Smolin
Add-in Express Team Leader
Posted 22 Oct, 2016 08:44:22 Top
mathieu ladroue




Posts: 4
Joined: 2016-10-21
Hi,
the goal is not to unit test the addinexpress but my own module.

To correctly test my addin i need it to run in outlook so even my unit test need to run with outlook.

So i need to access the original managed object. Right now i get this object but as a comobject i just need to cast the addinmodule object and my object to managed

thanks
regards
Posted 24 Oct, 2016 10:41:14 Top
Andrei Smolin


Add-in Express team


Posts: 18844
Joined: 2006-05-11
Hello Mathieu,

I understand your approach really well: a while back I thought this is a correct approach. Now I know this isn't so. I suppose you'll see my point when you find your unit tests failing due to causes external to your add-in.

mathieu ladroue writes:
Right now i get this object but as a comobject i just need to cast the addinmodule object and my object to managed


This is impossible. Instead, you need to use late binding as explained in my previous post.


Andrei Smolin
Add-in Express Team Leader
Posted 24 Oct, 2016 10:52:18 Top
mathieu ladroue




Posts: 4
Joined: 2016-10-21
I'll be glad to use late binding... but how ?
Posted 24 Oct, 2016 10:56:28 Top
Andrei Smolin


Add-in Express team


Posts: 18844
Joined: 2006-05-11
Posted 24 Oct, 2016 11:05:42 Top
mathieu ladroue




Posts: 4
Joined: 2016-10-21
Thanks for the links but it doesn't give me more information about a way to access a managed object

invokemember return me a comobject which is not easy to check if it's as expected
i want to be able to get a custom class for my unit test
Posted 24 Oct, 2016 11:31:50 Top
Andrei Smolin


Add-in Express team


Posts: 18844
Joined: 2006-05-11
Hi Mathieu,

InvokeMember is a way to invoke a property/member on the specified object (on the add-in module in your case). You can't retrieve the managed object; you can only access its members using InvokeMember.


Andrei Smolin
Add-in Express Team Leader
Posted 25 Oct, 2016 04:56:27 Top