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