Failed to delete assembly (.exe)

I wrote a small application to get the version numbers of the files contained in a .cab file.

I extract all the files from the cab to the temp directory and look at all the files and extract the version numbers as follows:

//Attempt to load .net assembly to retrieve information Assembly assembly = Assembly.LoadFile(tempDir + @"\" + renameTo); Version version = assembly.GetName().Version; DataRow dr = dt.NewRow(); dr["Product"] = renameTo; dr["Version"] = version.ToString(); dt.Rows.Add(dr); 

Then, when done, I want to delete all the files that were extracted as follows:

  foreach (string filePath in filePaths) { //Remove read-only attribute if set FileAttributes attributes = File.GetAttributes(filePath); if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) { File.SetAttributes(filePath, attributes ^ FileAttributes.ReadOnly); } File.Delete(filePath); } 

This works for all files, except when .net.exe sometimes crashes. I can manually delete the file so that it is not locked.

What should I look for to make this work? Can Assembly.LoadFile lock a file?

+4
source share
3 answers

AssemblyName.GetAssemblyName will receive an AssemblyName without locking the file on you. see msdn . You can get the version from there.

+2
source

Assembly.LoadFile really locks the file. If you need to load assemblies from files and then delete files, then you need to do the following:

  • Launch the new AppDomain
  • Download the assembly in this application.
  • Work only with it - do not use any types from the assembly in your main application.
  • Call AppDomain.Unload to tear down AppDomain
  • Then delete the file

You cannot delete the file containing the assembly when this assembly is loaded into the executable AppDomain.

+6
source

Another approach (in addition to using Load from file in a separate AppDomain) is to load the assembly from a copy of the MemoryStream file using Assembly.Load from bytes to the main AppDomain.

Please note that in order for the code to be completely correct, you may still need separate AppDomains for each assembly if there are assemblies with the same identifier in the same file (i.e. 2 non-strongly signed assemblies with the same file name )

Even with individual AppDomains, it would be safer to load from bytes using LoadReflectionOnlyFrom for your script, since in this case there is no chance that refusing to unload AppDomain will block the file, and you have full control over locking the file yourself. Regular loading of assemblies using a load of bytes requires significant reading to understand the related problems and better avoid.

+1
source

Source: https://habr.com/ru/post/1414414/


All Articles