3

I am trying to write over an assembly that is currently loaded into the AppDomain using Mono.Cecil and I keep getting an IO error saying the file is in use. What I'm doing at the moment is creating an assembly using AssemblyDefinitiion.Create() making any modifications I need than then writing over the Assembly using AssemblyDefinition.Write(). From what I understand about Mono.Cecil it should be possible to write over an existing assembly, but are there other steps to do so?

Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
The Pax Bisonica
  • 2,154
  • 2
  • 26
  • 45
  • 1
    A loaded assembly is a *locked* assembly. You can't overwrite it while it's in use. – Lucas Trzesniewski Jul 18 '15 at 22:32
  • 1
    Once you've modified the assembly, unload it and reload the correct one. – Asad Saeeduddin Jul 18 '15 at 23:08
  • 2
    @Asad you can't unload an assembly. You have to unload the whole AppDomain. – Lucas Trzesniewski Jul 18 '15 at 23:14
  • 2
    @LucasTrzesniewski Oh ok. I guess you could load the assembly into an isolated AppDomain and unload/load that. – Asad Saeeduddin Jul 19 '15 at 00:00
  • 2
    Mono.Cecil is an MSIL parser. Unlike reflection it does not "load the assembly into current app domain". Do you load that assembly via reflection explicitly for other purposes? If so, it is .NET reflection who locks up the file, and you have to unload as other comments indicated. – Lex Li Jul 19 '15 at 03:40

2 Answers2

2

For 0.10.0, adding the ReaderParameters helped with this:

using (AssemblyDefinition a = AssemblyDefinition.ReadAssembly(file, new ReaderParameters { ReadWrite = true }))
{
    var assemblyFileVersionCtor = a.CustomAttributes.Where(attribute => attribute.AttributeType.FullName == typeof(AssemblyFileVersionAttribute).FullName)
        .FirstOrDefault();

    if (assemblyFileVersionCtor != null)
    {
        assemblyFileVersionCtor.ConstructorArguments[0] = new CustomAttributeArgument(a.MainModule.TypeSystem.String, versionToSet.ToString());
        a.Write();
    }
}
2

I also had to set the InMemory property of the ReaderParameters to true.

var rp = new ReaderParameters();
rp.ReadingMode = ReadingMode.Immediate;
rp.ReadWrite = true;
rp.InMemory = true;
Lee Willis
  • 1,552
  • 9
  • 14