Introduction

Last week I found a little bug caused by Anotar. Anotar adds IL code to my assembly. The problem with this bug is that it only manifests itself at runtime or when covered by a test or when doing a PEVerify. Since I don’t claim to have 100% test coverage. I need a way to run PEVErify on my assemblies to make sure I catch any Anotar bugs (So I can report them and Simon can fix them).

When I mentioned this on twitter, the always brilliant Simon Cropp pointed me to his Verifier class that you can find in the sourcecode of Anotar.

The code

And here is my current, slightly reworked version of his code.

```vbnet Imports System Imports System.Diagnostics Imports System.IO Imports NUnit.Framework

Namespace PeVerify Public Class Verifier

    Public Shared Sub Verify(assemblyPath As String, Optional ByVal errorCodesToIgnore As String = "")
        Dim before = Validate(assemblyPath, errorCodesToIgnore)
        Assert.IsTrue(File.Exists(assemblyPath), "Assembly not found: " & assemblyPath)
        Assert.IsFalse(before.Contains("Error"), before)
    End Sub

    Private Shared Function Validate(assemblyPath As String, Optional ByVal errorCodesToIgnore As String = "") As String
        Dim exePath = GetPathToPeVerify()
        If (Not File.Exists(exePath)) Then
            Return String.Empty
        End If
        Dim arguments = String.Format("""{0}""", assemblyPath)
        If Not String.IsNullOrEmpty(errorCodesToIgnore) Then
            arguments = String.Format("{0} /ignore={1}", arguments, errorCodesToIgnore)
        End If
        Dim process1 = Process.Start(New ProcessStartInfo(exePath, arguments) With {.RedirectStandardOutput = True, .UseShellExecute = False, .CreateNoWindow = True})
        process1.WaitForExit(10000)
        Return process1.StandardOutput.ReadToEnd().Trim().Replace(assemblyPath, "")
    End Function

    Private Shared Function GetPathToPeVerify() As String
        Dim exePath = Environment.ExpandEnvironmentVariables("%programfiles(x86)%Microsoft SDKsWindowsv7.0ABinNETFX 4.0 ToolsPEVerify.exe")
        If (Not File.Exists(exePath)) Then
            exePath = Environment.ExpandEnvironmentVariables("%programfiles(x86)%Microsoft SDKsWindowsv8.0ABinNETFX 4.0 ToolsPEVerify.exe")
        End If
        Return exePath
    End Function

End Class

End Namespace``` This does not work on either the ncrunch or resharper testrunner since those use their ownversion of the assembly. But it works on Teamcity, which is the important part for me since I don’t want to let bugs out in the wild.

You can use it like this.

vbnet <Test> Public Sub PeVerifyAssembly() Dim filePath = Assembly.GetAssembly(GetType(SomeTypeInYourAssembly)).Location Verifier.Verify(filePath) End Sub Or in one case where I had an error like this you can just ignore the cannot find file error.

[IL]: Error: [ : TexDatabases2012.Menu.Facade.MessagesFacade::set__newtransfers] [HRESULT 0x80070002] – The system cannot find the file specified. [

vbnet <Test> Public Sub PeVerifyAssembly() Dim filePath = Assembly.GetAssembly(GetType(SomeTypeInYourAssembly)).Location Verifier.Verify(filePath, "0x80070002") End Sub

Conclusion

Adding a PEVerify step when working with software like Fody seems to be a good thing.

And I would also like to thank Simon for his awesome support.