internal void ReadAssemblyResources()

in src/Tasks/GenerateResource.cs [2941:3101]


        internal void ReadAssemblyResources(String name, String outFileOrDir)
        {
            // If something else in the solution failed to build...
            if (!File.Exists(name))
            {
                _logger.LogErrorWithCodeFromResources("GenerateResource.MissingFile", name);
                return;
            }

            Assembly a = null;
            bool mainAssembly = false;
            bool failedLoadingCultureInfo = false;
            NeutralResourcesLanguageAttribute neutralResourcesLanguageAttribute = null;
            AssemblyName assemblyName = null;

            try
            {
                a = Assembly.UnsafeLoadFrom(name);
                assemblyName = a.GetName();

                if (_extractResWFiles)
                {
                    var targetFrameworkAttribute = a.GetCustomAttribute<TargetFrameworkAttribute>();
                    if (
                            targetFrameworkAttribute != null &&
                            (
                                targetFrameworkAttribute.FrameworkName.StartsWith("Silverlight,", StringComparison.OrdinalIgnoreCase) ||
                                targetFrameworkAttribute.FrameworkName.StartsWith("WindowsPhone,", StringComparison.OrdinalIgnoreCase)
                            )
                        )
                    {
                        // Skip Silverlight assemblies.
                        _logger.LogMessageFromResources("GenerateResource.SkippingExtractingFromNonSupportedFramework", name, targetFrameworkAttribute.FrameworkName);
                        return;
                    }

                    _logger.LogMessageFromResources("GenerateResource.ExtractingResWFiles", name, outFileOrDir);
                }

                CultureInfo ci = null;
                try
                {
                    ci = assemblyName.CultureInfo;
                }
                catch (ArgumentException e)
                {
                    _logger.LogWarningWithCodeFromResources(null, name, 0, 0, 0, 0, "GenerateResource.CreatingCultureInfoFailed", e.GetType().Name, e.Message, assemblyName.ToString());
                    failedLoadingCultureInfo = true;
                }

                if (!failedLoadingCultureInfo)
                {
                    mainAssembly = ci.Equals(CultureInfo.InvariantCulture);
                    neutralResourcesLanguageAttribute = CheckAssemblyCultureInfo(name, assemblyName, ci, a, mainAssembly);
                }  // if (!failedLoadingCultureInfo)
            }
            catch (BadImageFormatException)
            {
                // If we're extracting ResW files, this task is being run on all DLL's referred to by the project.
                // That may potentially include C++ libraries & immersive (non-portable) class libraries, which don't have resources.
                // We can't easily filter those.  We can simply skip them.
                return;
            }
            catch (Exception e)
            {
                if (ExceptionHandling.IsCriticalException(e))
                    throw;
                _logger.LogErrorWithCodeFromResources("GenerateResource.CannotLoadAssemblyLoadFromFailed", name, e);
            }

            if (a != null)
            {
                String[] resources = a.GetManifestResourceNames();
                CultureInfo satCulture = null;
                String expectedExt = null;
                if (!failedLoadingCultureInfo)
                {
                    satCulture = assemblyName.CultureInfo;
                    if (!satCulture.Equals(CultureInfo.InvariantCulture))
                        expectedExt = '.' + satCulture.Name + ".resources";
                }

                foreach (String resName in resources)
                {
                    if (!resName.EndsWith(".resources", StringComparison.OrdinalIgnoreCase)) // Skip non-.resources assembly blobs
                        continue;

                    if (mainAssembly)
                    {
                        if (CultureInfo.InvariantCulture.CompareInfo.IsSuffix(resName, ".en-US.resources", CompareOptions.IgnoreCase))
                        {
                            _logger.LogErrorFromResources("GenerateResource.ImproperlyBuiltMainAssembly", resName, name);
                            continue;
                        }

                        if (neutralResourcesLanguageAttribute == null)
                        {
                            _logger.LogWarningWithCodeFromResources(null, name, 0, 0, 0, 0, "GenerateResource.MainAssemblyMissingNeutralResourcesLanguage", name);
                            break;
                        }
                    }
                    else if (!failedLoadingCultureInfo && !CultureInfo.InvariantCulture.CompareInfo.IsSuffix(resName, expectedExt, CompareOptions.IgnoreCase))
                    {
                        _logger.LogErrorFromResources("GenerateResource.ImproperlyBuiltSatelliteAssembly", resName, expectedExt, name);
                        continue;
                    }

                    try
                    {
                        Stream s = a.GetManifestResourceStream(resName);
                        using (IResourceReader rr = new ResourceReader(s))
                        {
                            ReaderInfo reader = new ReaderInfo();
                            if (mainAssembly)
                            {
                                reader.fromNeutralResources = true;
                                reader.assemblySimpleName = assemblyName.Name;
                            }
                            else
                            {
                                Debug.Assert(assemblyName.Name.EndsWith(".resources", StringComparison.OrdinalIgnoreCase));
                                reader.assemblySimpleName = assemblyName.Name.Remove(assemblyName.Name.Length - 10);  // Remove .resources from satellite assembly name
                            }
                            reader.outputFileName = resName.Remove(resName.Length - 10); // Remove the .resources extension
                            if (satCulture != null && !String.IsNullOrEmpty(satCulture.Name))
                            {
                                reader.cultureName = satCulture.Name;
                            }
                            else if (neutralResourcesLanguageAttribute != null && !String.IsNullOrEmpty(neutralResourcesLanguageAttribute.CultureName))
                            {
                                reader.cultureName = neutralResourcesLanguageAttribute.CultureName;
                            }

                            if (reader.cultureName != null)
                            {
                                // Remove the culture from the filename
                                if (reader.outputFileName.EndsWith("." + reader.cultureName, StringComparison.OrdinalIgnoreCase))
                                    reader.outputFileName = reader.outputFileName.Remove(reader.outputFileName.Length - (reader.cultureName.Length + 1));
                            }
                            _readers.Add(reader);

                            foreach (DictionaryEntry pair in rr)
                            {
                                AddResource(reader, (string)pair.Key, pair.Value, resName);
                            }
                        }
                    }
                    catch (FileNotFoundException)
                    {
                        _logger.LogErrorWithCodeFromResources(null, name, 0, 0, 0, 0, "GenerateResource.NoResourcesFileInAssembly", resName);
                    }
                }
            }

            var satelliteAssemblies = _satelliteInFiles.Where(ti => ti.GetMetadata("OriginalItemSpec").Equals(name, StringComparison.OrdinalIgnoreCase));

            foreach (var satelliteAssembly in satelliteAssemblies)
            {
                ReadAssemblyResources(satelliteAssembly.ItemSpec, outFileOrDir);
            }
        }