在我目前的项目中,我正在尝试编写一个挂钩到现有第三方库(通过COM / .NET)的Excel .NET加载项,但是,当涉及到COM时,我有点像新手尽管阅读了相当多的内容,但我从未真正找到过令人满意的解决方案。
有一个第三方加载项,我们称之为加载到Excel中的ExcelAddin.xla
,它在启动时会创建一个新对象。它还包含一个函数来返回AddinController
对象(另一个类)的属性,(下面是VBA):
Private AddinController as Object
Sub Auto_Open()
Set AddinController = CreateObject("ExcelAddInController")
End Sub
Function GetAddinApplication as Object
Set GetAddinApplication = AddinController.Application
End Function
ExcelAddInController
是.NET库中的COM暴露类的ProgID(我们称之为ExcelAddInController.dll
)也是由同一个第三方创建的。似乎Application
属性不是COM暴露的,但是我知道类的结构。
我正在尝试为Excel编写一个基于.NET的add-iin,它挂钩到ExcelAddin.xla
并试图调用GetAddinApplication
来获取Application
属性,这样我就可以用了用它做的事情。
最初,我在VB.NET中为Excel编写了一个传统的COM加载项(MyCOMAddin.dll
)并引用了第三方ExcelAddInController.dll
库,这样我就可以进入类了(下面是VB中的) .NET):
<GuidAttribute(Connect.TypeGuid), ProgIdAttribute(Connect.TypeProgId), ComVisible(True)> _
Public Class Connect
Implements Extensibility.IDTExtensibility2
Public Const TypeGuid As String = "<guid here>"
Public Const TypeProgId As String = "MyAddin"
Private _excelApplication As Excel.Application
Public Sub OnConnection(ByVal application As Object, ByVal connectMode As Extensibility.ext_ConnectMode, ByVal add-iinInst As Object, ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnConnection
_excelApplication = TryCast(application, Excel.Application)
Dim AddinControllerApp as ExcelAddInControllerApplication = TryCast(_excelApplication.Run("ExcelAddin.xla!GetAddinApplication"),ExcelAddInControllerApplication)
End Sub
End Class
这样可行,并且AddinControllerApp
已填充。但是,出于编写COM加载项的最佳实践目的,我想隔离它(即将其称为 - 我认为将其放在单独的AppDomain中?是正确的吗?)来自任何其他.NET加载项如果它崩溃(或任何其他.NET加载项也导致问题)它不会导致问题。
我使用Microsoft COMShim工具为我的加载项创建COM-shim,但是,当尝试使用加载项时,我收到了消息:
Unable to cast COM object of type 'System.__ComObject' to class type 'ExcelAddInControllerApplication'. Instances of types that represent COM components cannot be cast to types that do not represent COM components however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.
我尝试使用Excel-DNA来“包装”差异方法并导致无注册表的COM加载项,但是,我仍然遇到相同的错误 - 所以这必须是由于隔离或缺少某些东西。
在这种情况下,这是否可以解决,以便我可以在我的加载项中使用早期绑定,或者我是否需要使用后期绑定与第三方库进行交互?这不是一个大问题,我只是想确定没有一些聪明的技巧可以用来使用早期绑定(代码自动完成等)。