1

我有一个应用程序隐式打开 dll/文件的句柄。在应用程序的某个时刻,我想释放这个句柄。我该怎么做?我的应用程序在 C# 中。

4

4 回答 4

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。

于 2009-08-04T06:53:18.723 回答
4

如果您有要关闭的处理程序,请使用 PInvoke

[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
于 2009-08-04T06:54:17.723 回答
0

只需使用打开句柄的类的 Dispose 或 Close 方法。

于 2009-08-04T06:49:03.553 回答
0

我不知道一个简单的方法。过度隐式文件锁定是我一直不喜欢 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

于 2009-08-04T06:52:42.267 回答