2017-11-07 14 views
1

私はアプリケーションを再起動せずに私のdllを置き換える必要がありますが、FreeLibraryの後もまだ使用されており、削除することはできません。Delphi7。どのように再起動せずにDLLをアンロードするには?

助けてください。

//... 
function MyFunc(): PChar; stdcall; external 'MyDll.dll'; 

implementation 

//... 

hDLL := LoadLibrary('MyLib.dll'); 
if hDLL = 0 then 
    Begin 
    LogError('Can''t load MyLib.dll!'); 
    exit; 
    end; 

try 
    MyFunc(); 
finally 
    FreeLibrary(hDLL); 
end; 

if not DeleteFile('MyLib.dll') then 
    LogError('Can''t delete MyLib.dll!'); 
+0

私はあなたができるとは思わない。新しいDLLを別の名前でインストールし、そのDLLにリンクして、再起動時に古いDLLを削除し、新しいDLLの名前を変更することができます。 –

+2

@RudyVelthuisが間違っています。 'FreeLibrary'を呼び出すと、参照カウントが0になるとDLLがアンロードされます。他のプロセスがロードしていない限り、削除することができます。 –

+0

@David:明らかに、それはアンロードできません。だから何が原因であれ、私は説明されているようなことをするでしょう。 –

答えて

4

まず、よくある間違いを解消しましょう。あなたは書く:

if hDLL < 32 then 

これは、DLLをロードする際の障害のためにテストする方法ないです。 LoadLibraryのドキュメントで非常に明確に述べられているように、エラーは戻り値NULLで示されます。デルファイの用語では0です。限りLoadLibraryへの各呼び出しがFreeLibraryに一致する呼び出しと対になっているとして、ファイルを削除することが可能であり、それを超えて

if hDLL = 0 then 

:だからとそのテストを交換する必要があります。

だから、何かがあなたの削除を止めています。たとえば、次のようになります。

  • このDLLは、ユーザーが削除する権限がないディレクトリにあります。
  • 別のプロセスがDLLをロードしました。
  • あなたのプロセスは何らかの手段でDLLをロードしているため、依然として参照が保持されています。
  • DLLが現在の作業ディレクトリにありません。相対パスを使用したため、DLLのロード時にDLL検索パスが使用されますが、削除しようとすると作業ディレクトリが使用されます。これらは一致しないかもしれません。

このリストは網羅的ではありません。

ここでいくつかのデバッグを行う必要があります。 DeleteFileへの呼び出しが失敗する状況に直面しています。だから、なぜシステムに尋ねる。

if not DeleteFile('MyLib.dll') then 
    LogError(Format('Can''t delete MyLib.dll, error code = %d', [GetLastError])); 
+0

エラーコードは5(アクセスが拒否されました) – krtl

+0

さらに、LoadLibraryが呼び出される前でもMyLib.dllを削除できません。 DLLから使用されるすべての関数の宣言をコメントアウトすると、ファイルは削除されます。 – krtl

+0

私の答えはそれがそうであるかもしれない様々な理由を記載します。あなたはそれがどれであるかを知るためにいくつかのデバッグをする必要があります。 –

関連する問題