Skip to content

Instantly share code, notes, and snippets.

@devhawk
Created June 13, 2012 00:03
Show Gist options
  • Select an option

  • Save devhawk/2920919 to your computer and use it in GitHub Desktop.

Select an option

Save devhawk/2920919 to your computer and use it in GitHub Desktop.
Cecil Metadata Resolver for WinRT
class WinRTMetadataResolver : MetadataResolver
{
public WinRTMetadataResolver(IAssemblyResolver resolver)
: base(resolver)
{
}
IDictionary<string, ModuleDefinition> _loadedModules = new Dictionary<string, ModuleDefinition>();
public override TypeDefinition Resolve(TypeReference type)
{
if (type.Scope.MetadataScopeType == MetadataScopeType.AssemblyNameReference && ((AssemblyNameReference)type.Scope).IsWindowsRuntime)
{
var tuple = ResolveTypeName(type.GetElementType().FullName);
var filename = tuple.Item1.ToLowerInvariant();
ModuleDefinition module;
if (_loadedModules.ContainsKey(filename))
{
module = _loadedModules[filename];
}
else
{
module = ModuleDefinition.ReadModule(
filename,
new ReaderParameters { MetadataResolver = this, });
_loadedModules.Add(filename, module);
}
return (TypeDefinition)module.LookupToken((int)tuple.Item2);
}
return base.Resolve(type);
}
//note, this wrapper funtion returns the metadata file name and token
//it immediately releases the importer pointer
static Tuple<string, UInt32> ResolveTypeName(string typename)
{
string path;
object importer = null;
UInt32 token;
try
{
var hr = RoGetMetaDataFile(typename, IntPtr.Zero, out path, out importer, out token);
//TODO: check HR for error
return Tuple.Create(path, token);
}
finally
{
Marshal.ReleaseComObject(importer);
}
}
[DllImport("WinTypes.dll")]
static extern UInt32 RoGetMetaDataFile(
[MarshalAs(UnmanagedType.HString)] string name,
IntPtr metaDataDispenser,
[MarshalAs(UnmanagedType.HString)] out string metaDataFilePath,
[MarshalAs(UnmanagedType.Interface)] out object metaDataImport,
out UInt32 typeDefToken);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment