Beispiel #1
0
        // 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);
        }
Beispiel #2
0
        //
        // 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));
        }
Beispiel #3
0
        // 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);
        }
Beispiel #4
0
        //
        // 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);
        }
Beispiel #7
0
        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));
 }
Beispiel #9
0
        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;
        }
Beispiel #10
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;
        }
Beispiel #12
0
 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)));
 }
Beispiel #15
0
        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());
        }
Beispiel #16
0
        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());
        }
Beispiel #17
0
 public void ContentType(AssemblyContentType contentType)
 {
     AssemblyName assemblyName = new AssemblyName("MyAssemblyName");
     Assert.Equal(AssemblyContentType.Default, assemblyName.ContentType);
     assemblyName.ContentType = contentType;
     Assert.Equal(contentType, assemblyName.ContentType);
 }
Beispiel #18
0
 internal static AssemblyNameFlags CombineAssemblyNameFlags(AssemblyNameFlags flags, AssemblyContentType contentType, ProcessorArchitecture processorArchitecture)
 {
     return (AssemblyNameFlags)(((int)flags) | (((int)contentType) << 9) | ((int)processorArchitecture << 4));
 }
Beispiel #19
0
        /// <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());
        }
Beispiel #21
0
            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 );
            }
Beispiel #22
0
        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);
        }