internal static bool GetFileDependsOnNETStandard()

in src/Tasks/Microsoft.NET.Build.Extensions.Tasks/GetDependsOnNETStandard.net46.cs [23:147]


        internal static bool GetFileDependsOnNETStandard(string filePath)
        {
            // Ported from Microsoft.Build.Tasks.AssemblyInformation
            if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
            {
                // on Unix/Mac (mono) use ReflectionOnlyLoadFrom to examine dependencies
                // known issue: since this doesn't create an isolated app domain this will fail if more than one
                // assembly with the same name is analyzed by this task.  The same issue exists in ResolveAssemblyReferences
                // so we are not attempting to fix it here.
                var assembly = Assembly.ReflectionOnlyLoadFrom(filePath);

                foreach(var referencedAssembly in assembly.GetReferencedAssemblies())
                {
                    if (referencedAssembly.Name.Equals(NetStandardAssemblyName, StringComparison.Ordinal))
                    {
                        return true;
                    }
                }
            }
            else
            {
                // on Windows use CLR's unmanaged metadata API.
                // Create the metadata dispenser and open scope on the source file.
                var filePathAbsolute = Path.GetFullPath(filePath);
                var metadataDispenser = (IMetaDataDispenser)new CorMetaDataDispenser();
                var assemblyImport = (IMetaDataAssemblyImport)metadataDispenser.OpenScope(filePathAbsolute, 0, s_importerGuid);

                var asmRefEnum = IntPtr.Zero;
                var asmRefTokens = new UInt32[16];
                UInt32 fetched;

                var assemblyMD = new ASSEMBLYMETADATA()
                {
                    rpLocale = IntPtr.Zero,
                    cchLocale = 0,
                    rpProcessors = IntPtr.Zero,
                    cProcessors = 0,
                    rOses = IntPtr.Zero,
                    cOses = 0
                };

                // Ensure the enum handle is closed.
                try
                {
                    // Enum chunks of refs in 16-ref blocks until we run out.
                    do
                    {
                        assemblyImport.EnumAssemblyRefs(
                            ref asmRefEnum,
                            asmRefTokens,
                            (uint)asmRefTokens.Length,
                            out fetched);

                        for (uint i = 0; i < fetched; i++)
                        {
                            // Determine the length of the string to contain the name first.
                            IntPtr hashDataPtr, pubKeyPtr;
                            UInt32 hashDataLength, pubKeyBytes, asmNameLength, flags;
                            assemblyImport.GetAssemblyRefProps(
                                asmRefTokens[i],
                                out pubKeyPtr,
                                out pubKeyBytes,
                                null,
                                0,
                                out asmNameLength,
                                ref assemblyMD,
                                out hashDataPtr,
                                out hashDataLength,
                                out flags);

                            // Allocate assembly name buffer.
                            StringBuilder assemblyNameBuffer = new StringBuilder((int)asmNameLength + 1);

                            // Retrieve the assembly reference properties.
                            assemblyImport.GetAssemblyRefProps(
                                asmRefTokens[i],
                                out pubKeyPtr,
                                out pubKeyBytes,
                                assemblyNameBuffer,
                                (uint)assemblyNameBuffer.Capacity,
                                out asmNameLength,
                                ref assemblyMD,
                                out hashDataPtr,
                                out hashDataLength,
                                out flags);

                            var assemblyName = assemblyNameBuffer.ToString();

                            if (assemblyName.Equals(NetStandardAssemblyName, StringComparison.Ordinal))
                            {
                                return true;
                            }

                            if (assemblyName.Equals(SystemRuntimeAssemblyName, StringComparison.Ordinal))
                            {
                                var assemblyVersion = new Version(assemblyMD.usMajorVersion, assemblyMD.usMinorVersion, assemblyMD.usBuildNumber, assemblyMD.usRevisionNumber);

                                if (assemblyVersion >= SystemRuntimeMinVersion)
                                {
                                    return true;
                                }
                            }
                        }
                    } while (fetched > 0);
                }
                finally
                {
                    if (asmRefEnum != IntPtr.Zero)
                    {
                        assemblyImport.CloseEnum(asmRefEnum);
                    }

                    if (assemblyImport != null)
                    {
                        Marshal.ReleaseComObject(assemblyImport);
                    }

                    if (metadataDispenser != null)
                    {
                        Marshal.ReleaseComObject(metadataDispenser);
                    }
                }
            }
            return false;
        }