LoadLibrary 无法识别 VBA 代码中的 PATH

LoadLibrary does not recognize PATH in VBA code

我有一个 DLL,我需要使用 LoadLibrary("func1.dll") 调用它。 LoadLibrary 中省略了 func1.dll 的完整路径,因为我必须将 PATH 变量设置为 func1.dll 所在的位置,因为 func1.dll 引用了另一个名为func2.dll.

因此,为了使其正常工作,我使用了以下代码:

Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function SetEnvironmentVariable Lib "kernel32" Alias "SetEnvironmentVariableA" (ByVal lpName As String, ByVal lpValue As String) As Long

Private Sub t1()
    Dim lb As Long
    Dim dllpath As String

    dllpath = "C:\temp\DllsOffice\DLLsOffice\Debug"
    SetEnvironmentVariable "PATH", dllpath 
    Debug.Print Environ("PATH")

    lb = LoadLibrary("func1.dll")
    MsgBox lb   

    FreeLibrary lb
End Sub

对于 Office 2007、2010、2013、2016 甚至 Office 2019 的 VBA 都非常适用。32 位和 64 位。

在Microsoft Store安装的Office的VBA中编写上述代码时出现问题:

当 运行 上述 VBA 代码在 Microsoft Store 中的 Office 行中:

LoadLibrary("func1.dll")

returns 0,表示没有加载DLL。所以,我 运行 想不出让这个工作的想法,但直到现在都没有成功。

以下是有关该问题和我尝试执行的操作的一些附加信息:

  1. 正在将 DLL 复制到可执行路径。例如,如果我将 func1.dll(和 func2.dll)放在 C:\Program Files (x86)\Microsoft Office\Office14 中,我可以使用 LoadLibrary 而无需使用 SetEnvironmentVariable "PATH", dllpath。但是我无法将 DLL 从 Microsoft Store C:\Program Files\WindowsApps\Microsoft.Office.Desktop.Word_16040.10827.20181.0_x86__8wekyb3d8bbwe\Office16 复制到 Office 的路径,因为它拒绝访问;

  2. 我完全确定 SetEnvironmentVariable "PATH", dllpath 在 Microsoft Store 的 Office 上运行良好。我测试了将可执行文件放入 C:\temp\DllsOffice\DLLsOffice\Debug 然后调用 Shell "test.exe"(不传递完整路径)我的 test.exe 程序正常打开。

你知道我遗漏了什么或者有什么想法可以让我遵循吗?谢谢大家

我设法使用函数 AddDllDirectory 找到了解决方案。根据Microsoft websiteAddDllDirectory函数:

Adds a directory to the process DLL search path.

这意味着,与替换 DLL 搜索路径的 SetDllDirectory 不同,AddDllDirectory 的工作方式类似于增量 DLL 搜索路径。所以,我的工作代码可以是这样的:

Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function SetEnvironmentVariable Lib "kernel32" Alias "SetEnvironmentVariableA" (ByVal lpName As String, ByVal lpValue As String) As Long
Private Declare Function AddDllDirectory Lib "kernel32" (ByVal lpLibFileName As String) As Integer

Private Sub t1()
    Dim lb As Long
    Dim dllpath1 As String
    Dim dllpath2 As String
    Dim dllpathN As String

    dllpath1 = "C:\temp\DllsOffice\DLLsOffice\Debug1"
    dllpath2 = "C:\temp\OtherPath"
    dllpathN = "C:\temp\EvenOtherPath"
    AddDllDirectory (StrConv(dllpath1, vbUnicode))
    AddDllDirectory (StrConv(dllpath2, vbUnicode))
    AddDllDirectory (StrConv(dllpathN, vbUnicode))

    lb = LoadLibrary("func1.dll")  ' Success :)
    MsgBox lb   

    FreeLibrary lb
End Sub

OBS:VBA 中 AddDllDirectory 的诀窍在于,没有要使用的该函数的 Ansi 或 Unicode 版本,例如:

AddDllDirectoryA for Ansi 
AddDllDirectoryW for Unicode

所以我需要使用函数 StrConv 将路径显式转换为 Unicode 格式。