====== 動的DLLの解放 ======
[[https://qa.atmarkit.co.jp/q/1552|動的DLLの解放について]]
===== 質問内容 =====
①EXEを実行(EXEは24h常駐です。)
②動的にDLLをロード・実行し、DLLの処理終了(EXEは終了しない。)
③DLLのPGを改訂し、実行環境にコピーすると、エラーMSGがでる。
「○○.dllをコピーできません。他の人またはプログラムによって使用されています。ファイルを使用している可能性があるプログラムを全て閉じてから、やり直してください。」
EXEを24h常駐させ、実行条件によって、ロードするDLLを変更したいと考えています。
今後業務要件によってDLLを改訂する可能性があります。
===== 回答 =====
.NETでは、Win32の時のFreelibrary関数(DLLを呼び出しプロセスの アドレス空間から切り離す)のようなものはなく、一旦DLLを ロードしたらプロセスを終了するまでメモリに残り続けます。\\
(通常のDefault AppDomainにロードされている場合において)\\
{{:it技術:dotnet:appdomain.jpg|}}\\
あえて動的にする場合は、CreateDomainにて、「User AppDimain」を作成し、そこにアセンブリをロードして実行、終了時にAppDimainをUnloadすることで、動的にアセンブリを解放することが出来るようになります。
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)
'インターフェース実装
Public Class IClass
Public Interface IClass1
Function test() As Integer
End Interface
End Class
'シリアライズを入れる必要がある。
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)
===== 別案:シャローコピー =====
ロード中のアセンブリの入れ替えが目的ならシャドウコピーでよい。\\
[[https://msdn.microsoft.com/ja-jp/library/ms404279.aspx?f=255&MSPPError=-2147217396|アセンブリのシャドウ コピー MSDN]]\\
[[http://d.hatena.ne.jp/akiramei/20071111/1194786373|C# DLLの動的読み込み]]
===== 参照 =====
* [[http://acha-ya.cocolog-nifty.com/blog/2010/11/dll3-fb83.html|マネージドDLLの動的リンク(3)]]
* [[http://acha-ya.cocolog-nifty.com/blog/2010/11/dll4-be0f.html|マネージドDLLの動的リンク(4)[最終回]]]
* [[http://gushwell.ldblog.jp/archives/52211840.html|アセンブリを動的にロードし、そして完全にアンロードする]]
* [[http://white-azalea.hatenablog.jp/entry/20081106/1225976143|ManagedDll を動的に読み込むあれこれ]]
* [[https://jyuch.hatenablog.com/entry/2015/12/06/003000|VB.NETでもDLLをアンロードしたい]]