以编程方式在VBA宏中设置DLL搜索路径

Ste*_*out 8 dll vba ms-word word-vba

问题

  • 我有一个单词模板,它使用VBA的Declare语句链接到一个DLL,其路径可以在VBA宏中确定
  • 我想将其部署到用户%APPDATA%\ Microsoft\Word\STARTUP目录
  • 我不想永久更改用户的PATH环境变量(暂时可以,但这似乎不起作用,因为它们在应用程序重新启动之前不会刷新)

试图解决方案

我尝试Declare使用ThisDocument.VBProject.CodeModule.AddFromString(code)从正常目录加载模板时使用的语句动态添加代码,但是当模板在Word\STARTUP中时,它会给出以下错误:

运行时错误'50289':

由于项目受到保护,无法执行操作.

并且当模板在Word\STARTUP中时,将注册表项"HKEY ___ LOCAL_MACHINE\Software\Microsoft\Office\11.0\Word\Security\AccessVBOM"设置为1不会解决此问题


我真的很难找到解决方案.如果有人知道这样做的方法,那就太好了.

pan*_*-34 8

坦率地说,我不知道使用所有这些VBA代码注入,LoadLibrary()调用的程序集生成等技术,我已经看到这些技术用于这个简单的任务.在我的项目中,我使用简单的代码从与工作簿相同的位置加载dll,如下所示:

Declare Function MyFunc Lib "MyDll.dll" (....) As ...

Sub Test()
  ....
  ChDir ActiveWorkbook.Path
  ... = MyFunc(....)
End Sub
Run Code Online (Sandbox Code Playgroud)

至少Excel 2003,从当前路径加载DLL没有问题,将ChDir设置为DLL所具有的任何路径.您可能还需要更改与当前路径分开的当前驱动器.在第一次函数调用之前,无论当前路径在哪里,DLL都必须保持连接,所以你必须只执行一次,因此你可以在workbook_open中执行一次,而不用考虑以后的路径.我在DLL中为这个pupose提供了一个空虚拟函数.我不认为MS Word在这方面有任何不同.

Private Declare Sub Dummy Lib "MyDLL.dll" ()

Private Sub Workbook_Open()
    ChDrive Left$(Me.Path, 1)
    ChDir Me.Path
    Dummy
End Sub
Run Code Online (Sandbox Code Playgroud)

  • 这并不总是有效.当前目录在搜索的路径列表的下方很长,在某些情况下,当前目录可能根本不是搜索路径.另外,您正在使用流程范围的工作目录.具有绝对路径的显式`LoadLibrary`方法是执行此操作的最佳方法. (2认同)

Spa*_*rcU 5

您可以使用LoadLibrary api.

例如,在我的项目中,代码如下所示:

If LibraryLoaded() Then
   Call MyFunc ...
End If


Public Function LibraryLoaded() As Boolean

 Static IsLoaded As Boolean
 Static TriedToLoadAlready As Boolean

 If TriedToLoadAlready Then
    LibraryLoaded = IsLoaded
    Exit Function
  End If
  Dim path As String
 path = VBAProject.ThisWorkbook.path
 path = Left(path, InStrRev(path, "\") - 1)
 IsLoaded = LoadLibrary(path & "\bin\" & cLibraryName)
 TriedToLoadAlready = True

 LibraryLoaded = IsLoaded

End Function
Run Code Online (Sandbox Code Playgroud)