c# - Calling a method on Object exposed by Word Add-in throws RemotingException -


i writing (shared) word add-in in c# , want communicate exposing object through object property of comaddin class.

because want code executed on ui thread derive add-in , exposed object standardolemarshalobject class. should take care of marshaling described here , here.

but doing different behavior when compile against .net 2.0 or.net 4.0. when compiling against .net 4.0 exposed object of type __comobject , lets cast publicly comvisible defined interface. in turn lets me call methods on object , works perfectly.

when compiling against .net 2.0 exposed object of type __transparentproxy. can cast interface when try call method wil throw system.runtime.remoting.remotingexception message:

this remoting proxy has no channel sink means either server has no registered server channels listening, or application has no suitable client channel talk server.

when not inherit standardolemarshalobject seem work code execute on arbitrary rpc thread not i'm looking for.

i have searched internet not able find solution or reason why not working in .net 2.0. did find similar problems, seem address excel.

at moment i'm not in position of switching .net 4.0 i'm hoping can solved .net 2.0.

does have solution problem, or @ least explanation?

here test code :

[comvisible(true)][guid("...")] [interfacetype(cominterfacetype.interfaceisdual)] public interface iservice {    void hello(); }  [comvisible(true)][guid("...")] [classinterface(classinterfacetype.none)] public class myservice : standardolemarshalobject, iservice {    public void hello()    {       messagebox.show("hello");    } }  public class myaddin : standardolemarshalobject, idtextensibility2 {   public void onconnection(object application, ext_connectmode connectmode,       object addininst, ref array custom)   {         _service = new myservice();         ((comaddin)addininst).object = _service;   }    //rest of idtextensibility2 implementation }  public class test {    public static void main(string[] args)    {       application app = new application();       app.visible = true;        comaddin addin = app.comaddins.item("myaddin");       iservice service = addin.object iservice;       if (service != null)          service.hello(); // <-- remotingexception happening here    } } 

so found workaround problem acceptable , works .net2.0. don't find elegant have been, works. i'm using little hidden "proxy" window lets me marshal calls made out-of-proc client ui thread of word. i'm not planning have many methods exposed through com lines of code won't problem. i've added important pieces of code below.

    /// <summary>     /// hiddenform can used marshal calls ui thread not visible     /// </summary>     public class hiddenform : form     {       public hiddenform()       {        //making dummy call handle property force native         //window handle created minimum requirement         //invokerequired work.        intptr hwnd = handle;       }     }      /// <summary>     /// addinservice exposed through object property of addin not derive      /// standardolemarshalobject instead uses <see cref="hiddenform"/> marshal calls     /// arbitrary rpc thread ui thread.     /// </summary>     public class addinservice : iaddinservice     {       private readonly form _invokeform;        public addinservice()       {        //create instance of hiddenform allows marshal com        //calls ui thread.        _invokeform = new hiddenform();       }        public void hellooutofproc()       {        if(_invokeform.invokerequired)        {          _invokeform.invoke(           new action<object>(o => hellooutofproc()), new object()); //not elegant yet action<> "out of box" solution find        }        else        {          messagebox.show("hellooutofproc on thread id " + thread.currentthread.managedthreadid);        }       }     }      /// <summary>     /// addin class derive standardolemarshalobject it's executed on ui thread     /// </summary>     public class connect : standardolemarshalobject, idtextensibility2     {       private iaddinservice _service;        public void onconnection(object application, ext_connectmode connectmode,                    object addininst, ref array custom)       {        //create service object exposed out-of-proc processes        _service = new addinservice();         //expose addinservice through comaddin.object property        ((comaddin)addininst).object = _service;       }     } 

tested on window 7, office 2007. hope helps others.

i still know why it's working in .net4.0 , not .net2.0. if has answer this, still appreciated.


Comments

Popular posts from this blog

c# - how to write client side events functions for the combobox items -

exception - Python, pyPdf OCR error: pyPdf.utils.PdfReadError: EOF marker not found -