“Error 'System.Void Mono.Cecil.AssemblyDefinition::.ctor()' is declared in another module and needs to be imported”
-
07-07-2021 - |
Question
I am using latest version of Mono.cecil What I am trying to do is I am having Custom Attributes in a seperate dll and I want to add the attributes to every method in the sample.exe using mono.cecil but i am getting the error
"Error 'System.Void Mono.Cecil.AssemblyDefinition::.ctor()' is declared in another module and needs to be imported"
Can any one help me in resolving it?
Expecting your help.....
//Main File Sample.exe
class SampleItems
{
public static void Main()
{
}
public void Sample()
{
Console.WriteLine("sample");
}
public void Sample1()
{
Console .WriteLine ("sample1");
}
}
================================
Seperate application applying the custom attribute
static void Main(string[] args)
{
//opens the assembly
AssemblyDefinition assemblyDefinition = AssemblyDefinition.ReadAssembly(@"E:\MONOCECIL\POC SAMPLES\Sample.exe.exe");
//AssemblyDefinition as1= AssemblyDefinition .ReadAssembly (@"E:\MONOCECIL\POC SAMPLES\MonoStart\MonoStart\bin\Debug\SampleDll.dll");
var resolver = new DefaultAssemblyResolver();
var systemName = AssemblyNameReference.Parse("SampleDll");
AssemblyDefinition as1 = resolver.Resolve(systemName);
var ty = assemblyDefinition.MainModule.Import(as1.GetType ());
var attCtor = ty.Resolve().Methods.First(x => x.Name == ".ctor"
&& x.Parameters.Count == 0);
foreach (var modDef in assemblyDefinition.Modules)
{
foreach (var typeDef in modDef.Types)
{
Console.WriteLine(" +--Type {0}", typeDef.Name);
//All methods in this type
foreach (var methodDef in typeDef.Methods)
{
var custatt = new CustomAttribute(attCtor);
methodDef.CustomAttributes.Add(custatt);
Console.WriteLine(" --Method {0}", methodDef.Name);
}
}
}
assemblyDefinition.Write(@"E:\POSTSHARP SAMPLES\ASPECTDNG\Debug\Sampleupdate.exe");
Console .ReadLine ();
}
===============================
Sample dll
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SampleDll
{
[System.AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple=false )]
public sealed class SampleClass :Attribute
{
public SampleClass ()
{
}
}
}
Solution
The issue is that the lines:
var ty = assemblyDefinition.MainModule.Import(as1.GetType ());
var attCtor = ty.Resolve().Methods.First(x => x.Name == ".ctor" && x.Parameters.Count == 0);
make absolutely no sense.
Let say you have:
var sampleDll = AssemblyDefinition.ReadAssembly ("SampleDll.dll");
var targetExe = AssemblyDefiniion.ReadAssembly ("SampleExe.exe");
And that you want to add [SampleClass]
on each types in SampleExe.exe
.
You need to create a reference from the SampleClass type in sampleDll into targetExe
var sampleClass = sampleDll.MainModule.GetType ("SampleClass");
var sampleClassCtor = sampleClass.Methods.First(m => m.IsConstructor);
var ctorReference = targetExe.MainModule.Import (sampleClassCtor);
foreach (var type in targetExe.MainModule.Types)
type.CustomAttributes.Add (new CustomAttribute (ctorReference));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow