static void WindowsRuntimeMetadata_ReflectionOnlyNamespaceResolve(object sender, NamespaceResolveEventArgs e) { foreach (string s in WindowsRuntimeMetadata.ResolveNamespace(e.NamespaceName, null)) { e.ResolvedAssemblies.Add(Assembly.ReflectionOnlyLoadFrom(s)); } }
static Reflector() { AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += (sender, eventArgs) => Assembly.ReflectionOnlyLoad(eventArgs.Name); WindowsRuntimeMetadata.ReflectionOnlyNamespaceResolve += (sender, eventArgs) => { string path = WindowsRuntimeMetadata.ResolveNamespace(eventArgs.NamespaceName, Enumerable.Empty <string>()) .FirstOrDefault(); if (path == null) { return; } if (!String.IsNullOrEmpty(BaseWindMDDir)) { var newPath = Path.Combine(BaseWindMDDir, System.IO.Path.GetFileName(path)); eventArgs.ResolvedAssemblies.Add(Assembly.ReflectionOnlyLoadFrom(newPath)); } else { eventArgs.ResolvedAssemblies.Add(Assembly.ReflectionOnlyLoadFrom(path)); } }; }
private void WindowsRuntimeMetadata_ReflectionOnlyNamespaceResolve(object sender, NamespaceResolveEventArgs e) { // Create a directory list of paths to use when resolving assemblies List <string> dirs = new List <string>(); // Add the path to the current assembly as one possible location dirs.Add(Path.GetDirectoryName(_assemblyFile)); // Add non-empty reference directories as well if (_config.ReferenceDirectories != null) { string[] splitDirs = _config.ReferenceDirectories.Split(';'); foreach (var d in splitDirs) { if (!string.IsNullOrEmpty(d)) { dirs.Add(d); } } } // Resolve the namespace using the directory list. Unfortunately the system root usually overrides the passed folder. Log.Verbose("Resolving namespace '{0}' in assemblies located at '{1}'", e.NamespaceName, string.Join(";", dirs)); IEnumerable <string> foundAssemblies = WindowsRuntimeMetadata.ResolveNamespace(e.NamespaceName, dirs); foreach (var assemblyName in foundAssemblies) { Log.Verbose(@"Found namespace '{0}' in assembly '{1}'", e.NamespaceName, assemblyName); } string path = foundAssemblies.FirstOrDefault(); if (path == null) { return; } // HACK: Because the system path will override any local paths during resolution, go ahead and add // all .winmd files discovered. foreach (var assemblyPath in dirs) { var localAssemblies = Directory.GetFiles(assemblyPath, "*.winmd"); foreach (var localAssembly in localAssemblies) { if (localAssembly != e.RequestingAssembly.Location) { e.ResolvedAssemblies.Add(Assembly.ReflectionOnlyLoadFrom(localAssembly)); } } } // Finally add the path that was originally found in the earlier lookup. var assembly = Assembly.ReflectionOnlyLoadFrom(path); if (!e.ResolvedAssemblies.Contains(assembly)) { e.ResolvedAssemblies.Add(assembly); } }
private static void WindowsRuntimeMetadata_ReflectionOnlyNamespaceResolve(object sender, NamespaceResolveEventArgs e) { string path = WindowsRuntimeMetadata.ResolveNamespace(e.NamespaceName, Enumerable.Empty <string>()) .FirstOrDefault(); e.ResolvedAssemblies.Add(Assembly.ReflectionOnlyLoadFrom(path)); }
/// <summary> /// Event handler for windows winmd resolution. /// </summary> /// <param name="sender"> The sender App Domain. </param> /// <param name="args"> The args. </param> private void WindowsRuntimeMetadataReflectionOnlyNamespaceResolve(object sender, NamespaceResolveEventArgs args) { // Note: This will throw on pre-Win8 OS versions IEnumerable <string> fileNames = WindowsRuntimeMetadata.ResolveNamespace( args.NamespaceName, null, // Will use OS installed .winmd files, you can pass explicit Windows SDK path here for searching 1st party WinRT types this.searchDirectories); // You can pass package graph paths, they will be used for searching .winmd files with 3rd party WinRT types foreach (string fileName in fileNames) { args.ResolvedAssemblies.Add(Assembly.ReflectionOnlyLoadFrom(fileName)); } }
/// <summary> /// Return MetadataReferences to the .winmd assemblies /// for the given namespaces. /// </summary> internal static ImmutableArray <MetadataReference> GetRuntimeWinMds(params string[] namespaces) { var paths = new HashSet <string>(); foreach (var @namespace in namespaces) { foreach (var path in WindowsRuntimeMetadata.ResolveNamespace(@namespace, null)) { paths.Add(path); } } return(ImmutableArray.CreateRange(paths.Select(GetAssembly))); }
static WinMDRegistrationInfo() { if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Win64) { AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += (Sender, EventArgs) => Assembly.ReflectionOnlyLoad(EventArgs.Name); WindowsRuntimeMetadata.ReflectionOnlyNamespaceResolve += (Sender, EventArgs) => { string Path = WindowsRuntimeMetadata.ResolveNamespace(EventArgs.NamespaceName, ResolveSearchPaths).FirstOrDefault(); if (Path == null) { return; } EventArgs.ResolvedAssemblies.Add(Assembly.ReflectionOnlyLoadFrom(Path)); }; } }
public static void Main(string[] args) { string min = null; string max = null; foreach (var arg in args) { if (arg.StartsWith("/min:")) { min = arg.Replace("/min:", string.Empty); } else if (arg.StartsWith("/max:")) { max = arg.Replace("/max:", string.Empty); } } Version.TryParse(min, out Version minVersion); Version.TryParse(max, out Version maxVersion); if (minVersion == null || maxVersion == null) { Console.WriteLine("The differences generator needs to be run as follows:"); Console.WriteLine("DifferencesGen /min:4.0.0.0 /max:5.0.0.0"); return; } string folderPath = @"C:\Program Files (x86)\Windows Kits\10\References"; string universalApiFile = "Windows.Foundation.UniversalApiContract.winmd"; string universalApiDifferencesCompressedFile = "Differences-{0}.gz"; AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += (sender, eventArgs) => Assembly.ReflectionOnlyLoad(eventArgs.Name); WindowsRuntimeMetadata.ReflectionOnlyNamespaceResolve += (sender, eventArgs) => { string path = WindowsRuntimeMetadata.ResolveNamespace(eventArgs.NamespaceName, Enumerable.Empty <string>()) .FirstOrDefault(); if (path == null) { return; } eventArgs.ResolvedAssemblies.Add(Assembly.ReflectionOnlyLoadFrom(path)); }; DirectoryInfo directoryInfo = new DirectoryInfo(folderPath); FileInfo[] files = directoryInfo.GetFiles(universalApiFile, SearchOption.AllDirectories); List <Tuple <Version, Assembly> > assemblyList = new List <Tuple <Version, Assembly> >(); if (files.Length > 0) { foreach (var file in files) { var assembly = Assembly.ReflectionOnlyLoadFrom(file.FullName); var nameParts = assembly.FullName.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries); var versionParts = nameParts[1].Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); var version = Version.Parse(versionParts[1]); if (version >= minVersion && version <= maxVersion) { assemblyList.Add(new Tuple <Version, Assembly>(version, assembly)); } } } if (assemblyList.Count >= 2) { var orderedList = assemblyList.OrderBy(t => t.Item1).ToList(); for (int i = 1; i < orderedList.Count; i++) { var previousVersionAssembly = orderedList[i - 1].Item2; var newerVersionAssembly = orderedList[i].Item2; var version = orderedList[i].Item1; var previousVersionTypes = ProcessAssembly(previousVersionAssembly); var newerVersionTypes = ProcessAssembly(newerVersionAssembly); var addedTypes = new Dictionary <string, List <string> >(); foreach (var type in newerVersionTypes) { if (!previousVersionTypes.ContainsKey(type.Key)) { addedTypes.Add(type.Key, null); if (enumTypes.Contains(type.Key)) { System.Diagnostics.Debug.WriteLine($"New enum {type.Key}"); } continue; } HashSet <string> previousVersionTypeMembers = new HashSet <string>(previousVersionTypes[type.Key]); HashSet <string> newerVersionTypeMembers = new HashSet <string>(type.Value); newerVersionTypeMembers.ExceptWith(previousVersionTypeMembers); if (newerVersionTypeMembers.Count == 0) { continue; } if (enumTypes.Contains(type.Key)) { System.Diagnostics.Debug.WriteLine($"Enum {type.Key} has new members: {string.Join(",", newerVersionTypeMembers)}"); } foreach (var member in newerVersionTypeMembers) { if (typeEvents.Contains($"{type.Key}-{member}")) { System.Diagnostics.Debug.WriteLine($"Type {type.Key} has new event: {member}"); } } addedTypes.Add(type.Key, newerVersionTypeMembers.ToList()); } StringBuilder stringBuilder = new StringBuilder(); using (var compressedFS = File.Create(Path.Combine(AssemblyDirectory, string.Format(universalApiDifferencesCompressedFile, version.ToString())))) { using (var compressionFS = new GZipStream(compressedFS, CompressionMode.Compress)) { using (var writer = new StreamWriter(compressionFS)) { foreach (var addedType in addedTypes) { stringBuilder.Clear(); stringBuilder.Append(addedType.Key); if (addedType.Value != null && addedType.Value.Count > 0) { stringBuilder.Append(':'); stringBuilder.Append(string.Join(",", addedType.Value)); } writer.WriteLine(stringBuilder.ToString()); } } } } stringBuilder.Length = 0; } } }
public void Load() { // When loading for reflection only, it's impossible to get certain things like enum values. // So this IL disassembly is used as a supplement to the reflection. string ildasmPath; string ildasmArgs; if (Utils.IsRunningOnMacOS) { ildasmPath = "ikdasm"; ildasmArgs = "\"" + this.AssemblyFilePath + "\""; } else { ildasmPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) + @"\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\ildasm.exe"; if (!File.Exists(ildasmPath)) { throw new FileNotFoundException("ILDASM tool not found at: " + ildasmPath); } ildasmArgs = "/TEXT \"" + this.AssemblyFilePath + "\""; } StringWriter ilWriter = new StringWriter(); Utils.Execute( ildasmPath, ildasmArgs, Environment.CurrentDirectory, TimeSpan.FromSeconds(10), line => ilWriter.WriteLine(line)); try { this.AssemblyIl = ilWriter.ToString(); List <System.Reflection.Assembly> referenceAssemblies = new List <System.Reflection.Assembly>(); foreach (string referenceAssemblyPath in this.ReferenceAssemblyPaths) { var referenceAssembly = System.Reflection.Assembly.ReflectionOnlyLoadFrom(referenceAssemblyPath); referenceAssemblies.Add(referenceAssembly); Log.Verbose(" Referencing " + referenceAssembly.FullName + " from " + referenceAssemblyPath); } AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += (sender, e) => { System.Reflection.Assembly referenceAssembly = referenceAssemblies.SingleOrDefault(a => a.FullName == e.Name); if (referenceAssembly == null) { throw new TypeLoadException("Reference assembly not provided: " + e.Name); } return(referenceAssembly); }; string[] winrtSearchPaths = this.ReferenceAssemblyPaths.Select(p => Path.GetDirectoryName(p)).ToArray(); WindowsRuntimeMetadata.ReflectionOnlyNamespaceResolve += (sender, e) => { string path = WindowsRuntimeMetadata.ResolveNamespace(e.NamespaceName, winrtSearchPaths).FirstOrDefault(); if (path != null) { e.ResolvedAssemblies.Add(System.Reflection.Assembly.ReflectionOnlyLoadFrom(path)); } }; var refAssembly = System.Reflection.Assembly.ReflectionOnlyLoadFrom(this.AssemblyFilePath); Assembly assembly = new Assembly { Name = refAssembly.GetName().Name, Version = refAssembly.GetName().Version, CodeBase = refAssembly.CodeBase, Types = new List <Type>(), }; LoadTypes(refAssembly, assembly, this.IncludeNamespaces); this.LoadedAssembly = assembly; } catch (Exception ex) { // Don't let any exceptions leak through the cross-app-domain call, // because they might include non-serializable types. Instead, just // report the exception as text. this.Exception = ex.ToString(); } }