# encoding: ascii
# api: powershell
# title: Get-MemberBody
# description: Uses the ILSpy assemblies to decompile .NET assemblies on the fly using a simple PowerShell advanced function. It can be chained together with Get-Member calls.
# version: 2.1.0.1603
# type: function
# author: Adam Driscoll
# license: CC0
# function: Get-MemberBody
# x-poshcode-id: 4126
# x-archived: 2013-05-02T15:09:11
# x-published: 2013-04-23T19:00:00
#
#
#Requires ILSpy.
#Tested with version 2.1.0.1603
#http://ilspy.net/
Add-Type -Path "Mono.Cecil.dll"
Add-Type -Path "ICSharpCode.Decompiler.dll"
[void][System.Reflection.Assembly]::LoadFrom("ILSpy.exe")
function Get-MemberBody
{
[CmdletBinding()]
param(
[Parameter(ParameterSetName="MI")]
[System.Reflection.MemberInfo]$memberInfo,
[Parameter(ParameterSetName="MD",ValueFromPipeline=$true)]
[Microsoft.PowerShell.Commands.MemberDefinition]$memberDefinition)
Process
{
if ($memberDefinition -ne $null)
{
$type = [AppDomain]::CurrentDomain.GetAssemblies().GetTypes() | ? FullName -eq $memberDefinition.TypeName
$declaringTypeName = $type.FullName
$assembly = $type.Assembly.CodeBase.Replace("file:///", "").Replace("/", "\")
$memberName = $memberDefinition.Name
$memberType = $memberDefinition.MemberType
}
else
{
$assembly = $memberInfo.DeclaringType.Assembly.CodeBase.Replace("file:///", "").Replace("/", "\")
$memberName = $memberInfo.Name
$declaringTypeName = $memberInfo.DeclaringType.FullName
}
$AssemblyDefinition = [Mono.Cecil.AssemblyDefinition]::ReadAssembly($assembly)
$Context = New-Object ICSharpCode.Decompiler.DecompilerContext -ArgumentList $AssemblyDefinition.MainModule
$TextOutput = New-Object ICSharpCode.Decompiler.PlainTextOutput
$Opts = New-Object ICSharpCode.ILSpy.DecompilationOptions
$Lang = New-Object ICSharpCode.ILSpy.CSharpLanguage
try
{
if ($memberType -eq "Method")
{
$CecilMethod = $AssemblyDefinition.MainModule.Types | ? FullName -eq $declaringTypeName | Select -ExpandProperty Methods | ? Name -eq $memberName
$Lang.DecompileMethod($CecilMethod,$TextOutput,$Opts)
}
if ($memberType -eq "Property")
{
$CecilMember = $AssemblyDefinition.MainModule.Types | ? FullName -eq $declaringTypeName | Select -ExpandProperty Properties | ? Name -eq $memberName
$Lang.DecompileProperty($CecilMember,$TextOutput,$Opts)
}
if ($memberType -eq "Event")
{
$CecilMember = $AssemblyDefinition.MainModule.Types | ? FullName -eq $declaringTypeName | Select -ExpandProperty Events | ? Name -eq $memberName
$Lang.DecompileEvent($CecilMember,$TextOutput,$Opts)
}
if ($memberType -eq "Field")
{
$CecilMember = $AssemblyDefinition.MainModule.Types | ? FullName -eq $declaringTypeName | Select -ExpandProperty Fields | ? Name -eq $memberName
$Lang.DecompileField($CecilMember,$TextOutput,$Opts)
}
}
catch
{
Write-Error (New-Object -TypeName System.Exception -ArgumentList "Failed to decompile $declaringTypeName.$memberName", $Error[0].Exception)
}
$TextOutput.ToString()
}
}