views:

2021

answers:

4

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#.

A: 

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

Thomas Danecker
A: 

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

David
+1  A: 

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.

amazedsaint
+1  A: 

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

[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
ArsenMkrt
But how do I find out the handle that I have to close. I know only the file name. The handle that my process opened on that file is unknown.
Poulo
do you use Process class to launch exe?
ArsenMkrt