|
<# |
|
.SYNOPSIS |
|
DLL 内の Class および Enum メンバーを列挙する |
|
|
|
.DESCRIPTION |
|
対象DLLを読み込み、Class や Enum メンバーと、 |
|
その属性(`System.ComponentModel.DescriptionAttribute`)値を列挙します。 |
|
|
|
.PARAMETER Path |
|
対象DLLファイル |
|
|
|
.PARAMETER Html |
|
HTML (Tableタグ) 出力する。 |
|
h1 (namespace), h2 (class/enum), h3 (Method, Property, Field) の見出しも付与されます。 |
|
|
|
#> |
|
using namespace System.Reflection; |
|
using namespace System.Collections.Generic; |
|
using namespace System.ComponentModel; |
|
|
|
[OutputType("MemberItem")] |
|
param( |
|
[Parameter(Mandatory, Position=0)] |
|
[string] $Path |
|
, |
|
[switch] $Html |
|
) |
|
|
|
class MemberItem { |
|
hidden [type] $Parent |
|
[string] $Namespace |
|
[string] $ClassName |
|
[string] $Kind # "Enum", Method, Property or Field |
|
[string] $Type # "Enum", ReturnType or PropertyType |
|
[string] $Name |
|
[string] $Description # ComponentMode.DescriptionAttribute |
|
MemberItem([type] $type, [MemberInfo] $memberInfo) { |
|
$this.Parent = $type |
|
$this.Namespace = $type.Namespace; |
|
$this.ClassName = $type.Name; |
|
$this.Kind = $memberInfo.MemberType; |
|
$this.Description = [MemberItem]::GetDescription($memberInfo); |
|
switch ($memberInfo.MemberType) { |
|
Method { |
|
$method = [MethodInfo]$memberInfo |
|
$params = $method.GetParameters() | ForEach-Object { "{0} {1}" -F [MemberItem]::GetTypeName($_.ParameterType), $_.Name } |
|
$this.Name = "{0}({1})" -f $method.Name, ($params -join ", ") |
|
$this.Type = [MemberItem]::GetTypeName($method.ReturnType) |
|
} |
|
Property { |
|
$prop = [PropertyInfo]$memberInfo |
|
$this.Name = $prop.Name; |
|
$this.Type = [MemberItem]::GetTypeName($prop.PropertyType) |
|
} |
|
Field { |
|
$field = [FieldInfo]$memberInfo |
|
$this.Name = $field.Name; |
|
$this.Type = [MemberItem]::GetTypeName($field.FieldType) |
|
} |
|
} |
|
} |
|
MemberItem([type] $type, [enum] $value) { |
|
$this.Parent = $type; |
|
$this.Namespace = $type.Namespace; |
|
$this.ClassName = $type.Name; |
|
$this.Kind = "Enum" |
|
$this.Type = "Enum" |
|
$this.Name = "{0:g} (0x{0:x})" -f $value; |
|
$this.Description = [MemberItem]::GetDescription($value.GetType().GetField($value.ToString())); |
|
} |
|
static [string] GetDescription([MemberInfo] $memberInfo) { |
|
return $memberInfo.GetCustomAttributes([DescriptionAttribute]).Description |
|
} |
|
static [string] GetTypeName([type] $Type) { |
|
$typeName = $Type.ToString(); |
|
$i = $typeName.IndexOf("``") |
|
if ($i -gt 0) { |
|
$typeName = $typeName.Substring(0, $i) |
|
$genericParams = $Type.GenericTypeArguments | ForEach-Object { [MemberItem]::GetTypeName($_) } |
|
$typeName += ("<{0}>" -F ($genericParams -join ", ")) |
|
} |
|
return $typeName.Substring($Type.Namespace.Length + 1); |
|
} |
|
} |
|
function Get-CustomMember { |
|
param( |
|
[Parameter(Mandatory, Position=0)] |
|
[string] $Path |
|
) |
|
begin { |
|
$libFile = Get-Item -LiteralPath $Path; |
|
$lib = [Assembly]::LoadFile($libFile.FullName); |
|
$flags = [BindingFlags]::Public -bor [BindingFlags]::Instance |
|
} |
|
end { |
|
foreach ($type in $lib.GetTypes()) { |
|
if (-not $type.IsPublic) { continue; } |
|
|
|
if ($type.IsClass) { |
|
foreach ($member in $type.GetMembers($flags)) { |
|
# 別モジュールから継承して得られたメンバーは除外 |
|
if ($member.Module -ne $lib.ManifestModule) { continue; } |
|
# Getter/Setter の場合に true となると思われる IsSpecialName も除外 |
|
if ($member.IsSpecialName) { continue; } |
|
Write-Output ([MemberItem]::new($type, $member)) |
|
} |
|
} elseif ($type.IsEnum) { |
|
foreach ($value in $type.GetEnumValues()) { |
|
# Write-Output ([EnumInfo]::new($type.Namespace, $type.Name, $value)) |
|
Write-Output ([MemberItem]::new($type, $value)) |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
if ($Html) { |
|
Get-CustomMember -Path $Path | Group-Object Namespace | ForEach-Object { |
|
$nsName = $_.Name; |
|
"<h1 id=`"namespace-{0}`">{0}</h1>" -F $nsName; |
|
$_.Group | Group-Object ClassName | ForEach-Object { |
|
$className = $_.Name; |
|
$desc = [MemberItem]::GetDescription($_.Group[0].Parent) |
|
if ($_.Group[0].Kind -eq "Enum") { |
|
"<h2 id=`"{0}.{1}`">Enum: {1}</h2>" -F $nsName, $className |
|
if ($desc) { "<p>{0}</p>" -F $desc } |
|
$_.Group | ConvertTo-Html -Fragment -Property Name,Description |
|
} else { |
|
"<h2 id=`"{0}.{1}`">Class: {1}</h2>" -F $nsName, $className |
|
if ($desc) { "<p>{0}</p>" -F $desc } |
|
$_.Group | Group-Object Kind | ForEach-Object { |
|
"<h3 id=`"{0}.{1}-{2}`">{2}</h2>" -F $nsName, $ClassName, $_.Name; |
|
$_.Group | ConvertTo-Html -Fragment -Property Type,Name,Description |
|
} |
|
} |
|
} |
|
} |
|
} else { |
|
Get-CustomMember -Path $Path |
|
} |