public static LocateAssemblyResult Locate(string assemblyName, bool isBeforeBuild, params SearchLocation[] locations)
        {
            foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies().Where(x => !x.IsDynamic))
            {
                if (assembly.Location.Equals(assemblyName, StringComparison.CurrentCultureIgnoreCase) || assembly.GetName().Name.Equals(assemblyName, StringComparison.CurrentCultureIgnoreCase))
                {
                    return(new LocateAssemblyResult(assembly));
                }
            }

            Assembly entryAssembly = Assembly.GetEntryAssembly();
            ProcessorArchitecture entryArchitecture = entryAssembly.GetName().ProcessorArchitecture;

            try
            {
                ProcessorArchitecture assemblyArchitecture = AssemblyName.GetAssemblyName(assemblyName).ProcessorArchitecture;
                bool isCompatible64 = (entryArchitecture == ProcessorArchitecture.Amd64 || entryArchitecture == ProcessorArchitecture.MSIL) &&
                                      (assemblyArchitecture == ProcessorArchitecture.Amd64 || assemblyArchitecture == ProcessorArchitecture.MSIL);
                bool isCompatible86 = entryArchitecture == ProcessorArchitecture.X86 && assemblyArchitecture == ProcessorArchitecture.X86;
                if (!isCompatible64 && !isCompatible86)
                {
                    return(new LocateAssemblyResult(assemblyArchitecture));
                }
            }
            catch (FileNotFoundException)
            {
                if (isBeforeBuild)
                {
                    return(new LocateAssemblyResult());
                }
                throw;
            }

            try
            {
                SwitchableFramework? assemblyFramework   = null;
                string[]             frameworkFiles      = FileSystem.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll");
                IEnumerable <string> loadedAssemblies    = AppDomain.CurrentDomain.GetAssemblies().Where(x => !x.IsDynamic).Select(x => x.Location);
                PathAssemblyResolver resolver            = new PathAssemblyResolver(loadedAssemblies.Concat(frameworkFiles));
                MetadataLoadContext  metadataLoadContext = new MetadataLoadContext(resolver);

                using (metadataLoadContext)
                {
                    Assembly assemblyData = metadataLoadContext.LoadFromAssemblyPath(assemblyName);
                    IList <CustomAttributeData> customAttributeData = assemblyData.GetCustomAttributesData();

                    foreach (CustomAttributeData attributeData in customAttributeData)
                    {
                        try
                        {
                            assemblyFramework = assemblyFramework ?? attributeData.ConstructorArguments.Select(x => x.Value as string)
                                                .Where(x => x != null)
                                                .Select(TryParseFrameworkName)
                                                .FirstOrDefault()?
                                                .GetSwitchableFramework();
                        }
                        catch
                        {
                            // Some unnecessary attributes can not be read by a assembly with the wrong framework version, so ignore them
                        }
                    }
                    assemblyFramework = assemblyFramework ?? SwitchableFramework.None;
                }

                SwitchableFramework entryFramework = entryAssembly.GetSwitchableFramework();
                if (entryFramework != assemblyFramework && assemblyFramework != SwitchableFramework.None)
                {
                    return(new LocateAssemblyResult(assemblyFramework.Value));
                }
            }
            catch (TypeLoadException exception)
            {
                Logger.Warning($"Could not check framework compatibility, because {exception.TypeName} could not be loaded\n{exception.Message}");
            }
            catch (FileNotFoundException exception)
            {
                Logger.Warning($"Could not check framework compatibility, because an assembly could not be found\n{exception.Message}");
            }
            catch (Exception exception)
            {
                Logger.Warning($"Could not check framework compatibility, because an error occurred\n{exception.Message}");
            }
            NugetAssemblyLocator locator = NugetPackageDependencyLoader.CreateLocator();

            locator.Locations.InsertRange(0, locations);
            Version defaultVersion = typeof(CoreModule).Assembly.GetName().Version;

            return(new LocateAssemblyResult(locator.Locate(assemblyName, defaultVersion)));
        }
        public static string FrameworkName(this SwitchableFramework framework)
        {
            FieldInfo memberInfos = framework.GetType().GetField(framework.ToString());

            return(memberInfos?.GetCustomAttribute <FrameworkNameAttribute>()?.Name);
        }
 public LocateAssemblyResult(SwitchableFramework framework)
 {
     this.Success           = false;
     this.SwitchContext     = true;
     this.SwitchToFramework = framework;
 }
Пример #4
0
 public SwitchContextResult(ProcessorArchitecture?switchToArchitecture, SwitchableFramework switchToFramework)
 {
     this.SwitchToArchitecture = switchToArchitecture;
     this.SwitchToFramework    = switchToFramework;
 }