mirror of
https://github.com/aphrody-labs/NuGet.Client.git
synced 2026-10-14 13:29:05 +00:00
78 lines
3.3 KiB
C#
78 lines
3.3 KiB
C#
// Copyright (c) .NET Foundation. All rights reserved.
|
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
|
|
#nullable disable
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Reflection.Metadata;
|
|
using System.Reflection.PortableExecutable;
|
|
using NuGet.Frameworks;
|
|
|
|
namespace NuGet.Test.Utility
|
|
{
|
|
internal static class AssemblyReader
|
|
{
|
|
internal static NuGetFramework GetTargetFramework(string assemblyPath)
|
|
{
|
|
using (var fileStream = File.OpenRead(assemblyPath))
|
|
using (var peReader = new PEReader(fileStream))
|
|
{
|
|
var metadataReader = peReader.GetMetadataReader();
|
|
var targetFrameworkAttribute = GetTargetFrameworkAttribute(metadataReader);
|
|
var targetFrameworkString = GetTargetFrameworkString(targetFrameworkAttribute, metadataReader);
|
|
var targetFramework = NuGetFramework.Parse(targetFrameworkString);
|
|
return targetFramework;
|
|
}
|
|
}
|
|
|
|
private static CustomAttribute GetTargetFrameworkAttribute(MetadataReader metadataReader)
|
|
{
|
|
foreach (CustomAttributeHandle customAttributeHandle in metadataReader.CustomAttributes)
|
|
{
|
|
CustomAttribute customAttribute = metadataReader.GetCustomAttribute(customAttributeHandle);
|
|
|
|
if (customAttribute.Constructor.Kind == HandleKind.MemberReference)
|
|
{
|
|
MemberReference memberReference = metadataReader.GetMemberReference((MemberReferenceHandle)customAttribute.Constructor);
|
|
string name = GetMemberName(memberReference, metadataReader);
|
|
|
|
if (name == "System.Runtime.Versioning.TargetFrameworkAttribute..ctor")
|
|
{
|
|
return customAttribute;
|
|
}
|
|
}
|
|
}
|
|
|
|
throw new Exception("Assembly doesn't have a TargetFrameworkAttribute");
|
|
}
|
|
|
|
private static string GetMemberName(MemberReference memberReference, MetadataReader metadataReader)
|
|
{
|
|
if (memberReference.Parent.Kind != HandleKind.TypeReference)
|
|
{
|
|
throw new NotSupportedException("Didn't expect member reference parent to be of kind " + memberReference.Parent.Kind);
|
|
}
|
|
|
|
var typeReference = metadataReader.GetTypeReference((TypeReferenceHandle)memberReference.Parent);
|
|
|
|
var memberName = metadataReader.GetString(memberReference.Name);
|
|
var typeName = metadataReader.GetString(typeReference.Name);
|
|
var namespaceName = metadataReader.GetString(typeReference.Namespace);
|
|
|
|
return namespaceName + "." + typeName + "." + memberName;
|
|
}
|
|
|
|
private static string GetTargetFrameworkString(CustomAttribute targetFrameworkAttribute, MetadataReader metadataReader)
|
|
{
|
|
var blobReader = metadataReader.GetBlobReader(targetFrameworkAttribute.Value);
|
|
|
|
// I'm not sure if this is IL, or just a list of arguments, but the first value is a 16-bit number with the value 1
|
|
blobReader.ReadInt16();
|
|
|
|
// Next is the string passed to the TargetFrameworkAttribute constructor
|
|
return blobReader.ReadSerializedString();
|
|
}
|
|
}
|
|
}
|