1 #if !NET_CORE 2 3 using System; 4 using System.Collections.Generic; 5 using System.IO; 6 using Microsoft.Win32; 7 8 namespace Mono.Cecil.Tests { 9 public class WindowsRuntimeAssemblyResolver : DefaultAssemblyResolver { 10 11 readonly Dictionary<string, AssemblyDefinition> assemblies = new Dictionary<string, AssemblyDefinition> (); 12 CreateInstance()13 public static WindowsRuntimeAssemblyResolver CreateInstance () 14 { 15 if (Platform.OnMono) 16 return null; 17 try { 18 return new WindowsRuntimeAssemblyResolver (); 19 } catch { 20 return null; 21 } 22 } 23 Resolve(AssemblyNameReference name)24 public override AssemblyDefinition Resolve (AssemblyNameReference name) 25 { 26 AssemblyDefinition assembly; 27 if (assemblies.TryGetValue(name.Name, out assembly)) 28 return assembly; 29 30 return base.Resolve (name); 31 } 32 WindowsRuntimeAssemblyResolver()33 private WindowsRuntimeAssemblyResolver () 34 { 35 LoadWindowsSdk ("v8.1", "8.1", (installationFolder) => { 36 var fileName = Path.Combine (installationFolder, @"References\CommonConfiguration\Neutral\Annotated\Windows.winmd"); 37 var assembly = AssemblyDefinition.ReadAssembly (fileName); 38 Register (assembly); 39 }); 40 41 LoadWindowsSdk ("v10.0", "10", (installationFolder) => { 42 var referencesFolder = Path.Combine (installationFolder, "References"); 43 var assemblies = Directory.GetFiles (referencesFolder, "*.winmd", SearchOption.AllDirectories); 44 45 foreach (var assemblyPath in assemblies) { 46 var assembly = AssemblyDefinition.ReadAssembly (assemblyPath); 47 Register (assembly); 48 } 49 }); 50 } 51 Register(AssemblyDefinition assembly)52 void Register (AssemblyDefinition assembly) 53 { 54 assemblies [assembly.Name.Name] = assembly; 55 RegisterAssembly (assembly); 56 } 57 Dispose(bool disposing)58 protected override void Dispose (bool disposing) 59 { 60 if (!disposing) 61 return; 62 63 foreach (var assembly in assemblies.Values) 64 assembly.Dispose (); 65 66 base.Dispose (true); 67 } 68 LoadWindowsSdk(string registryVersion, string windowsKitsVersion, Action<string> registerAssembliesCallback)69 void LoadWindowsSdk (string registryVersion, string windowsKitsVersion, Action<string> registerAssembliesCallback) 70 { 71 #if NET_4_0 72 using (var localMachine32Key = RegistryKey.OpenBaseKey (RegistryHive.LocalMachine, RegistryView.Registry32)) { 73 using (var sdkKey = localMachine32Key.OpenSubKey (@"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v" + registryVersion)) { 74 #else 75 { 76 // this will fail on 64-bit process as there's no way (other than pinoke) to read from 32-bit registry view 77 using (var sdkKey = Registry.LocalMachine.OpenSubKey (@"SOFTWARE\Microsoft\Microsoft SDKs\Windows\" + registryVersion)) { 78 #endif 79 string installationFolder = null; 80 if (sdkKey != null) 81 installationFolder = (string)sdkKey.GetValue ("InstallationFolder"); 82 if (string.IsNullOrEmpty (installationFolder)) { 83 #if NET_4_0 84 var programFilesX86 = Environment.GetFolderPath (Environment.SpecialFolder.ProgramFilesX86); 85 #else 86 var programFilesX86 = Environment.GetEnvironmentVariable ("ProgramFiles(x86)"); 87 #endif 88 installationFolder = Path.Combine (programFilesX86, @"Windows Kits\" + windowsKitsVersion); 89 } 90 registerAssembliesCallback (installationFolder); 91 } 92 } 93 } 94 } 95 } 96 #endif