How to release a handle through C#?

2019-06-05 00:01发布

I have an application that IMPLICITLY opens a handle on a dll/file. At some point in the application, I want to release this handle. How can I do it? My application is in C#.

4条回答
Evening l夕情丶
2楼-- · 2019-06-05 00:44

What exactly you are trying to do? If you want to load an assembly to do some stuff with that, and then unload it completely, you need to rely on creating a new app domain.

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);
}

Have a look at this post for more, http://blogs.msdn.com/suzcook/archive/2003/07/08/57211.aspx

Or, if you're only worried about keeping the file locked, you could use shadow copying. That will make a copy of the file on disk and load it from the new location. The original file will not be locked by that load. To do that, set AppDomainSetup.ShadowCopyFiles to "true" when creating the AppDomain or set AppDomain.ShadowCopyFiles to true after it's already been created.

查看更多
3楼-- · 2019-06-05 00:46

Just use the Dispose or Close method of the class that opened the handle.

查看更多
▲ chillily
4楼-- · 2019-06-05 00:55

use PInvoke if you have an handler that you want to close

[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
查看更多
SAY GOODBYE
5楼-- · 2019-06-05 00:57

I don't know an easy way. Excessive implicit file locking is something I've always disliked about Windows.

If you need to replace the file, MoveFileEx can do it at next boot. You'd use it to rename or delete the original, and then rename something else into its place. http://msdn.microsoft.com/en-us/library/aa365240(VS.85).aspx http://www.pinvoke.net/default.aspx/kernel32/MoveFileEx.html

If you don't want to mess with the API directly there's MoveFile in the SysInternals suite which does the same: http://technet.microsoft.com/en-us/sysinternals/bb897556.aspx

Or you can have another program access the file when your program isn't running.

There's ways to get a list of handles per process, if you really want to try to close the handle, which would most likely just crash your program if .NET tries to access it again. It's not pretty, and the example is C++: http://www.codeguru.com/forum/showthread.php?t=176997

查看更多
登录 后发表回答