问题
我有一个单词模板,它使用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不会解决此问题
我真的很难找到解决方案.如果有人知道这样做的方法,那就太好了.
坦率地说,我不知道使用所有这些VBA代码注入,LoadLibrary()调用的程序集生成等技术,我已经看到这些技术用于这个简单的任务.在我的项目中,我使用简单的代码从与工作簿相同的位置加载dll,如下所示:
Declare Function MyFunc Lib "MyDll.dll" (....) As ... Sub Test() .... ChDir ActiveWorkbook.Path ... = MyFunc(....) End Sub
至少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
您可以使用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