Search code examples
c#msbuildportable-class-librarymsbuild-taskmono.cecil

Locked Target Assembly with Mono.Cecil and PCL Code Injection


I have a solution structure as follows:

**CoreSolution**
|
+---- Core.dll (PCL)
       |
       +---- CodeInjectionLogic (Inserts IL instruction on each type using Mono.Cecil for PCL)

**BuildSolution**
|
+---- Core.dll  (For Project Reference)
|     
+---- CustomMSBuildTask.dll  (Injects the code into the target.dll)
      |
      + ---CodeInjectionTask 
           Applies CodeInjectionLogic on each Type to weave IL instruction

 **TargetSolution**
 |
 +---- Core.dll  (For Project Reference)
 |
 +---- Target.dll (PCL)
       |
       +  <using Task CodeInjectionTask....>  

The locking issue for CustomMSBuildTask.dll is solved by copying all dlls on a temporary director as a BeforeBuild event.

Building TargetSolution which contains the Target assembly and using Mono.Cecil I am able to read the Target.dll modify the types and insert the IL instruction but when I try to write the modified stream back using Mono.Cecil.AssemblyDefiniyion.Write() I always get an error from MSBuild

The process cannot access Target.dll because it is being used by another process. Which I assume is the MSBuild itself.

Any pointers on how can I use Mono.Ceeil and PCL to weave a target assembly that is being built using custom MSBuild AfterBuild target.


Solution

  • Ok, i asked this to Jb Evain and based on his comments I am going to answer my own question.

    This is due to the breaking change in latest version of Cecil (0.10 Beta) http://cecil.pe/post/149243207656/mono-cecil-010-beta-1

    If we are reading and writing to same file then we have to update the code as below.

    // ReaderParameters { ReadWrite = true } is necessary to later write the file
    using (var module = ModuleDefinition.ReadModule(file, new ReaderParameters { ReadWrite = true })) 
    {
         // Modify the assembly
         module.Write (); // Write to the same file that was used to open the file
    }