无需本地管理员即可将VSTO功能公开给VBA
将Dotnet VSTO Excel外接程序中的某些功能公开到VBA而不要求用户是本地管理员(即没有COM注册,没有HttpListener)的最佳方法是什么?是否可以使用VBA中的Microsoft消息队列?
解决方案
如果我可以将问题解释为"如何在没有COM注册的情况下将.Net程序集的功能公开给Excel",那么一个很好的解决方案是使用Excel的XLL接口。
基本上,它会部署xll填充程序和关联的.Net dll。加载xll时,它将反映dll,并将其中的功能公开给Excel。
可以在以下网址找到开放源代码实现:http://exceldna.typepad.com/blog/2006/01/introducing_exc.html
商业的,封闭的源代码,但此处功能更丰富
http://www.managedxll.com/
我们不能简单地将它们实例化为COM对象,因为VSTO不会在默认应用程序域中运行。
这是我的操作方式,这确实有些令人费解。这是将VSTO工作簿另存为XLA文件的方式,在某些方面比纯VSTO加载项更灵活。
- 我们需要使用regasm.exe生成类型库,该库将由VBA代码引用。
- 在.NET对象模型中创建一个根工厂类,该类能够实例化我们要在VBA中使用的任何类(类似于Office对象模型中的" Application"类)。
- 然后,我们需要找到一种将对该工厂类的实例的引用传递给VBA的方法。一旦VBA引用了该工厂类的实例,它便可以调用其方法以实例化.NET对象模型中的任何其他对象。
- 要将实例传递给VBA,请在VBA代码中定义一个宏,如下所示
示例代码:
Private m_objMyFactory As Object Public Sub RegisterFactory(MyFactory As Object) On Error GoTo ErrHandler Set m_objMyFactory = MyFactory Exit Sub ErrHandler: MsgBox "An unexpected error occurred when registering the Factory component: " & Err.Description Exit Sub End Sub
- 现在,将代码添加到VSTO ThisWorkbook_Open事件处理程序中,该事件处理程序将实例化工厂对象,并调用上述宏以将对工厂对象的引用传递给该宏。
示例代码:
void ThisWorkbook_Open() { try { ThisApplication.Run("RegisterFactory", new MyNamespace.MyFactory(), Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); } catch (Exception ex) { MessageBox.Show("Load error: " + ex.ToString()); } }
如果我们有兴趣继续进行此操作,还有一些其他问题需要考虑,以使此功能稳定运行,请告诉我,我将发布更多详细信息。
我们可能对Excel4Net感兴趣(它类似于ExcelDNA和ManagedXll,但更易于使用):
网站:
http://www.excel4net.com
博客:
http://excel4net.blogspot.com
仅供以后的读者参考:我们可能还想看看这个问题:
从VBA(Excel)访问VSTO应用程序插件类型
尤其是那里引用的博客:
VSTO加载项,COMAddIns和RequestComAddInAutomationService
通过重写RequestComAddInAutomationService(),可以定义一个Facade类(为所有这些功能提供入口点),并将该类暴露给VBA,从而提供所需的任何功能。