15

当使用Reflection.Emit在运行时构建程序集时,我想在保存到光盘之前验证程序集 MSIL。像PEVerify但在运行时。有这样的API吗?

4

4 回答 4

8

peverify.exe 似乎是 c:\Windows\Microsoft.NET\Framework\v4.0.30319\peverify.dll (或 c:\Windows\Microsoft.NET\Framework\v2.0.50727\peverify.dll对于CLR 2.0),这是一个原生DLL(实际上peverify.exe也是原生的)

我没有在任何地方看到此文档,因此它可能不是公共 API。您可以使用Dependency Walker之类的东西从该 DLL 中找出导出的函数,但我认为只调用 peverify.exe 会更简单。

编辑:轶事证据:

于 2011-10-05T03:14:35.983 回答
2

除了使用 PEVerify,您还可以使用 ILSpy 的反编译器作为进程内解决方案,如下所述:http: //www.codeproject.com/Tips/659692/Automated-MSIL-PE-verification-using-ILSpy

文章摘要如下:

  1. 收集相关 DLL 以从您的测试项目中引用,或者在这种情况下从运行时 IL 检查器中引用
  2. 遍历方法以使用 Mono.Cecil 进行验证
  3. 对于每个方法,将其添加到执行验证的 ICSharpCode.Decompiler 中定义的 AstBuilder。例如。
var context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType };
var astBuilder = new AstBuilder(context);
astBuilder.AddMethod(method);

性能方面,我没有检查哪种方法更快。虽然这个方法是进程内的,但它可能会更慢,因为抽象语法树是在验证 IL 时构建的(我必须设置一个性能测试来检查这个理论)。

正如上面文章中所指出的,我发现 ILSpy 反编译器比 PEVerify 更可靠,在一个实例中,PEVerify 声明一个程序集是有效的,而 ILSpy 正确地给出了一个漂亮的堆栈跟踪,表明我的生成错误。

于 2013-09-30T17:44:26.817 回答
0

调用 peverify 确实可能是最好的方法,但 peverify 位于许多不同的目录中,具体取决于 .NET 的运行版本。您可以尝试枚举所有这些路径并检查最新的路径,但在最后一次计数 IIRC 中这至少是 6 条不同的路径,并且不是跨平台的,即。不包括单声道。

我最近发现我可以只链接到 Microsoft.Build.Tasks 程序集,然后创建 Microsoft.Build.Tasks.GetFrameworkSdkPath 的实例并调用 Path 属性。我注意到一个奇怪的行为是第一次访问路径会引发异常,但是如果您只是吞下该异常,则可以从那时起访问该路径。

Peverify.exe 然后是 Path.Combine(new GetFrameworkSdkPath().Path, "bin\peverify")。

于 2012-11-17T16:23:21.453 回答
0

调试 LCG允许您在运行时使用 Windbg 调试生成的代码。

也许它可以帮助你。

于 2011-09-03T03:36:05.950 回答