示例#1
0
 static void WindowsRuntimeMetadata_ReflectionOnlyNamespaceResolve(object sender, NamespaceResolveEventArgs e)
 {
     foreach (string s in WindowsRuntimeMetadata.ResolveNamespace(e.NamespaceName, null))
     {
         e.ResolvedAssemblies.Add(Assembly.ReflectionOnlyLoadFrom(s));
     }
 }
示例#2
0
        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);
            }
        }
示例#4
0
        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));
        }
示例#5
0
        /// <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)));
        }
示例#7
0
 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));
         };
     }
 }
示例#8
0
        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;
                }
            }
        }
示例#9
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();
                }
            }