// constructor used by metadata reader: internal AssemblyIdentity( bool noThrow, string name, Version?version = null, string?cultureName = null, ImmutableArray <byte> publicKeyOrToken = default, bool hasPublicKey = false, bool isRetargetable = false, AssemblyContentType contentType = AssemblyContentType.Default ) { Debug.Assert(name != null); Debug.Assert( (hasPublicKey && MetadataHelpers.IsValidPublicKey(publicKeyOrToken)) || ( !hasPublicKey && ( publicKeyOrToken.IsDefaultOrEmpty || publicKeyOrToken.Length == PublicKeyTokenSize ) ) ); Debug.Assert(noThrow); _name = name; _version = version ?? NullVersion; _cultureName = NormalizeCultureName(cultureName); _contentType = IsValid(contentType) ? contentType : AssemblyContentType.Default; _isRetargetable = isRetargetable && _contentType != AssemblyContentType.WindowsRuntime; InitializeKey(publicKeyOrToken, hasPublicKey, out _publicKey, out _lazyPublicKeyToken); }
// // Converts an AssemblyName to a RuntimeAssemblyName that is free from any future mutations on the AssemblyName. // public static RuntimeAssemblyName ToRuntimeAssemblyName(this AssemblyName assemblyName) { if (assemblyName.Name == null) { throw new ArgumentException(SR.InvalidAssemblyName); } AssemblyNameFlags flags = assemblyName.Flags; AssemblyContentType contentType = assemblyName.ContentType; #pragma warning disable SYSLIB0037 // AssemblyName.ProcessorArchitecture is obsolete ProcessorArchitecture processorArchitecture = assemblyName.ProcessorArchitecture; #pragma warning restore SYSLIB0037 AssemblyNameFlags combinedFlags = CombineAssemblyNameFlags(flags, contentType, processorArchitecture); byte[]? pkOriginal; if (0 != (flags & AssemblyNameFlags.PublicKey)) { pkOriginal = assemblyName.GetPublicKey(); } else { pkOriginal = assemblyName.GetPublicKeyToken(); } // AssemblyName's PKT property getters do NOT copy the array before giving it out. Make our own copy // as the original is wide open to tampering by anyone. byte[]? pkCopy = null; if (pkOriginal != null) { pkCopy = new byte[pkOriginal.Length]; Array.Copy(pkOriginal, pkCopy, pkOriginal.Length); } return(new RuntimeAssemblyName(assemblyName.Name, assemblyName.Version, assemblyName.CultureName, combinedFlags, pkCopy)); }
// asserting constructor used by SourceAssemblySymbol: internal AssemblyIdentity( string name, Version version, string?cultureName, ImmutableArray <byte> publicKeyOrToken, bool hasPublicKey ) { Debug.Assert(name != null); Debug.Assert(IsValid(version)); Debug.Assert(IsValidCultureName(cultureName)); Debug.Assert( (hasPublicKey && MetadataHelpers.IsValidPublicKey(publicKeyOrToken)) || ( !hasPublicKey && ( publicKeyOrToken.IsDefaultOrEmpty || publicKeyOrToken.Length == PublicKeyTokenSize ) ) ); _name = name; _version = version ?? NullVersion; _cultureName = NormalizeCultureName(cultureName); _isRetargetable = false; _contentType = AssemblyContentType.Default; InitializeKey(publicKeyOrToken, hasPublicKey, out _publicKey, out _lazyPublicKeyToken); }
// // Converts an AssemblyName to a RuntimeAssemblyName that is free from any future mutations on the AssemblyName. // public static RuntimeAssemblyName ToRuntimeAssemblyName(this AssemblyName assemblyName) { if (assemblyName.Name == null) { throw new ArgumentException(); } AssemblyNameFlags flags = assemblyName.Flags; AssemblyContentType contentType = assemblyName.ContentType; ProcessorArchitecture processorArchitecture = assemblyName.ProcessorArchitecture; AssemblyNameFlags combinedFlags = CombineAssemblyNameFlags(flags, contentType, processorArchitecture); byte[] pkOriginal; if (0 != (flags & AssemblyNameFlags.PublicKey)) { pkOriginal = assemblyName.GetPublicKey(); } else { pkOriginal = assemblyName.GetPublicKeyToken(); } // AssemblyName's PKT property getters do NOT copy the array before giving it out. Make our own copy // as the original is wide open to tampering by anyone. byte[] pkCopy = null; if (pkOriginal != null) { pkCopy = new byte[pkOriginal.Length]; ((ICollection <byte>)pkOriginal).CopyTo(pkCopy, 0); } return(new RuntimeAssemblyName(assemblyName.Name, assemblyName.Version, assemblyName.CultureName, combinedFlags, pkCopy)); }
public void ContentType(AssemblyContentType contentType) { AssemblyName assemblyName = new AssemblyName("MyAssemblyName"); Assert.Equal(AssemblyContentType.Default, assemblyName.ContentType); assemblyName.ContentType = contentType; Assert.Equal(contentType, assemblyName.ContentType); }
/// <summary> /// Constructs an <see cref="AssemblyIdentity"/> from its constituent parts. /// </summary> /// <param name="name">The simple name of the assembly.</param> /// <param name="version">The version of the assembly.</param> /// <param name="cultureName">The name of the culture to associate with the assembly.</param> /// <param name="publicKeyOrToken">The public key or public key token of the assembly.</param> /// <param name="hasPublicKey">Indicates whether <paramref name="publicKeyOrToken"/> represents a public key.</param> /// <param name="isRetargetable">Indicates whether the assembly is retargetable.</param> /// <param name="contentType">Specifies the binding model for how this object will be treated in comparisons.</param> /// <exception cref="ArgumentException">If <paramref name="name"/> is null, empty or contains an embedded null character.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="contentType"/> is not a value of the <see cref="AssemblyContentType"/> enumeration.</exception> /// <exception cref="ArgumentException"><paramref name="version"/> contains values that are not greater than or equal to zero and less than or equal to ushort.MaxValue.</exception> /// <exception cref="ArgumentException"><paramref name="hasPublicKey"/> is true and <paramref name="publicKeyOrToken"/> is not set.</exception> /// <exception cref="ArgumentException"><paramref name="hasPublicKey"/> is false and <paramref name="publicKeyOrToken"/> /// contains a value that is not the size of a public key token, 8 bytes.</exception> public AssemblyIdentity( string name, Version version = null, string cultureName = null, ImmutableArray <byte> publicKeyOrToken = default(ImmutableArray <byte>), bool hasPublicKey = false, bool isRetargetable = false, AssemblyContentType contentType = AssemblyContentType.Default) { if (!IsValid(contentType)) { throw new ArgumentOutOfRangeException(CodeAnalysisResources.InvalidContentType, "contentType"); } if (!IsValidName(name)) { throw new ArgumentException(string.Format(CodeAnalysisResources.InvalidAssemblyName, name), "name"); } if (!IsValidCultureName(cultureName)) { throw new ArgumentException(string.Format(CodeAnalysisResources.InvalidCultureName, cultureName), "cultureName"); } // Version allows more values then can be encoded in metadata: if (!IsValid(version)) { throw new ArgumentOutOfRangeException("version"); } if (hasPublicKey) { if (publicKeyOrToken.IsDefaultOrEmpty) { throw new ArgumentException(CodeAnalysisResources.ExpectedNonEmptyPublicKey, "publicKeyOrToken"); } } else { if (!publicKeyOrToken.IsDefaultOrEmpty && publicKeyOrToken.Length != PublicKeyTokenSize) { throw new ArgumentException(CodeAnalysisResources.InvalidSizeOfPublicKeyToken, "publicKeyOrToken"); } } if (isRetargetable && contentType == AssemblyContentType.WindowsRuntime) { throw new ArgumentException(CodeAnalysisResources.WinRTIdentityCantBeRetargetable, "isRetargetable"); } this.name = name; this.version = version ?? NullVersion; this.cultureName = cultureName ?? string.Empty; this.isRetargetable = isRetargetable; this.contentType = contentType; InitializeKey(publicKeyOrToken, hasPublicKey, out this.publicKey, out this.lazyPublicKeyToken); }
public AssemblyIdentity( string?name, Version?version = null, string?cultureName = null, ImmutableArray <byte> publicKeyOrToken = default, bool hasPublicKey = false, bool isRetargetable = false, AssemblyContentType contentType = AssemblyContentType.Default) { if (!IsValid(contentType)) { throw new ArgumentOutOfRangeException(nameof(contentType), CodeAnalysisResources.InvalidContentType); } if (!IsValidName(name)) { throw new ArgumentException(string.Format(CodeAnalysisResources.InvalidAssemblyName, name), nameof(name)); } if (!IsValidCultureName(cultureName)) { throw new ArgumentException(string.Format(CodeAnalysisResources.InvalidCultureName, cultureName), nameof(cultureName)); } // Version allows more values then can be encoded in metadata: if (!IsValid(version)) { throw new ArgumentOutOfRangeException(nameof(version)); } if (hasPublicKey) { if (!MetadataHelpers.IsValidPublicKey(publicKeyOrToken)) { throw new ArgumentException(CodeAnalysisResources.InvalidPublicKey, nameof(publicKeyOrToken)); } } else { if (!publicKeyOrToken.IsDefaultOrEmpty && publicKeyOrToken.Length != PublicKeyTokenSize) { throw new ArgumentException(CodeAnalysisResources.InvalidSizeOfPublicKeyToken, nameof(publicKeyOrToken)); } } if (isRetargetable && contentType == AssemblyContentType.WindowsRuntime) { throw new ArgumentException(CodeAnalysisResources.WinRTIdentityCantBeRetargetable, nameof(isRetargetable)); } _name = name; _version = version ?? NullVersion; _cultureName = NormalizeCultureName(cultureName); _isRetargetable = isRetargetable; _contentType = contentType; InitializeKey(publicKeyOrToken, hasPublicKey, out _publicKey, out _lazyPublicKeyToken); }
private AssemblyIdentity(SerializationInfo info, StreamingContext context) { this.name = (string)info.GetValue("name", typeof(string)); this.version = (Version)info.GetValue("version", typeof(Version)); this.cultureName = (string)info.GetValue("cultureName", typeof(string)); this.publicKey = info.GetByteArray("publicKey"); this.lazyPublicKeyToken = info.GetByteArray("publicKeyToken"); this.isRetargetable = (bool)info.GetValue("isRetargetable", typeof(bool)); this.contentType = (AssemblyContentType)info.GetValue("contentType", typeof(AssemblyContentType)); }
private AssemblyIdentity(AssemblyIdentity other, Version version) { Debug.Assert((object)other != null); Debug.Assert((object)version != null); _contentType = other.ContentType; _name = other._name; _cultureName = other._cultureName; _publicKey = other._publicKey; _lazyPublicKeyToken = other._lazyPublicKeyToken; _isRetargetable = other._isRetargetable; _version = version; _lazyDisplayName = null; _lazyHashCode = 0; }
// constructor used by metadata reader: internal AssemblyIdentity( string name, Version version, string cultureName, ImmutableArray <byte> publicKeyOrToken, bool hasPublicKey, bool isRetargetable, AssemblyContentType contentType, bool noThrow) { Debug.Assert(!string.IsNullOrEmpty(name)); Debug.Assert((hasPublicKey && MetadataHelpers.IsValidPublicKey(publicKeyOrToken)) || (!hasPublicKey && (publicKeyOrToken.IsDefaultOrEmpty || publicKeyOrToken.Length == PublicKeyTokenSize))); Debug.Assert(noThrow); _name = name; _version = version ?? NullVersion; _cultureName = cultureName ?? string.Empty; _contentType = IsValid(contentType) ? contentType : AssemblyContentType.Default; _isRetargetable = isRetargetable && _contentType != AssemblyContentType.WindowsRuntime; InitializeKey(publicKeyOrToken, hasPublicKey, out _publicKey, out _lazyPublicKeyToken); }
// error-tolerant constructor used by metadata reader: internal AssemblyIdentity( string name, Version version, string cultureName, ImmutableArray <byte> publicKeyOrToken, bool hasPublicKey, bool isRetargetable, AssemblyContentType contentType, bool noThrow) { Debug.Assert(!string.IsNullOrEmpty(name)); Debug.Assert(noThrow); if (hasPublicKey) { if (publicKeyOrToken.IsEmpty) { // PublicKey flag but no key specified => assume the flag is wrong: hasPublicKey = false; } } else { if (!publicKeyOrToken.IsDefaultOrEmpty && publicKeyOrToken.Length != PublicKeyTokenSize) { // token specified but its size isn't correct => assume it's the full key: hasPublicKey = true; } } InitializeKey(publicKeyOrToken, hasPublicKey, out this.publicKey, out this.lazyPublicKeyToken); this.name = name; this.version = version; this.cultureName = cultureName != null ? cultureName : string.Empty; this.contentType = IsValid(contentType) ? contentType : AssemblyContentType.Default; this.isRetargetable = isRetargetable && this.contentType != AssemblyContentType.WindowsRuntime; }
private static bool IsValid(AssemblyContentType value) { return(value >= AssemblyContentType.Default && value <= AssemblyContentType.WindowsRuntime); }
public static string ComputeDisplayName(string name, Version version, string cultureName, byte[] pkt, AssemblyNameFlags flags, AssemblyContentType contentType) { const int PUBLIC_KEY_TOKEN_LEN = 8; if (name == string.Empty) { throw new FileLoadException(); } StringBuilder sb = new StringBuilder(); if (name != null) { sb.AppendQuoted(name); } if (version != null) { Version canonicalizedVersion = version.CanonicalizeVersion(); if (canonicalizedVersion.Major != ushort.MaxValue) { sb.Append(", Version="); sb.Append(canonicalizedVersion.Major); if (canonicalizedVersion.Minor != ushort.MaxValue) { sb.Append('.'); sb.Append(canonicalizedVersion.Minor); if (canonicalizedVersion.Build != ushort.MaxValue) { sb.Append('.'); sb.Append(canonicalizedVersion.Build); if (canonicalizedVersion.Revision != ushort.MaxValue) { sb.Append('.'); sb.Append(canonicalizedVersion.Revision); } } } } } if (cultureName != null) { if (cultureName == string.Empty) { cultureName = "neutral"; } sb.Append(", Culture="); sb.AppendQuoted(cultureName); } if (pkt != null) { if (pkt.Length > PUBLIC_KEY_TOKEN_LEN) { throw new ArgumentException(); } sb.Append(", PublicKeyToken="); if (pkt.Length == 0) { sb.Append("null"); } else { foreach (byte b in pkt) { sb.Append(b.ToString("x2", CultureInfo.InvariantCulture)); } } } if (0 != (flags & AssemblyNameFlags.Retargetable)) { sb.Append(", Retargetable=Yes"); } if (contentType == AssemblyContentType.WindowsRuntime) { sb.Append(", ContentType=WindowsRuntime"); } // NOTE: By design (desktop compat) AssemblyName.FullName and ToString() do not include ProcessorArchitecture. return(sb.ToString()); }
internal static AssemblyNameFlags CombineAssemblyNameFlags(AssemblyNameFlags flags, AssemblyContentType contentType, ProcessorArchitecture processorArchitecture) { return((AssemblyNameFlags)(((int)flags) | (((int)contentType) << 9) | ((int)processorArchitecture << 4))); }
public static String ComputeDisplayName(RuntimeAssemblyName a) { if (a.Name == String.Empty) { throw new FileLoadException(); } StringBuilder sb = new StringBuilder(); if (a.Name != null) { sb.AppendQuoted(a.Name); } if (a.Version != null) { sb.Append(", Version="); sb.Append(a.Version.ToString()); } String cultureName = a.CultureName; if (cultureName != null) { if (cultureName == String.Empty) { cultureName = "neutral"; } sb.Append(", Culture="); sb.AppendQuoted(cultureName); } byte[] pkt = a.PublicKeyOrToken; if (pkt != null) { if (0 != (a.Flags & AssemblyNameFlags.PublicKey)) { pkt = ComputePublicKeyToken(pkt); } if (pkt.Length > PUBLIC_KEY_TOKEN_LEN) { throw new ArgumentException(); } sb.Append(", PublicKeyToken="); if (pkt.Length == 0) { sb.Append("null"); } else { foreach (byte b in pkt) { sb.Append(b.ToString("x2", CultureInfo.InvariantCulture)); } } } if (0 != (a.Flags & AssemblyNameFlags.Retargetable)) { sb.Append(", Retargetable=Yes"); } AssemblyContentType contentType = a.Flags.ExtractAssemblyContentType(); if (contentType == AssemblyContentType.WindowsRuntime) { sb.Append(", ContentType=WindowsRuntime"); } // NOTE: By design (desktop compat) AssemblyName.FullName and ToString() do not include ProcessorArchitecture. return(sb.ToString()); }
public static string ComputeDisplayName(string name, Version?version, string?cultureName, byte[]?pkt, AssemblyNameFlags flags = 0, AssemblyContentType contentType = 0) { const int PUBLIC_KEY_TOKEN_LEN = 8; Debug.Assert(name.Length != 0); var vsb = new ValueStringBuilder(stackalloc char[256]); vsb.AppendQuoted(name); if (version != null) { ushort major = (ushort)version.Major; if (major != ushort.MaxValue) { vsb.Append(", Version="); vsb.AppendSpanFormattable(major); ushort minor = (ushort)version.Minor; if (minor != ushort.MaxValue) { vsb.Append('.'); vsb.AppendSpanFormattable(minor); ushort build = (ushort)version.Build; if (build != ushort.MaxValue) { vsb.Append('.'); vsb.AppendSpanFormattable(build); ushort revision = (ushort)version.Revision; if (revision != ushort.MaxValue) { vsb.Append('.'); vsb.AppendSpanFormattable(revision); } } } } } if (cultureName != null) { if (cultureName.Length == 0) { cultureName = "neutral"; } vsb.Append(", Culture="); vsb.AppendQuoted(cultureName); } if (pkt != null) { if (pkt.Length > PUBLIC_KEY_TOKEN_LEN) { throw new ArgumentException(); } vsb.Append(", PublicKeyToken="); if (pkt.Length == 0) { vsb.Append("null"); } else { HexConverter.EncodeToUtf16(pkt, vsb.AppendSpan(pkt.Length * 2), HexConverter.Casing.Lower); } } if (0 != (flags & AssemblyNameFlags.Retargetable)) { vsb.Append(", Retargetable=Yes"); } if (contentType == AssemblyContentType.WindowsRuntime) { vsb.Append(", ContentType=WindowsRuntime"); } // NOTE: By design (desktop compat) AssemblyName.FullName and ToString() do not include ProcessorArchitecture. return(vsb.ToString()); }
internal static AssemblyNameFlags CombineAssemblyNameFlags(AssemblyNameFlags flags, AssemblyContentType contentType, ProcessorArchitecture processorArchitecture) { return (AssemblyNameFlags)(((int)flags) | (((int)contentType) << 9) | ((int)processorArchitecture << 4)); }
/// <summary> /// Parses display name filling defaults for any basic properties that are missing. /// </summary> /// <param name="displayName">Display name.</param> /// <param name="identity">A full assembly identity.</param> /// <param name="parts"> /// Parts of the assembly identity that were specified in the display name, /// or 0 if the parsing failed. /// </param> /// <returns>True if display name parsed correctly.</returns> /// <remarks> /// The simple name has to be non-empty. /// A partially specified version might be missing build and/or revision number. The default value for these is 65535. /// The default culture is neutral (<see cref="CultureName"/> is <see cref="String.Empty"/>. /// If neither public key nor token is specified the identity is considered weak. /// </remarks> /// <exception cref="ArgumentNullException"><paramref name="displayName"/> is null.</exception> public static bool TryParseDisplayName(string displayName, out AssemblyIdentity identity, out AssemblyIdentityParts parts) { // see ndp\clr\src\Binder\TextualIdentityParser.cpp, ndp\clr\src\Binder\StringLexer.cpp identity = null; parts = 0; if (displayName == null) { throw new ArgumentNullException(nameof(displayName)); } if (displayName.IndexOf('\0') >= 0) { return(false); } int position = 0; if (!TryParseNameToken(displayName, ref position, out string simpleName)) { return(false); } AssemblyIdentityParts parsedParts = AssemblyIdentityParts.Name; AssemblyIdentityParts seen = AssemblyIdentityParts.Name; Version version = null; string culture = null; bool isRetargetable = false; AssemblyContentType contentType = AssemblyContentType.Default; ImmutableArray <byte> publicKey = default(ImmutableArray <byte>); ImmutableArray <byte> publicKeyToken = default(ImmutableArray <byte>); while (position < displayName.Length) { // Parse ',' name '=' value if (displayName[position] != ',') { return(false); } position++; if (!TryParseNameToken(displayName, ref position, out string propertyName)) { return(false); } if (position >= displayName.Length || displayName[position] != '=') { return(false); } position++; if (!TryParseNameToken(displayName, ref position, out string propertyValue)) { return(false); } // Process property if (string.Equals(propertyName, "Version", StringComparison.OrdinalIgnoreCase)) { if ((seen & AssemblyIdentityParts.Version) != 0) { return(false); } seen |= AssemblyIdentityParts.Version; if (propertyValue == "*") { continue; } if (!TryParseVersion(propertyValue, out ulong versionLong, out AssemblyIdentityParts versionParts)) { return(false); } version = ToVersion(versionLong); parsedParts |= versionParts; } else if (string.Equals(propertyName, "Culture", StringComparison.OrdinalIgnoreCase) || string.Equals(propertyName, "Language", StringComparison.OrdinalIgnoreCase)) { if ((seen & AssemblyIdentityParts.Culture) != 0) { return(false); } seen |= AssemblyIdentityParts.Culture; if (propertyValue == "*") { continue; } culture = string.Equals(propertyValue, InvariantCultureDisplay, StringComparison.OrdinalIgnoreCase) ? null : propertyValue; parsedParts |= AssemblyIdentityParts.Culture; } else if (string.Equals(propertyName, "PublicKey", StringComparison.OrdinalIgnoreCase)) { if ((seen & AssemblyIdentityParts.PublicKey) != 0) { return(false); } seen |= AssemblyIdentityParts.PublicKey; if (propertyValue == "*") { continue; } if (!TryParsePublicKey(propertyValue, out ImmutableArray <byte> value)) { return(false); } // NOTE: Fusion would also set the public key token (as derived from the public key) here. // We may need to do this as well for error cases, as Fusion would fail to parse the // assembly name if public key token calculation failed. publicKey = value; parsedParts |= AssemblyIdentityParts.PublicKey; } else if (string.Equals(propertyName, "PublicKeyToken", StringComparison.OrdinalIgnoreCase)) { if ((seen & AssemblyIdentityParts.PublicKeyToken) != 0) { return(false); } seen |= AssemblyIdentityParts.PublicKeyToken; if (propertyValue == "*") { continue; } if (!TryParsePublicKeyToken(propertyValue, out ImmutableArray <byte> value)) { return(false); } publicKeyToken = value; parsedParts |= AssemblyIdentityParts.PublicKeyToken; } else if (string.Equals(propertyName, "Retargetable", StringComparison.OrdinalIgnoreCase)) { if ((seen & AssemblyIdentityParts.Retargetability) != 0) { return(false); } seen |= AssemblyIdentityParts.Retargetability; if (propertyValue == "*") { continue; } if (string.Equals(propertyValue, "Yes", StringComparison.OrdinalIgnoreCase)) { isRetargetable = true; } else if (string.Equals(propertyValue, "No", StringComparison.OrdinalIgnoreCase)) { isRetargetable = false; } else { return(false); } parsedParts |= AssemblyIdentityParts.Retargetability; } else if (string.Equals(propertyName, "ContentType", StringComparison.OrdinalIgnoreCase)) { if ((seen & AssemblyIdentityParts.ContentType) != 0) { return(false); } seen |= AssemblyIdentityParts.ContentType; if (propertyValue == "*") { continue; } if (string.Equals(propertyValue, "WindowsRuntime", StringComparison.OrdinalIgnoreCase)) { contentType = AssemblyContentType.WindowsRuntime; } else { return(false); } parsedParts |= AssemblyIdentityParts.ContentType; } else { parsedParts |= AssemblyIdentityParts.Unknown; } } // incompatible values: if (isRetargetable && contentType == AssemblyContentType.WindowsRuntime) { return(false); } bool hasPublicKey = !publicKey.IsDefault; bool hasPublicKeyToken = !publicKeyToken.IsDefault; identity = new AssemblyIdentity(simpleName, version, culture, hasPublicKey ? publicKey : publicKeyToken, hasPublicKey, isRetargetable, contentType); if (hasPublicKey && hasPublicKeyToken && !identity.PublicKeyToken.SequenceEqual(publicKeyToken)) { identity = null; return(false); } parts = parsedParts; return(true); }
public static string ComputeDisplayName(string name, Version?version, string?cultureName, byte[]?pkt, AssemblyNameFlags flags = 0, AssemblyContentType contentType = 0) { const int PUBLIC_KEY_TOKEN_LEN = 8; Debug.Assert(name.Length != 0); StringBuilder sb = new StringBuilder(); sb.AppendQuoted(name); if (version != null) { Version canonicalizedVersion = version.CanonicalizeVersion(); if (canonicalizedVersion.Major != ushort.MaxValue) { sb.Append(", Version="); sb.Append(canonicalizedVersion.Major); if (canonicalizedVersion.Minor != ushort.MaxValue) { sb.Append('.'); sb.Append(canonicalizedVersion.Minor); if (canonicalizedVersion.Build != ushort.MaxValue) { sb.Append('.'); sb.Append(canonicalizedVersion.Build); if (canonicalizedVersion.Revision != ushort.MaxValue) { sb.Append('.'); sb.Append(canonicalizedVersion.Revision); } } } } } if (cultureName != null) { if (cultureName.Length == 0) { cultureName = "neutral"; } sb.Append(", Culture="); sb.AppendQuoted(cultureName); } if (pkt != null) { if (pkt.Length > PUBLIC_KEY_TOKEN_LEN) { throw new ArgumentException(); } sb.Append(", PublicKeyToken="); if (pkt.Length == 0) { sb.Append("null"); } else { sb.Append(HexConverter.ToString(pkt, HexConverter.Casing.Lower)); } } if (0 != (flags & AssemblyNameFlags.Retargetable)) { sb.Append(", Retargetable=Yes"); } if (contentType == AssemblyContentType.WindowsRuntime) { sb.Append(", ContentType=WindowsRuntime"); } // NOTE: By design (desktop compat) AssemblyName.FullName and ToString() do not include ProcessorArchitecture. return(sb.ToString()); }
private static async Task<Tuple<Assembly, IReadOnlyList<AssemblyName>>> CreateDynamicAssemblyAsync( ProjectInformation projectInfo, AssemblyContentType contentType ) { Contract.Ensures( Contract.Result<Task<Tuple<Assembly, IReadOnlyList<AssemblyName>>>>() != null ); if ( projectInfo == null ) return new Tuple<Assembly, IReadOnlyList<AssemblyName>>( null, new AssemblyName[0] ); byte[] rawAssembly; IReadOnlyList<AssemblyName> referencedAssemblies; // create a msbuild workspace and get the compilation unit for the current project using ( var workspace = MSBuildWorkspace.Create() ) { var project = await workspace.OpenProjectAsync( projectInfo.ProjectPath ).ConfigureAwait( false ); var compilation = await project.GetCompilationAsync().ConfigureAwait( false ); using ( var stream = new MemoryStream() ) { // compile into an in-memory assembly var result = compilation.Emit( stream ); // handled failed compilation gracefully if ( !result.Success ) return new Tuple<Assembly, IReadOnlyList<AssemblyName>>( null, new AssemblyName[0] ); rawAssembly = stream.ToArray(); } // loading assemblies from binary will result in no location information being available. to ensure that referenced // assemblies can be resolved, build a list of referenced assembly names from the metadata referencedAssemblies = project.MetadataReferences.Select( mr => AssemblyName.GetAssemblyName( mr.Display ) ).ToArray(); } // we only need the type name so we use a reflection-only load var assembly = Assembly.ReflectionOnlyLoad( rawAssembly ); return Tuple.Create( assembly, referencedAssemblies ); }
private static string BuildDisplayName( string name, Version version, string cultureName, ImmutableArray <byte> publicKeyOrToken, bool hasPublicKey, bool isRetargetable, AssemblyContentType contentType) { PooledStringBuilder pooledBuilder = PooledStringBuilder.GetInstance(); var sb = pooledBuilder.Builder; EscapeName(sb, name); sb.Append(", Version="); sb.Append(version.Major); sb.Append("."); sb.Append(version.Minor); sb.Append("."); sb.Append(version.Build); sb.Append("."); sb.Append(version.Revision); sb.Append(", Culture="); if (cultureName.Length == 0) { sb.Append(InvariantCultureDisplay); } else { EscapeName(sb, cultureName); } if (hasPublicKey) { sb.Append(", PublicKey="); AppendKey(sb, publicKeyOrToken); } else { sb.Append(", PublicKeyToken="); if (publicKeyOrToken.Length > 0) { AppendKey(sb, publicKeyOrToken); } else { sb.Append("null"); } } if (isRetargetable) { sb.Append(", Retargetable=Yes"); } switch (contentType) { case AssemblyContentType.Default: break; case AssemblyContentType.WindowsRuntime: sb.Append(", ContentType=WindowsRuntime"); break; default: throw ExceptionUtilities.UnexpectedValue(contentType); } string result = sb.ToString(); pooledBuilder.Free(); return(result); }