LoadLibrary无法识别VBA代码中的PATH

时间:2018-10-27 19:31:01

标签: vba interop windows-store loadlibrary

我有一个DLL,我需要使用LoadLibrary("func1.dll")来调用它。 func1.dll省略了LoadLibrary的完整路径,因为我必须将PATH变量设置为func1.dll所在的地方,因为func1.dll引用了另一个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中编写以上代码时,会出现问题: enter image description here

从Microsoft Store在Office中运行上述VBA代码时,该行:

LoadLibrary("func1.dll")

返回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程序正常打开。

您是我所缺少的还是对我有任何想法?谢谢大家。

1 个答案:

答案 0 :(得分:0)

我设法使用功能AddDllDirectory找到了解决方案。根据{{​​3}},AddDllDirectory函数:

  

将目录添加到进程DLL搜索路径。

这意味着,与SetDllDirectory取代DLL搜索路径的方式不同,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格式。