题
我有一个应用程序隐式打开 dll/文件上的句柄。在应用程序的某个时刻,我想释放这个句柄。我该怎么做?我的应用程序是用 C# 编写的。
解决方案
使用PInvoke的,如果你有,你要关闭的处理程序
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
其他提示
正是你正在尝试做的?如果要加载程序集做一些东西了,并且然后完全卸载它,你需要依靠建立一个新的应用领域。
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
或者,如果你只是担心 保持锁定了该文件,你可以使用 影子复制。这将使副本 磁盘上的文件,并从加载它 新的位置。原始文件 不会受负载被锁定。至 做到这一点,设置 AppDomainSetup.ShadowCopyFiles到 “真实”创造的AppDomain时或 集AppDomain.ShadowCopyFiles为真 后它已经被创建。
只要使用的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 也能起到同样的作用: http://technet.microsoft.com/en-us/sysinternals/bb897556.aspx
或者,您可以在您的程序未运行时让另一个程序访问该文件。
如果您确实想尝试关闭句柄,可以通过多种方法获取每个进程的句柄列表,如果 .NET 尝试再次访问它,这很可能会使您的程序崩溃。这不太漂亮,示例是 C++:http://www.codeguru.com/forum/showthread.php?t=176997