为了重新产生问题,我创建了这样一个简单的类,这个文件将被编译为“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”文件,然后我尝试使用这个文件。创建了一个consloe应用程序并引用了“SourceDll.Patched.dll”。
namespace TestInstrumentDll
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Class1.Add(1, 1));
}
}
}
不幸的是,我收到了这样的错误:
未处理的异常:System.IO.FileNotFoundException:无法加载文件或屁股 embly'SourceDll,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'或者one 它的依赖关系。该系统找不到指定的文件。 在TestInstrumentDll.Program.Main(String [] args)
如果我切换到原始的SourceDll.dll,它会工作并打印一个数字“2”,如我们所料。
答案 0 :(得分:5)
这与Mono.Cecil库无关。这与CLR如何搜索程序集有关。程序集名称将写入程序集的元数据中,CLR将查找元数据以查找程序集。您可以通过将程序集从SourceDLL.dll
重命名为SourceDLL2.dll
然后引用重命名的assebmly(Mono.Cecil不参与!)来轻松测试它。你可以看到你会得到完全相同的例外。
要使其正常工作,您需要在编写之前更改程序集名称:
var assembly = AssemblyDefinition.ReadAssembly(assemblyPath));
assembly.Name.Name += ".Patched";
assembly.Write(assemblyPath.Replace(".dll", ".Patched.dll"));