예제 #1
0
        LoadedAssembly LookupReferencedAssemblyInternal(Decompiler.Metadata.IAssemblyReference fullName, bool isWinRT)
        {
            string GetName(Decompiler.Metadata.IAssemblyReference name) => isWinRT ? name.Name : name.FullName;

            string         file;
            LoadedAssembly asm;

            lock (loadingAssemblies) {
                foreach (LoadedAssembly loaded in assemblyList.GetAssemblies())
                {
                    var reader = loaded.GetPEFileOrNull()?.Metadata;
                    if (reader == null || !reader.IsAssembly)
                    {
                        continue;
                    }
                    var asmDef     = reader.GetAssemblyDefinition();
                    var asmDefName = isWinRT ? reader.GetString(asmDef.Name) : reader.GetFullAssemblyName();
                    if (GetName(fullName).Equals(asmDefName, StringComparison.OrdinalIgnoreCase))
                    {
                        LoadedAssemblyReferencesInfo.AddMessageOnce(fullName.FullName, MessageKind.Info, "Success - Found in Assembly List");
                        return(loaded);
                    }
                }

                var resolver = new MyUniversalResolver(this);
                file = resolver.FindAssemblyFile(fullName);

                foreach (LoadedAssembly loaded in assemblyList.GetAssemblies())
                {
                    if (loaded.FileName.Equals(file, StringComparison.OrdinalIgnoreCase))
                    {
                        return(loaded);
                    }
                }

                if (file != null && loadingAssemblies.TryGetValue(file, out asm))
                {
                    return(asm);
                }

                if (assemblyLoadDisableCount > 0)
                {
                    return(null);
                }

                if (file != null)
                {
                    LoadedAssemblyReferencesInfo.AddMessage(fullName.ToString(), MessageKind.Info, "Success - Loading from: " + file);
                    asm = new LoadedAssembly(assemblyList, file)
                    {
                        IsAutoLoaded = true
                    };
                }
                else
                {
                    LoadedAssemblyReferencesInfo.AddMessageOnce(fullName.ToString(), MessageKind.Error, "Could not find reference: " + fullName);
                    return(null);
                }
                loadingAssemblies.Add(file, asm);
            }
            App.Current.Dispatcher.BeginInvoke((Action) delegate() {
                lock (assemblyList.assemblies) {
                    assemblyList.assemblies.Add(asm);
                }
                lock (loadingAssemblies) {
                    loadingAssemblies.Remove(file);
                }
            });
            return(asm);
        }
