dll/ファイルのハンドルを暗黙的に開くアプリケーションがあります。アプリケーションのある時点で、このハンドルを解放したいと考えています。どうすればいいですか?私のアプリケーションは C# です。
4 に答える
あなたは正確に何をしようとしていますか?アセンブリを読み込んでそれを処理し、完全にアンロードする場合は、新しいアプリ ドメインの作成に頼る必要があります。
public static void Main(string[] args)
{
AppDomain appDomain = AppDomain.CreateDomain("NewAppDomain");
appDomain.DoCallBack(new CrossAppDomainDelegate(AsmLoad));
// At this point, your assembly is locked, you can't delete
AppDomain.Unload(appDomain);
Console.WriteLine("AppDomain unloaded");
//You've completely unloaded your assembly. Now if you want, you can delete the same
}
public static void AsmLoad()
{
Assembly assembly = Assembly.LoadFrom(@"c:\Yourassembly.dll");
//Loaded to the new app domain. You can do some stuff here
Console.WriteLine("Assembly loaded in {0}",AppDomain.CurrentDomain.FriendlyName);
}
詳細については、この投稿をご覧ください。http://blogs.msdn.com/suzcook/archive/2003/07/08/57211.aspx
または、ファイルをロックしたままにしておくことだけが心配な場合は、シャドウ コピーを使用できます。これにより、ディスク上にファイルのコピーが作成され、新しい場所からロードされます。そのロードによって元のファイルがロックされることはありません。これを行うには、AppDomain の作成時に AppDomainSetup.ShadowCopyFiles を「true」に設定するか、既に作成された後に AppDomain.ShadowCopyFiles を true に設定します。
閉じたいハンドラーがある場合は、PInvoke を使用します。
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
ハンドルを開いたクラスの Dispose メソッドまたは Close メソッドを使用するだけです。
簡単な方法がわかりません。過剰な暗黙的なファイル ロックは、私がずっと Windows で嫌いだったことです。
ファイルを置き換える必要がある場合、MoveFileEx は次回の起動時にそれを行うことができます。元の名前を変更または削除してから、別の名前をその場所に変更するために使用します。 http://msdn.microsoft.com/en-us/library/aa365240(VS.85).aspx http://www.pinvoke.net/default.aspx/kernel32/MoveFileEx.html
API を直接いじりたくない場合は、同じことを行う SysInternals スイートに MoveFile があります。
または、プログラムが実行されていないときに、別のプログラムがファイルにアクセスするようにすることもできます。
本当にハンドルを閉じようとする場合は、プロセスごとにハンドルのリストを取得する方法があります。.NET が再びハンドルにアクセスしようとすると、プログラムがクラッシュする可能性が高くなります。きれいではありません。例は C++ です: http://www.codeguru.com/forum/showthread.php?t=176997