How to avoid locking a file after reading it?

Howdy folks,

I wrote a small windows application that allows the user to drag and drop files from Windows Explorer. The program attempts to load each file as an assembly in a try-catch block. If it's a valid assembly, it displays information about it in a data grid.

The problem is, the application has some sort of lock on the file from that point until the application is closed. After I get the information I want from the assembly (version, etc), I set the assembly variable in the code to null. Still, when I try to delete a file in Windows Explorer, it says that it's being used by another program. Does anybody know how I can tell my application to release whatever lock it has on the file

Thanks,
Dan


Answer this question

How to avoid locking a file after reading it?

  • Dennis Pilarinos

    Derek, I tried your suggestion but had the same problem. I got a got a temp file from a call to System.IO.Path.GetTempFileName(). I was able to copy the file, and load it as an assembly. When I tried to delete the file within the program though, same problem (should have seen this coming since I couldn't delete from outside the program after the assembly was loaded). Well, there are huge numbers of files that are checked by the program (sometimes thousands) so I didn't want to clog up somebody's temp directory.

    Imran, you're a genius! Your code works perfectly and no longer locks the files. The only change was that the FileStream declaration needed to be System.IO.FileStream(@"C:\MyAssembly.dll", System.IO.FileMode.Open, System.IO.FileAccess.Read) because it was throwing an exception when trying to read read-only files.

    Thanks so much for all your help, it works great now!

    Dan

  • Lior Canetti

    Dan,

    As Derek mentioned, once an assembly is loaded into an AppDomain, it cannot be unloaded until the AppDomain itself has been unloaded. In most cases, this translates into "until your application closes". Also, using Assembly.Load and specifying the filename for the assembly does lock the file which means you can't do anything to the file until your application closes down. One way is to load the assembly in another AppDomain. Another way is to use the overload of Assembly.Load that takes in an array of bytes. Here's how you can do that:
    [VB.NET]
    Imports System.Reflection

    Dim asm As Assembly

    Using stream As New FileStream("C:\MyAssembly.dll", FileMode.Open)
        Using memstream As New MemoryStream()
            Dim b(4096) As Byte
            While stream.Read(b, 0, b.Length) > 0
                memstream.Write(b, 0, b.Length)
            End While
            asm = Assembly.Load(memstream.ToArray())
        End Using
    End Using
    MessageBox.Show(asm.FullName)

    [C#]
    using System.Reflection;
    using System.IO;

    MemoryStream memStream;

    using(FileStream stream = new FileStream(@"C:\MyAssembly.dll", FileMode.Open))
    {
        using (memStream = new MemoryStream())
        {
            int res;
            byte[] b = new byte[4096];
            while ((res = stream.Read(b, 0, b.Length)) > 0)
            {
                memStream.Write(b, 0, b.Length);
            }
        }
    }
    Assembly asm = Assembly.Load(memStream.ToArray());
    MessageBox.Show(asm.FullName);

    hope that helps,
    Imran.

  • ChrisSabien

    When you load an assembly dynamically you load it into an AppDomain, assemblies cannot be unloaded from an AppDomain unless the AppDomain is completely destroyed.

    This is fairly detailed stuff, gets right into the foundations of the .NET framework, and I have no idea how it all works in code. If you do a search for AppDomain or even better search for creating add-ins and you'll find the right information you need.

    http://www.gotdotnet.com/team/clr/AppdomainFAQ.aspx

    What your doing by loading an Assembly is partially what you do to load custom add-ins for your application.

    There's an easier way to solve this problem though, copy the assembly to a temporary directory, load that copy, and clear the directory when your application closes. Leave the original alone and it won't be locked.



  • How to avoid locking a file after reading it?