예제 #2
0
        /// <summary>
        /// 1) try to find exact match by tfm + full asm name in loaded assemblies
        /// 2) try to find match in search paths
        /// 3) if a.deps.json is found: search %USERPROFILE%/.nuget/packages/* as well
        /// 4) look in /dotnet/shared/{runtime-pack}/{closest-version}
        /// 5) if the version is retargetable or all zeros or ones, search C:\Windows\Microsoft.NET\Framework64\v4.0.30319
        /// 6) For "mscorlib.dll" we use the exact same assembly with which ILSpy runs
        /// 7) Search the GAC
        /// 8) search C:\Windows\Microsoft.NET\Framework64\v4.0.30319
        /// 9) try to find match by asm name (no tfm/version) in loaded assemblies
        /// </summary>
        LoadedAssembly LookupReferencedAssemblyInternal(IAssemblyReference fullName, bool isWinRT, string tfm)
        {
            string key = tfm + ";" + (isWinRT ? fullName.Name : fullName.FullName);

            string         file;
            LoadedAssembly asm;

            lock (loadingAssemblies)
            {
                foreach (LoadedAssembly loaded in assemblyList.GetAssemblies())
                {
                    var module = loaded.GetPEFileOrNull();
                    var reader = module?.Metadata;
                    if (reader == null || !reader.IsAssembly)
                    {
                        continue;
                    }
                    var asmDef     = reader.GetAssemblyDefinition();
                    var asmDefName = loaded.GetTargetFrameworkIdAsync().Result + ";" + (isWinRT ? reader.GetString(asmDef.Name) : reader.GetFullAssemblyName());
                    if (key.Equals(asmDefName, StringComparison.OrdinalIgnoreCase))
                    {
                        LoadedAssemblyReferencesInfo.AddMessageOnce(fullName.FullName, MessageKind.Info, "Success - Found in Assembly List");
                        return(loaded);
                    }
                }

                if (universalResolver == null)
                {
                    universalResolver = new MyUniversalResolver(this);
                }

                file = universalResolver.FindAssemblyFile(fullName);

                foreach (LoadedAssembly loaded in assemblyList.GetAssemblies())
                {
                    if (loaded.FileName.Equals(file, StringComparison.OrdinalIgnoreCase))
                    {
                        return(loaded);
                    }
                }

                if (file != null && loadingAssemblies.TryGetValue(file, out asm))
                {
                    return(asm);
                }

                if (assemblyLoadDisableCount > 0)
                {
                    return(null);
                }

                if (file != null)
                {
                    LoadedAssemblyReferencesInfo.AddMessage(fullName.ToString(), MessageKind.Info, "Success - Loading from: " + file);
                    asm = new LoadedAssembly(assemblyList, file)
                    {
                        IsAutoLoaded = true
                    };
                }
                else
                {
                    var candidates = new List <(LoadedAssembly assembly, Version version)>();

                    foreach (LoadedAssembly loaded in assemblyList.GetAssemblies())
                    {
                        var module = loaded.GetPEFileOrNull();
                        var reader = module?.Metadata;
                        if (reader == null || !reader.IsAssembly)
                        {
                            continue;
                        }
                        var asmDef     = reader.GetAssemblyDefinition();
                        var asmDefName = reader.GetString(asmDef.Name);
                        if (fullName.Name.Equals(asmDefName, StringComparison.OrdinalIgnoreCase))
                        {
                            candidates.Add((loaded, asmDef.Version));
                        }
                    }

                    if (candidates.Count == 0)
                    {
                        LoadedAssemblyReferencesInfo.AddMessageOnce(fullName.ToString(), MessageKind.Error, "Could not find reference: " + fullName);
                        return(null);
                    }

                    candidates.SortBy(c => c.version);

                    var bestCandidate = candidates.FirstOrDefault(c => c.version >= fullName.Version).assembly ?? candidates.Last().assembly;
                    LoadedAssemblyReferencesInfo.AddMessageOnce(fullName.ToString(), MessageKind.Info, "Success - Found in Assembly List with different TFM or version: " + bestCandidate.fileName);
                    return(bestCandidate);
                }
                loadingAssemblies.Add(file, asm);
            }
            App.Current.Dispatcher.BeginInvoke((Action) delegate() {
                lock (assemblyList.assemblies)
                {
                    assemblyList.assemblies.Add(asm);
                }
                lock (loadingAssemblies)
                {
                    loadingAssemblies.Remove(file);
                }
            }, DispatcherPriority.Normal);
            return(asm);
        }
예제 #3
0
        private LoadedAssembly LookupReferencedAssemblyInternal(AssemblyNameReference fullName, bool isWinRT)
        {
            string GetName(AssemblyNameReference name) => isWinRT ? name.Name : name.FullName;

            string         file;
            LoadedAssembly asm;

            lock (loadingAssemblies) {
                foreach (LoadedAssembly loaded in assemblyList.GetAssemblies())
                {
                    var asmDef = loaded.GetAssemblyDefinitionOrNull();
                    if (asmDef != null && GetName(fullName).Equals(GetName(asmDef.Name), StringComparison.OrdinalIgnoreCase))
                    {
                        LoadedAssemblyReferencesInfo.AddMessageOnce(fullName.ToString(), MessageKind.Info, "Success - Found in Assembly List");
                        return(loaded);
                    }
                }

                if (isWinRT)
                {
                    file = Path.Combine(Environment.SystemDirectory, "WinMetadata", fullName.Name + ".winmd");
                }
                else
                {
                    var resolver = new MyUniversalResolver(this)
                    {
                        TargetFramework = GetTargetFrameworkIdAsync().Result
                    };
                    file = resolver.FindAssemblyFile(fullName);
                }

                foreach (LoadedAssembly loaded in assemblyList.GetAssemblies())
                {
                    if (loaded.FileName.Equals(file, StringComparison.OrdinalIgnoreCase))
                    {
                        return(loaded);
                    }
                }

                if (file != null && loadingAssemblies.TryGetValue(file, out asm))
                {
                    return(asm);
                }

                if (assemblyLoadDisableCount > 0)
                {
                    return(null);
                }

                if (file != null)
                {
                    LoadedAssemblyReferencesInfo.AddMessage(fullName.ToString(), MessageKind.Info, "Success - Loading from: " + file);
                    asm = new LoadedAssembly(assemblyList, file)
                    {
                        IsAutoLoaded = true
                    };
                }
                else
                {
                    LoadedAssemblyReferencesInfo.AddMessageOnce(fullName.ToString(), MessageKind.Error, "Could not find reference: " + fullName);
                    return(null);
                }
                loadingAssemblies.Add(file, asm);
            }
            App.Current.Dispatcher.BeginInvoke((Action) delegate() {
                lock (assemblyList.assemblies) {
                    assemblyList.assemblies.Add(asm);
                }
                lock (loadingAssemblies) {
                    loadingAssemblies.Remove(file);
                }
            });
            return(asm);
        }