短縮版
IMetadataImportを使用するときに、ファイルから列挙型に関連付けられた数値を取得するにはどうすればよいですか?*.winmd
良い例は、ApplicationHighContrastAdjustment列挙です。
//Windows.UI.Xaml.ApplicationContrastMode (@020000006)
public enum ApplicationHighContrastAdjustment : uint
{
None = 0u,
Auto = 4294967295u
}
ほとんどの列挙は0, 1, 2, ...
. ただし、これには列挙型メンバーで指定された他の値があります。
- 0
- 4294967295
これらのUInt32値を取得するにはどうすればよいですか
注: この質問は、WinRT だけに当てはまる必要はありません。C# の世界では、.NET マネージ アセンブリを検査するために同じインターフェイスが使用されます。WinRT はたまたま同じアセンブリ ファイル形式を使用しています。
ロングバージョン
(WinRT アプリケーション用の最新バージョンの TLB)IMetadataImport
の内容を読み取るために使用しています。*.winmd
しかし、問題は .NET マネージ アセンブリに関するメタデータの読み取りにも同様に当てはまります。
winmd メタデータ ファイルの読み取りを開始して実行する方法の要約版:
// Create your metadata dispenser:
IMetadataDispsener dispener;
MetaDataGetDispenser(CLSID_CorMetaDataDispenser, IMetaDataDispenser, out dispenser);
//Open the winmd file we want to dump
String filename = "C:\Windows\System32\WinMetadata\Windows.UI.Xaml.winmd";
IMetaDataImport reader; //IMetadataImport2 supports generics
dispenser.OpenScope(filename, ofRead, IMetaDataImport, out reader); //"Import" is used to read metadata. "Emit" is used to write metadata.
列挙型に関する情報の取得 (自動、なし)
これでリーダーができました。アセンブリ内の型を列挙するのではなく、この質問の興味深い型に直接ジャンプできます: 0x02000006
:
//Get metadata for enum Windows.UI.Xaml.ApplicationHighContrastAdjustment
mdToken tokenID = 0x02000006; //Windows.UI.Xaml.ApplicationHighContrastAdjustment
//btw, this is all hypothetical code that is vaguely C#/Java-like.
Pointer enum = null;
mdToken memberID;
int nCount;
while (reader.EnumMembers(ref enum, tokenID, out memberID, 1, out nCount) == S_OK)
{
//out MemberID receives the TokenID of each member of the enumeration
}
reader.CloseEnum(enum);
を呼び出すとEnumMembers
、列挙型の 3 つのメンバーが返されます。
- Windows.UI.Xaml.ApplicationContrastMode (@02000006)
- value__ (@04000439、非公開)
- なし(@0400043A、公開)
- 自動(@0400043B、公開)
各列挙値の情報を取得する
GetMemberPropsを呼び出すことで、実際に名前 (および 1 つが非公開であるという事実) を見つけます。
IMetaDataImporter.GetMemberProps(0x0400043A, ...); //"None"
IMetaDataImporter.GetMemberProps(0x0400043B, ...); //"Auto"
注: GetMemberProps はヘルパー関数です。マイクロソフトから:
これは単純なヘルパー メソッドです。md が MethodDef の場合、GetMethodPropsを呼び出します。mdが FieldDef の場合、 GetFieldPropsを呼び出します。詳細については、これらの他の方法を参照してください。
GetMemberPropsメソッドは、各列挙値に関する情報のホスト全体を返しますが、実際の列挙値は返しません。
| Metadata | @0400043A | @0400043B |
|-------------------|-------------------|-----------------|
| Name | "None" | "Auto" |
| Attributes | 0x00008056 | 0x00008056 |
| Signature | 06 11 A3 95 | 06 11 A3 95 |
| CodeRVA | 0x00000000 | 0x00000000 |
| CPlusTypeFlag | ELEMENT_TYPE_U4 | ELEMENT_TYPE_U4 |
| DefaultValue | (none) | (none) |
列挙型に割り当てられた値を示すメンバー プロパティが見つかりません。他のIMetadataImporterメソッドを見ると、次のようになります。
- IMetdataImporter
- GetMemberProps (GetMemberProps は、型に応じて GetMethodProps または GetFieldProps を呼び出すヘルパーです)
- GetMethodProps
- GetFieldProps
- GetPropertyProps
- GetEventProps
- GetParamProps
- GetInterfaceImplProps
- GetCustomAttributeProps
- GetTypeDefProps
- GetTypeRefProps
- GetScopeProps
- GetPermissionSetProps
- GetModuleRefProps
- GetNestedClassProps
- GetMemberRefProps
- GetMemberProps (GetMemberProps は、型に応じて GetMethodProps または GetFieldProps を呼び出すヘルパーです)
ボーナスリーディング
- MSDN ブログ: Metadata Unmanaged API (私の知る限り、Metadata API に関する唯一の Microsoft ドキュメントである古い Word ドキュメントの予備 PDF バージョン) (アーカイブ)