//FIXME: the fallback is broken since multiple frameworks can have the same corlib public TargetFrameworkMoniker GetTargetFrameworkForAssembly(TargetRuntime tr, string file) { if (!File.Exists(file)) { return(TargetFrameworkMoniker.UNKNOWN); } var universe = CreateClosedUniverse(); try { IKVM.Reflection.Assembly assembly = universe.LoadFile(file); var att = assembly.CustomAttributes.FirstOrDefault(a => a.AttributeType.FullName == "System.Runtime.Versioning.TargetFrameworkAttribute" ); if (att != null) { if (att.ConstructorArguments.Count == 1) { var v = att.ConstructorArguments[0].Value as string; TargetFrameworkMoniker m; if (v != null && TargetFrameworkMoniker.TryParse(v, out m)) { return(m); } } LoggingService.LogError("Invalid TargetFrameworkAttribute in assembly {0}", file); } foreach (var r in assembly.GetReferencedAssemblies()) { if (r.Name == "mscorlib") { TargetFramework compatibleFramework = null; // If there are several frameworks that can run the file, pick one that is installed foreach (TargetFramework tf in GetKnownFrameworks()) { if (tf.GetCorlibVersion() == r.Version.ToString()) { compatibleFramework = tf; if (tr.IsInstalled(tf)) { return(tf.Id); } } } if (compatibleFramework != null) { return(compatibleFramework.Id); } break; } } } catch (Exception ex) { LoggingService.LogError("Error determining target framework for assembly {0}: {1}", file, ex); return(TargetFrameworkMoniker.UNKNOWN); } finally { universe.Dispose(); } LoggingService.LogError("Failed to determine target framework for assembly {0}", file); return(TargetFrameworkMoniker.UNKNOWN); }
//FIXME: the fallback is broken since multiple frameworks can have the same corlib public TargetFrameworkMoniker GetTargetFrameworkForAssembly(TargetRuntime tr, string file) { if (!File.Exists(file)) { return(TargetFrameworkMoniker.UNKNOWN); } try { using (var reader = new PEReader(File.OpenRead(file))) { var mr = reader.GetMetadataReader(); foreach (var customAttributeHandle in mr.GetAssemblyDefinition().GetCustomAttributes()) { var customAttribute = mr.GetCustomAttribute(customAttributeHandle); var ctorHandle = customAttribute.Constructor; if (ctorHandle.Kind != HandleKind.MemberReference) { continue; } var ctor = mr.GetMemberReference((MemberReferenceHandle)ctorHandle); var attrType = mr.GetTypeReference((TypeReferenceHandle)ctor.Parent); var ns = mr.GetString(attrType.Namespace); if (ns != "System.Runtime.Versioning") { continue; } var typeName = mr.GetString(attrType.Name); if (typeName != "TargetFrameworkAttribute") { continue; } var provider = new StringParameterValueTypeProvider(mr, customAttribute.Value); var signature = ctor.DecodeMethodSignature(provider, null); var parameterTypes = signature.ParameterTypes; if (parameterTypes.Length != 1) { continue; } var value = parameterTypes [0]; if (value != null && TargetFrameworkMoniker.TryParse(value, out var m)) { return(m); } LoggingService.LogError("Invalid TargetFrameworkAttribute in assembly {0} - {1}", file, value); } if (tr != null) { foreach (var assemblyReferenceHandle in mr.AssemblyReferences) { var assemblyReference = mr.GetAssemblyReference(assemblyReferenceHandle); var name = mr.GetString(assemblyReference.Name); if (name != "mscorlib") { continue; } TargetFramework compatibleFramework = null; // If there are several frameworks that can run the file, pick one that is installed foreach (TargetFramework tf in GetKnownFrameworks()) { if (tf.GetCorlibVersion() == assemblyReference.Version.ToString()) { compatibleFramework = tf; if (tr.IsInstalled(tf)) { return(tf.Id); } } } if (compatibleFramework != null) { return(compatibleFramework.Id); } break; } } } } catch (Exception ex) { LoggingService.LogError("Error determining target framework for assembly {0}: {1}", file, ex); } return(TargetFrameworkMoniker.UNKNOWN); }