При использовании Reflection.Emit
для сборки сборки во время выполнения я хотел бы проверить сборку MSIL перед сохранением на диск. Как PEVerify, но во время выполнения. Есть ли такой API?
Существует ли API для проверки MSIL динамической сборки во время выполнения?
Ответ 1
Похоже, что 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. Вы можете найти экспортированные функции из этой DLL, используя что-то вроде Dependency Walker, но я думаю, что было бы проще просто вызвать peverify. ехе.
EDIT: анекдотические доказательства:
- На этапе компиляции Boo на самом деле вызывает peverify.exe.
- Nemerle вызывает peverify.exe в своих тестах.
- Замок .DynamicProxy вызывает peverify.exe в своих тестах.
Ответ 2
Вместо использования PEVerify вы можете использовать декомпилятор ILSpy для решения in-process, как описано здесь: http://www.codeproject.com/Tips/659692/Automated-MSIL-PE-verification-using-ILSpy
Резюме статьи:
- Соберите соответствующие DLL для ссылки из вашего тестового проекта или runtime IL checker в этом случае
- Итерации с помощью методов проверки с помощью Mono.Cecil
- Для каждого метода добавьте его в AstBuilder, определенный в ICSharpCode.Decompiler, который выполняет проверку. Например.
var context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType };
var astBuilder = new AstBuilder(context);
astBuilder.AddMethod(method);
По производительности я не проверял, какой метод выполняется быстрее. Хотя этот метод является in-proc, он может быть медленнее, поскольку абстрактное дерево синтаксиса построено по мере того, как IL проверяется (мне нужно будет настроить тест производительности, чтобы проверить эту теорию).
Я нашел декомпилятор ILSpy более надежным, чем PEVerify, как указано в этой статье, в одном экземпляре PEVerify объявила, что одна сборка действительна, тогда как ILSpy правильно дал красивую трассировку стека, указывающую мою ошибку в генерации.
Ответ 3
Отладка LCG позволяет отлаживать сгенерированный код во время выполнения с помощью Windbg.
Может быть, это может вам помочь.
Ответ 4
Вызов peverify действительно, вероятно, лучший подход, но peverify находится во многих разных каталогах в зависимости от текущей версии .NET. Вы можете попытаться перечислить все эти пути и проверить последнюю версию, но это было по крайней мере 6 разных путей в последнем счете IIRC и не является межплатформенным, т.е. не включает Mono.
Недавно я обнаружил, что могу просто ссылаться на сборку Microsoft.Build.Tasks, а затем создать экземпляр Microsoft.Build.Tasks.GetFrameworkSdkPath и позвонить свойство Path. Одно странное поведение, которое я заметил, это то, что доступ к первому пути вызывает исключение, но если вы просто проглотите это исключение, вы можете получить доступ к этому пути с этого момента.
Peverify.exe - это Path.Combine(новый GetFrameworkSdkPath(). Путь, "bin\peverify" ).