2

为了重现问题,我创建了这样一个简单的类,这个文件将被编译为“SourceDLL.dll”。

namespace SourceDll
{
    public class Class1
    {
        static public int Add(int b, int c)
        {
            return b + c;
        }
    }
}

然后我用 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));
        }
    }
}

我得到了一个修改过的“SourceDll.Patched.dll”文件,然后我尝试使用这个文件。创建了一个控制台应用程序并引用“SourceDll.Patched.dll”。

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

}

不幸的是,我收到了这样的错误:

未处理的异常:System.IO.FileNotFoundException:无法加载文件或汇编程序“SourceDll,版本=1.0.0.0,文化=中性,PublicKeyToken=null”或其依赖项之一。该系统找不到指定的文件。在 TestInstrumentDll.Program.Main(String[] args)

如果我切换到原始 SourceDll.dll,它可以正常工作并按预期打印数字“2”。

4

1 回答 1

5

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

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

var assembly = AssemblyDefinition.ReadAssembly(assemblyPath));
assembly.Name.Name += ".Patched";
assembly.Write(assemblyPath.Replace(".dll", ".Patched.dll"));
于 2013-03-04T14:46:15.503 回答