我正在尝试使用dnlib项目的de4dot库来加载程序集并获取包含在“body”上的 IL 指令所有的方法。
我已经编译了这个 VB.NET 来源:
Public Class Main
Public Sub testmethod(ByVal testparameter As String)
MsgBox(testparameter)
End Sub
Public Class Test2
Public Function testfunction(ByVal testparameter As String) As String
Return testparameter
End Function
End Class
End Class
我知道编译器会修改很多东西,但我认为方法名称(在这种情况下)不会被修改,如果我错了请纠正我。
然后我试图用这段代码检索这些方法:
Imports dnlib.DotNet
Imports dnlib.DotNet.Emit
Private Sub Test_Handler() Handles MyBase.Shown
Dim asmResolver As New AssemblyResolver()
Dim modCtx As New ModuleContext(asmResolver)
' All resolved assemblies will also get this same modCtx
asmResolver.DefaultModuleContext = modCtx
' Enable the TypeDef cache for all assemblies that are loaded
' by the assembly resolver. Only enable it if all auto-loaded
' assemblies are read-only.
asmResolver.EnableTypeDefCache = True
Dim Assembly As ModuleDefMD = ModuleDefMD.Load("C:\WindowsApplication.exe")
Assembly.Context = modCtx
' Use the previously created (and shared) context
Assembly.Context.AssemblyResolver.AddToCache(Assembly)
Dim Members As IEnumerable(Of MemberRef) = Assembly.GetMemberRefs
For Each m As MemberRef In Members
If m.IsMethodRef Then
Dim Method As MethodDef = m.ResolveMethod
If Method.HasBody Then
Dim sb As New System.Text.StringBuilder
With sb
.AppendLine(String.Format("Method Name: {0}", Method.FullName))
.AppendLine()
.AppendLine(String.Format("Method Signature: {0}", Method.Signature.ToString))
.AppendLine()
.AppendLine(String.Format("Method Instructions: {0}", Environment.NewLine &
String.Join(Environment.NewLine, Method.Body.Instructions)))
End With
MessageBox.Show(sb.ToString)
End If
End If
Next
End Sub
问题是我见过的这个库的唯一文档是XML文档文件和dnlib站点上的一些非常基本的例子,帮助我编写上面的代码,但我不知道如何解决/检索那些方法因为我没有正确地做到这一点,上面的代码并没有解决我编译的任何方法( testmethod 和 testfunction ),而是它向我展示了很多构造函数(.ctor)和其他方法。
我想要做的只是执行我编译的源代码中包含的所有方法(私有,公共等)的迭代,而不管项目具有的类的数量,也不管包含哪个类获取其指示的具体方法。
答案 0 :(得分:2)
看来你只是在大会中四处寻找,所以你得到的就是AssemblyInfo.vb
中定义的内容。您可能想要做的是迭代Assembly中的Types,然后深入查找为您要查找的成员或属性定义的成员或属性。
此代码应该指向正确的方向:
Dim modDef As ModuleDefMD = ModuleDefMD.Load("C:\Temp\ConsoleApplication1.exe")
For Each t As TypeDef In modDef.GetTypes
'print the Type name
Console.WriteLine(t.Name)
' stupid way to match a Type, but will work for demo purposes
If t.FullName.StartsWith("ConsoleApplication1.Module1") Then
For Each meth As MethodDef In t.Methods
' print the method name
Console.WriteLine(" Method: {0}", meth.Name)
Next
End If
Next
输出如下所示,请注意列出了您的方法。
<Module>
MyApplication
MyComputer
MyProject
MyWebServices
ThreadSafeObjectProvider`1
InternalXmlHelper
RemoveNamespaceAttributesClosure
Module1
Method: Main
Method: testmethod
Test2
Method: .ctor
Method: testfunction
Resources
MySettings
MySettingsProperty