1

我正在尝试使用 Excel VBA 中的 COM 可见 .NET DLL。使用 regasm 注册 DLL 然后通过 VBA Developer 窗口中的 Tools -> References 菜单项手动添加对它的引用时,我已经成功。

但是,我现在尝试在不使用 regasm 命令的情况下注册 DLL,以便可以在任何计算机上使用 Excel 文件而无需注册 DLL。到目前为止,这是我尝试过的:

Dim JART_Instance As Object

Sub Initialize()
    Dim RefPath As String, X As Byte
    Const RefName = "JART xxx"
    RefPath = Application.ActiveWorkbook.Path & "\JART\JART.dll"

    With ActiveWorkbook.VBProject.References
        For X = 1 To .Count
            If .Item(X).Description Like RefName Then
                .Remove .Item(X)
            End If
        Next
       .AddFromFile (RefPath)
    End With
End Sub

Sub PostInitialize()
    Set JART_Instance = New JART.MainJobControl
End Sub

我添加了对“Microsoft Visual Basic for Applications Extensibility 5.3”的引用。当我运行上面的代码时,我得到“运行时错误'48':加载 DLL 时出错”。我已经使用 regasm 加载了这个 DLL 几次。我是否需要做一些事情,比如更改项目中使用的 GUID 并重试。我已经看过应该可以工作的代码示例。

如果我引用 tlb 文件而不是 .dll,我不会收到 DLL 加载错误。相反,每当我尝试使用 JART_Instance 变量说引用尚未设置时,我都会收到错误消息。即使 PostInitialize 在 Initialize 之后直接被调用,并且没有证据表明任何代码引发错误或无法运行。如果我尝试在 PostInitialize 函数中放置“停止”命令,它会告诉我“此时无法进入中断模式”。

任何想法,谢谢。

4

2 回答 2

1

Excel-DNA 有一个辅助函数,可以为在该平台上编写的 Com Addins 执行此操作。

它似乎:

  1. 加载插件
  2. 用 CoRegisterClassObject 注册它
  3. 将它的 progid 添加到注册表
  4. 将其添加到注册表项 HKCU\Software\Microsoft\Office\Excel\Addins
  5. 在 Excel 中调用 Application.ComAddins.Update
  6. 删除所有以前的注册表项
  7. 使用 CoRevokeClassObject 注销对象

看起来,一旦 Excel 加载了插件,在删除注册表项并调用 CoRevokeClassObject 时它不会卸载。它会一直加载,直到 Excel 关闭并释放它。

所以,这是可行的,但并不容易。

于 2013-08-19T18:53:01.133 回答
0

好的,所以我使用了一个 shell 命令来使用 regasm 注册 DLL。这是我的代码:

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Dim strWinCmd As String
    Dim retVal As Double
    strWinCmd = "cmd.exe %SystemRoot%\Microsoft.NET\Framework\v2.0.50727\regasm.exe /u /codebase /tlb .\JART\JART.dll"
    retVal = Shell(strWinCmd, vbHide)
End Sub

Private Sub Workbook_Open()
    Dim strWinCmd As String
    Dim retVal As Double
    strWinCmd = "cmd.exe /c %SystemRoot%\Microsoft.NET\Framework\v2.0.50727\regasm.exe /codebase /tlb """ & Application.ActiveWorkbook.Path & "\JART\JART.dll"""
    Call Shell(strWinCmd, vbNormalFocus)

    Call Button_Handlers.Sleep(1500)

    Call Button_Handlers.Initialize
End Sub

作为参考, Button_Handlers.Sleep 只调用系统睡眠方法,而 Button_Handlers.Initialize 这样做:

Sub Initialize()
    'This JART.MainJobControl is the main class in the JART DLL
    Set JART_Instance = New JART.MainJobControl
    'Use JART_Instance
End Sub

所以基本上我试图在启动时注册 DLL 并在关闭时取消注册。我的问题是,当我在新 PC 上打开此文件时,Button_Handlers.Initialize 出现错误。它告诉我我正在尝试使用未定义的类 (JART.MainJobControl),就好像没有引用 DLL。如果我尝试重新打开文件一切正常???

我这样做的方式是在已经注册了 regasm 的机器上手动添加对 DLL 的引用。然后我保存这个 excel 文件并将其传输到尚未注册 DLL 的机器上并尝试打开它并运行它。我认为由于引用已经添加到 excel 文件中,所有代码所要做的就是使用 regasm 注册它。有谁知道为什么这不起作用?我是不是睡得不够久。我可以将此作为一个单独的问题发布。

于 2013-08-20T16:19:58.103 回答