2017-08-16 132 views
1

當我完成使用它(清除代碼完成後)時,需要刪除一個DLL文件。VBA FreeLibrary不會卸載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」執行「殺死」時我收到以下錯誤命令:

Path Access Error

以及示出的DLL文件確實仍然由加載進程瀏覽器Excel中:

Process Explorer

文件可以重命名,但不能刪除(如INDI由代碼提供)。

我錯過了什麼嗎?

+0

FreeLib僅遞減引用計數。檢查FreeLib返回值。如果它不是零,那麼你還沒有真正卸載它。 – cyboashu

+0

@cyboashu謝謝!我已經測試過,並更新了我的代碼來解決這個問題。即使FreeLib返回0,我仍然遇到錯誤。 – Shrout1

回答

0

取決於問題的根源是什麼,這可能會或可能不會幫助,但我認爲這是朝正確方向邁出的一步。

從FreeLib的返回值爲0表示出現了錯誤,因此該庫已被釋放,在這裏看到:https://msdn.microsoft.com/en-us/library/windows/desktop/ms683152%28v=vs.85%29.aspx

從我的理解是調用LoadLibrary是FreeLib只應調用多次使用......所以,而非循環,直到出現一個錯誤(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

另外,我宣佈LOADLIB和FreeLib與LongPtrVBA7這樣的:

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 

希望它能幫助:)