我需要在使用它时删除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”命令时收到以下错误:
并且Process Explorer显示Excel文件确实仍然由Excel加载:
该文件可以重命名,但不能删除(如代码所示)。
我错过了什么吗?
答案 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
。
另外,我正在使用LongPtr
为VBA7
声明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
希望有所帮助:)