VBA FreeLibrary不会卸载DLL

时间:2017-08-16 19:23:23

标签: excel vba dll delete-file

我需要在使用它时删除DLL文件(代码完成后清理)。

我尝试在Excel VBA中使用“LoadLibrary”和“FreeLibrary”但无论我做什么Excel.exe都附着在DLL文件中。

 Public Declare PtrSafe Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
 Public Declare PtrSafe Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long

 Private Sub Load_Unload_DLL()

     Dim lb As Long, pa As Long
     lb = LoadLibrary("C:\Users\Administrator\Documents\MathLibrary.dll")

     'MsgBox "Library address: " & lb

     Dim FreeResult As Long
     FreeResult = 1

     Do Until FreeResult = 0
         FreeResult = FreeLibrary(lb)
     Loop

     Name "C:\Users\Administrator\Documents\MathLibrary.dll" As "C:\Users\Administrator\Documents\MathLibrary2.dll"

     Kill ("C:\Users\Administrator\Documents\MathLibrary2.dll")

 End Sub

尽管“FreeResult”等于“0”,但在执行“Kill”命令时收到以下错误:

Path Access Error

并且Process Explorer显示Excel文件确实仍然由Excel加载:

Process Explorer

该文件可以重命名,但不能删除(如代码所示)。

我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

我刚刚重新发现了这个答案,并且有一些经验表明它不会被使用。

请参阅:https://stackoverflow.com/a/28745693/3451115

我遇到的这个方法的一个问题是,虽然库已被释放,但尝试重新加载它会导致主机崩溃(MS Word对我来说)。

虽然它很邪恶,但它可能符合需要,因此请谨慎使用。

根据问题的根本原因,这可能会有所帮助,也可能没有帮助,但我认为这是朝着正确方向迈出的一步。

FreeLib的返回值0表示存在错误而不是库已被释放,请参阅此处:https://msdn.microsoft.com/en-us/library/windows/desktop/ms683152%28v=vs.85%29.aspx

根据我的理解,FreeLib应该只被调用多次,因为使用了LoadLibrary ...所以,而不是循环直到出现错误(FreeLib = 0)你可以改为有一个循环来释放库,然后检查是否该库仍然加载,尝试这样的事情:

    Do Until lb = 0
        FreeLibrary lb
        If CBool(Err.LastDllError) Then
            debug.print "dll error" & " " & Err.LastDllError
            Err.Clear
            Exit Do
        End If

        lb = 0 ' Reset lb needed for test on next line

        ' Check if the dll really has been released...
        lb = GetModuleHandle("C:\Users\Administrator\Documents\MathLibrary.dll")
    Loop

您需要声明此函数以使用GetModuleHandle(VBA7版本):Private Declare PtrSafe Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal GetModuleHandle As String) As LongPtr

另外,我正在使用LongPtrVBA7声明LoadLib和FreeLib,如下所示:

Private Declare PtrSafe Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As LongPtr
Private Declare PtrSafe Function FreeLibrary Lib "kernel32" (ByVal hLibModule As LongPtr) As Long

希望有所帮助:)

相关问题