外接共享插件和VSTO 2005 SE 插件的对比

参考:Migrating a Shared Add-in to a Visual Studio Tools for Office Add-In

http://msdn.microsoft.com/zh-cn/library/aa663367(en-us).aspx

我的小结:

1.外接共享插件可以通过事件,将插件类对象赋值给addInInstance.Object ,这样外部调用程序,可以读取

COMAddIn addIn = wordApp.COMAddIns.Item(ref oI);

addIn.Object,从而进行交互控制。

   public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom)
   {

            wordApp = (Word.Application)application;
            addInInstance = (Office.COMAddIn)addInInst;

            //提供一个外部程序调用插件方法的对象引用,晚绑定调用方法
            //外部程序通过COMAddIn.Object远程访问此插件程序的对象
            addInInstance.Object = this;
   }

VSTO SE 则是通过       

protected override object RequestComAddInAutomationService()
        {
            if (utilities == null)
                utilities = new AddInUtilities();

            return utilities;
        }

方法,将返回值给COMAddIn.Object . 也实现了同样的功能.注意一定要设置[System.Runtime.InteropServices.ComVisibleAttribute(true)]

参考:

AddIn.RequestComAddInAutomationService Method

http://msdn.microsoft.com/en-us/library/microsoft.office.tools.addin.requestcomaddinautomationservice(VS.80).aspx

How to cast COMAddIn.Object in C#?

http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/4ca46a99-9d48-4ba1-af3a-8d5c0c18f99e/

First, lets see what is actuall happening:

In Excel.exe process:
Addin Obj (managed) ---> Com Callable Wrapper created (CLR) ---> Excel recieves pointer to the CCW

In external app (automating Excel):
External App (managed) reads Addin object from Excel <---- Runtime Callable Wrapper created (CLR) <--- Excel returns CCW

As far as the instance of CLR running in the external app is concerned, it recieved a pointer to a COM interface (actually proxy). It can not cast a COM object to a managed object because it has no idea what the object in the other process (Excel.exe) is.

In fact if you tried your exact same code from another addin running in-proc (i.e within Excel.exe) it would work. In this case CLR always knows the underlying type of the object and is able to perform a legal cast.

Solutions:
1. You can make late-bound calls on the COM object using reflection. This is actually the reason why VBA code works. VBA runtime always makes late bound calls using IDispatch interface based on the code you typed (remember it's interpreted not compiled).

    object addInObj = isentrisAddIn.Object;

    // Making late-bound call on object. We lose out on compile time checking
    object [] invokeArgs = {4};
    object retVal = addInObj.GetType().InvokeMember( "SomeMethod" ,
        System.Reflection.
BindingFlags .InvokeMethod, null , addInObj, invokeArgs);
    Console .WriteLine(retVal.ToString()); // output: "4"

2. Declare an interface in your addin and only pass the interface "pointer" around. In this case CLR will make the late-bound calls for you based on the interface definition.

In your addin:
    IExposedClass expClsPtr = null;
    public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom) {
        expClsPtr = new ExposedClass();
        Office.
COMAddIn addin = (Office.COMAddIn)addInInst;
        addin.Object = expClsPtr;
    }

[System.Runtime.InteropServices.ComVisibleAttribute(true)]
[System.Runtime.InteropServices.InterfaceType(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIDispatch)]
    public interface IExposedClass {
       
string SomeMethod(int r);
    }

[System.Runtime.InteropServices.ComVisibleAttribute(true)]
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)]
    public class ExposedClass : IExposedClass {
       
public string SomeMethod(int r) { return r.ToString(); }
    }

In external app (automating Excel):
    object addInObj = isentrisAddIn.Object;
    MyExcelAddin1.
IExposedClass addInExposedAgain = (MyExcelAddin1.IExposedClass)addInObj;
    string temp = addInExposedAgain.SomeMethod(4);    // Call a method on addin object

上面提供的方法,第一种回调方式,我OK,但是第二种方式,我失败了,会出错!

2、VSTOSE插件是托管的,所以插件的异常可以被WORD程序捕获,并显示,而共享插件出现异常时,无法获取到。所以VSTOSE插件更易于维护。

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值