使用Mono.cecil修改程序集后,获取"System.IO.FileNotFoundException"错误

Nic*_* Lu 2 c# mono .net-assembly mono.cecil

为了重新产生问题,我创建了这样一个简单的类,这个文件将被编译为"SourceDLL.dll".

namespace SourceDll
{
    public class Class1
    {
        static public int Add(int b, int c)
        {
            return b + c;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我使用Mono.Cecil修改它,我只是打开并保存回来.

namespace InstrumentSystemDll
{
    class Program
    {
        static void Main(string[] args)
        {
            var fileName = args[0];
            var assembly = AssemblyDefinition.ReadAssembly(string.Format(@"..\..\..\Dependences\{0}.dll", fileName));
            Console.WriteLine(string.Format(@"..\..\..\Dependences\{0}.Patched.dll", fileName));
            assembly.Write(string.Format(@"..\..\..\Dependences\{0}.Patched.dll", fileName));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我有一个修改过的"SourceDll.Patched.dll"文件,然后我尝试使用这个文件.创建了一个consloe应用程序并引用了"SourceDll.Patched.dll".

namespace TestInstrumentDll
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Class1.Add(1, 1));
        }
    }
Run Code Online (Sandbox Code Playgroud)

}

不幸的是,我有这样的错误:

未处理的异常:System.IO.FileNotFoundException:无法加载文件或包含'SourceDll,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'或其依赖项之一.该系统找不到指定的文件.在TestInstrumentDll.Program.Main(String [] args)

如果我切换到原始SourceDll.dll,它工作并打印一个数字"2",如我们所料.

Moh*_*han 5

这与Mono.Cecil库无关.这与CLR如何搜索程序集有关.程序集名称将写入程序集的元数据中,CLR将查找元数据以查找程序集.您只需将程序集重命名SourceDLL.dllSourceDLL2.dll,然后引用重命名的assebmly(Mono.Cecil不参与!)即可轻松测试它.你可以看到你会得到完全相同的异常.

要使其工作,您需要在编写之前更改程序集名称:

var assembly = AssemblyDefinition.ReadAssembly(assemblyPath));
assembly.Name.Name += ".Patched";
assembly.Write(assemblyPath.Replace(".dll", ".Patched.dll"));
Run Code Online (Sandbox Code Playgroud)