Короткая версия
Как получить числовое значение, связанное с enum из файла *.winmd
при использовании IMetadataImport ?
Хорошим примером является ApplicationHighContrastAdjustment перечисление:
//Windows.UI.Xaml.ApplicationContrastMode (@020000006)
public enum ApplicationHighContrastAdjustment : uint
{
None = 0u,
Auto = 4294967295u
}
Большинство перечислений 0, 1, 2, ...
.Но у этого есть другие значения, определенные на членах перечисления:
Как мне прочитать получить эти UInt32 значения
Примечание : вопрос не должен относиться только к WinRT.Те же интерфейсы используются в мире C # для проверки управляемых сборок .NET.WinRT использует один и тот же формат файла сборки.
Длинная версия
Я использую IMetadataImport
для чтения содержимого *.winmd
(современная версия TLB для приложений WinRT),Но вопрос в равной степени относится и к чтению метаданных об управляемой сборке .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.
Получение информации о enum (Авто, Нет)
Теперь у нас есть читатель.Вместо перечисления типов в сборке я могу перейти к интересному вопросу: 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
возвращает нам трех членов перечисления:
- Windows.UI.Xaml.ApplicationContrastMode (@ 02000006)
- значение __ (@ 04000439, личное)
- Нет (@ 0400043A, общедоступный)
- Авто (@ 0400043B, общедоступный)
Получение информации о каждом значении перечисления
На самом деле мы узнаем их имена (и тот факт, что один является личным) через вызов GetMemberProps :
IMetaDataImporter.GetMemberProps(0x0400043A, ...); //"None"
IMetaDataImporter.GetMemberProps(0x0400043B, ...); //"Auto"
Примечание : GetMemberProps - это вспомогательная функция.От Microsoft:
Это простой вспомогательный метод: если 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 11*
- GetMemberRefProps
Чтение бонусов
- Блоги MSDN: Неуправляемый API метаданных (предварительный PDFверсия старого документа Word, которая, насколько я могу судить, является единственной документацией Microsoft для API метаданных) ( архив )