目次

動的DLLの解放

動的DLLの解放について

質問内容

質問内容
①EXEを実行(EXEは24h常駐です。)
②動的にDLLをロード・実行し、DLLの処理終了(EXEは終了しない。)
③DLLのPGを改訂し、実行環境にコピーすると、エラーMSGがでる。
 「○○.dllをコピーできません。他の人またはプログラムによって使用されています。ファイルを使用している可能性があるプログラムを全て閉じてから、やり直してください。」
 
EXEを24h常駐させ、実行条件によって、ロードするDLLを変更したいと考えています。
今後業務要件によってDLLを改訂する可能性があります。

回答

.NETでは、Win32の時のFreelibrary関数(DLLを呼び出しプロセスの アドレス空間から切り離す)のようなものはなく、一旦DLLを ロードしたらプロセスを終了するまでメモリに残り続けます。
(通常のDefault AppDomainにロードされている場合において)

あえて動的にする場合は、CreateDomainにて、「User AppDimain」を作成し、そこにアセンブリをロードして実行、終了時にAppDimainをUnloadすることで、動的にアセンブリを解放することが出来るようになります。

メインコード(動的にDLLを呼ぶ側)
Dim ad As AppDomain
Dim hanlde As System.Runtime.Remoting.ObjectHandle
Try
  'ドメインを生成
  ad = AppDomain.CreateDomain("TEST")
  'インスタンス生成
  hanlde = ad.CreateInstance("ClassLibrary1", "ClassLibrary1.Class1")
  'ラップされたオブジェクトを取得し、IClass1インターフェースにキャスト
  CType(hanlde.Unwrap, IClass.IClass.IClass1).test()
Finally
  'ドメインを開放
  AppDomain.Unload(ad)
End Try

参照設定:IClassのDLL(IClass1インターフェースを持つDLL)

IClass1インターフェースを持つクラス(DLL)のコード
'インターフェース実装
Public Class IClass
    Public Interface IClass1
        Function test() As Integer
    End Interface
End Class
ClassLibrary1を持つDLLのコード(今後動的に変更させるDLL)
'シリアライズを入れる必要がある。
Public Class Class1
Inherits MarshalByRefObject 'アプリケーションドメイン境界を超えてオブジェクトにアクセス
Implements IClass.IClass.IClass1 'インターフェースの継承
    Public Function test() As Integer Implements IClass.IClass.IClass1.test
        Return (任意値)
    End Function
End Class

参照設定:IClassのDLL(IClass1インターフェースを持つDLL)

別案:シャローコピー

ロード中のアセンブリの入れ替えが目的ならシャドウコピーでよい。
アセンブリのシャドウ コピー MSDN
C# DLLの動的読み込み

参照