//****************************************************************************************************** // AssemblyInfo.cs - Gbtc // // Copyright © 2012, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), the "License"; you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 04/29/2005 - Pinal C. Patel // Generated original version of source code. // 12/29/2005 - Pinal C. Patel // Migrated 2.0 version of source code from 1.1 source (GSF.Shared.Assembly). // 12/12/2007 - Darrell Zuercher // Edited Code Comments. // 09/08/2008 - J. Ritchie Carroll // Converted to C# as AssemblyInformation. // 09/14/2009 - Stephen C. Wills // Added new header and license agreement. // 10/21/2009 - Pinal C. Patel // Added error checking to assembly attribute properties. // 09/28/2010 - Pinal C. Patel // Modified EntryAssembly to perform a reflection only load of the currently executing process // to deal with entry assembly not being available in non-default application domains. // Changed GetCustomAttribute() to return CustomAttributeData instead of Object to deal with // possible reflection only load being performed in EntryAssembly. // Removed debuggable property since it was not very useful and added complexity when extracting. // 09/21/2011 - J. Ritchie Carroll // Added Mono implementation exception regions. // 12/14/2012 - Starlynn Danyelle Gilliam // Modified Header. // //****************************************************************************************************** using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.InteropServices; using System.Security; using GSF.IO; namespace GSF.Reflection { /// /// Represents a common information provider for an assembly. /// public class AssemblyInfo { #region [ Members ] // Fields private readonly Assembly m_assemblyInstance; #endregion #region [ Constructors ] /// Initializes a new instance of the class. /// An object. public AssemblyInfo(Assembly assemblyInstance) { m_assemblyInstance = assemblyInstance; } #endregion #region [ Properties ] /// /// Gets the underlying being represented by this object. /// public Assembly Assembly { get { return m_assemblyInstance; } } /// /// Gets the title information of the . /// public string Title { get { CustomAttributeData attribute = GetCustomAttribute(typeof(AssemblyTitleAttribute)); if ((object)attribute == null) return string.Empty; return (string)attribute.ConstructorArguments[0].Value; } } /// /// Gets the description information of the . /// public string Description { get { CustomAttributeData attribute = GetCustomAttribute(typeof(AssemblyDescriptionAttribute)); if ((object)attribute == null) return string.Empty; return (string)attribute.ConstructorArguments[0].Value; } } /// /// Gets the company name information of the . /// public string Company { get { CustomAttributeData attribute = GetCustomAttribute(typeof(AssemblyCompanyAttribute)); if ((object)attribute == null) return string.Empty; return (string)attribute.ConstructorArguments[0].Value; } } /// /// Gets the product name information of the . /// public string Product { get { CustomAttributeData attribute = GetCustomAttribute(typeof(AssemblyProductAttribute)); if ((object)attribute == null) return string.Empty; return (string)attribute.ConstructorArguments[0].Value; } } /// /// Gets the copyright information of the . /// public string Copyright { get { CustomAttributeData attribute = GetCustomAttribute(typeof(AssemblyCopyrightAttribute)); if ((object)attribute == null) return string.Empty; return (string)attribute.ConstructorArguments[0].Value; } } /// /// Gets the trademark information of the . /// public string Trademark { get { CustomAttributeData attribute = GetCustomAttribute(typeof(AssemblyTrademarkAttribute)); if ((object)attribute == null) return string.Empty; return (string)attribute.ConstructorArguments[0].Value; } } /// /// Gets the configuration information of the . /// public string Configuration { get { CustomAttributeData attribute = GetCustomAttribute(typeof(AssemblyConfigurationAttribute)); if ((object)attribute == null) return string.Empty; return (string)attribute.ConstructorArguments[0].Value; } } /// /// Gets a boolean value indicating if the has been built as delay-signed. /// public bool DelaySign { get { CustomAttributeData attribute = GetCustomAttribute(typeof(AssemblyDelaySignAttribute)); if ((object)attribute == null) return false; return (bool)attribute.ConstructorArguments[0].Value; } } /// /// Gets the version information of the . /// public string InformationalVersion { get { CustomAttributeData attribute = GetCustomAttribute(typeof(AssemblyInformationalVersionAttribute)); if ((object)attribute == null) return string.Empty; return (string)attribute.ConstructorArguments[0].Value; } } /// /// Gets the name of the file containing the key pair used to generate a strong name for the attributed . /// public string KeyFile { get { CustomAttributeData attribute = GetCustomAttribute(typeof(AssemblyKeyFileAttribute)); if ((object)attribute == null) return string.Empty; return (string)attribute.ConstructorArguments[0].Value; } } /// /// Gets the culture name of the . /// public string CultureName { get { CustomAttributeData attribute = GetCustomAttribute(typeof(NeutralResourcesLanguageAttribute)); if ((object)attribute == null) return string.Empty; return (string)attribute.ConstructorArguments[0].Value; } } /// /// Gets the assembly version used to instruct the System.Resources.ResourceManager to ask for a particular /// version of a satellite assembly to simplify updates of the main assembly of an application. /// public string SatelliteContractVersion { get { CustomAttributeData attribute = GetCustomAttribute(typeof(SatelliteContractVersionAttribute)); if ((object)attribute == null) return string.Empty; return (string)attribute.ConstructorArguments[0].Value; } } /// /// Gets the string representing the assembly version used to indicate to a COM client that all classes /// in the current version of the assembly are compatible with classes in an earlier version of the assembly. /// public string ComCompatibleVersion { get { CustomAttributeData attribute = GetCustomAttribute(typeof(ComCompatibleVersionAttribute)); if ((object)attribute == null) return string.Empty; return attribute.ConstructorArguments[0].Value + "." + attribute.ConstructorArguments[1].Value + "." + attribute.ConstructorArguments[2].Value + "." + attribute.ConstructorArguments[3].Value; } } /// /// Gets a boolean value indicating if the is exposed to COM. /// public bool ComVisible { get { CustomAttributeData attribute = GetCustomAttribute(typeof(ComVisibleAttribute)); if ((object)attribute == null) return false; return (bool)attribute.ConstructorArguments[0].Value; } } /// /// Gets a boolean value indicating if the was built in debug mode. /// public bool Debuggable { get { DebuggableAttribute attribute = m_assemblyInstance.GetCustomAttributes().FirstOrDefault(); return (object)attribute != null && attribute.IsJITOptimizerDisabled; } } /// /// Gets the GUID that is used as an ID if the is exposed to COM. /// public string Guid { get { CustomAttributeData attribute = GetCustomAttribute(typeof(GuidAttribute)); if ((object)attribute == null) return string.Empty; return (string)attribute.ConstructorArguments[0].Value; } } /// /// Gets the string representing the version number in MajorVersion.MinorVersion format. /// public string TypeLibVersion { get { CustomAttributeData attribute = GetCustomAttribute(typeof(TypeLibVersionAttribute)); if ((object)attribute == null) return string.Empty; return attribute.ConstructorArguments[0].Value + "." + attribute.ConstructorArguments[1].Value; } } /// /// Gets a boolean value indicating whether the is CLS-compliant. /// public bool CLSCompliant { get { CustomAttributeData attribute = GetCustomAttribute(typeof(CLSCompliantAttribute)); if ((object)attribute == null) return false; return (bool)attribute.ConstructorArguments[0].Value; } } /// /// Gets the path or UNC location of the loaded file that contains the manifest. /// public string Location { get { return m_assemblyInstance.Location; } } /// /// Gets the location of the as specified originally. /// public string CodeBase { get { return m_assemblyInstance.CodeBase.Replace("file:///", ""); } } /// /// Gets the display name of the . /// public string FullName { get { return m_assemblyInstance.FullName; } } /// /// Gets the simple, unencrypted name of the . /// public string Name { get { return m_assemblyInstance.GetName().Name; } } /// /// Gets the major, minor, revision, and build numbers of the . /// public Version Version { get { return m_assemblyInstance.GetName().Version; } } /// /// Gets the string representing the version of the common language runtime (CLR) saved in the file /// containing the manifest. /// public string ImageRuntimeVersion { get { return m_assemblyInstance.ImageRuntimeVersion; } } /// /// Gets a boolean value indicating whether the was loaded from the global assembly cache. /// public bool GACLoaded { get { return m_assemblyInstance.GlobalAssemblyCache; } } /// /// Gets the date and time when the was built. /// public DateTime BuildDate { get { return File.GetLastWriteTime(m_assemblyInstance.Location); } } /// /// Gets the root namespace of the . /// public string RootNamespace { get { return m_assemblyInstance.GetExportedTypes()[0].Namespace; } } #endregion #region [ Methods ] /// Gets a collection of assembly attributes exposed by the assembly. /// A System.Specialized.KeyValueCollection of assembly attributes. public NameValueCollection GetAttributes() { NameValueCollection assemblyAttributes = new NameValueCollection(); //Add some values that are not in AssemblyInfo. assemblyAttributes.Add("Full Name", FullName); assemblyAttributes.Add("Name", Name); assemblyAttributes.Add("Version", Version.ToString()); assemblyAttributes.Add("Image Runtime Version", ImageRuntimeVersion); assemblyAttributes.Add("Build Date", BuildDate.ToString()); assemblyAttributes.Add("Location", Location); assemblyAttributes.Add("Code Base", CodeBase); assemblyAttributes.Add("GAC Loaded", GACLoaded.ToString()); //Add all attributes available from AssemblyInfo. assemblyAttributes.Add("Title", Title); assemblyAttributes.Add("Description", Description); assemblyAttributes.Add("Company", Company); assemblyAttributes.Add("Product", Product); assemblyAttributes.Add("Copyright", Copyright); assemblyAttributes.Add("Trademark", Trademark); assemblyAttributes.Add("Configuration", Configuration); assemblyAttributes.Add("Delay Sign", DelaySign.ToString()); assemblyAttributes.Add("Informational Version", InformationalVersion); assemblyAttributes.Add("Key File", KeyFile); assemblyAttributes.Add("Culture Name", CultureName); assemblyAttributes.Add("Satellite Contract Version", SatelliteContractVersion); assemblyAttributes.Add("Com Compatible Version", ComCompatibleVersion); assemblyAttributes.Add("Com Visible", ComVisible.ToString()); assemblyAttributes.Add("Guid", Guid); assemblyAttributes.Add("Type Lib Version", TypeLibVersion); assemblyAttributes.Add("CLS Compliant", CLSCompliant.ToString()); return assemblyAttributes; } /// Gets the specified assembly attribute if it is exposed by the assembly. /// Type of the attribute to get. /// The requested assembly attribute if it exists; otherwise null. /// /// This method always returns null under Mono deployments. /// public CustomAttributeData GetCustomAttribute(Type attributeType) { #if MONO return null; #else //Returns the requested assembly attribute. return m_assemblyInstance.GetCustomAttributesData().FirstOrDefault(assemblyAttribute => assemblyAttribute.Constructor.DeclaringType == attributeType); #endif } /// Gets the specified embedded resource from the assembly. /// The full name (including the namespace) of the embedded resource to get. /// The embedded resource. public Stream GetEmbeddedResource(string resourceName) { //Extracts and returns the requested embedded resource. return m_assemblyInstance.GetEmbeddedResource(resourceName); } #endregion #region [ Static ] // Static Fields private static AssemblyInfo s_callingAssembly; private static AssemblyInfo s_entryAssembly; private static AssemblyInfo s_executingAssembly; private static Dictionary s_assemblyCache; private static bool s_addedResolver; // Static Properties /// /// Finds the specified searching through all loaded assemblies. /// /// Fully qualified type name. /// The found; otherwise null. public static Type FindType(string typeName) { return AppDomain.CurrentDomain.GetAssemblies() .Where(assembly => !assembly.IsDynamic) .SelectMany(assembly => { try { return assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { return ex.Types.Where(x => x != null); } }) .FirstOrDefault(type => type.FullName.Equals(typeName)); } /// /// Gets the object of the assembly that invoked the currently executing method. /// public static AssemblyInfo CallingAssembly { get { if ((object)s_callingAssembly == null) { // We have to find the calling assembly of the caller. StackTrace trace = new StackTrace(); Assembly caller = Assembly.GetCallingAssembly(); Assembly current = Assembly.GetExecutingAssembly(); StackFrame[] stackFrames = trace.GetFrames(); if ((object)stackFrames != null) { foreach (StackFrame frame in stackFrames) { if ((object)frame != null) { MethodBase method = frame.GetMethod(); if ((object)method != null && (object)method.DeclaringType != null) { Assembly assembly = Assembly.GetAssembly(method.DeclaringType); if (assembly != caller && assembly != current) { // Assembly is neither the current assembly or the calling assembly. s_callingAssembly = new AssemblyInfo(assembly); break; } } } } } } return s_callingAssembly; } } /// /// Gets the object of the process executable in the default application domain. /// public static AssemblyInfo EntryAssembly { get { if ((object)s_entryAssembly == null) { Assembly entryAssembly = Assembly.GetEntryAssembly(); if ((object)entryAssembly == null) entryAssembly = Assembly.ReflectionOnlyLoadFrom(Process.GetCurrentProcess().MainModule.FileName); s_entryAssembly = new AssemblyInfo(entryAssembly); } return s_entryAssembly; } } /// /// Gets the object of the assembly that contains the code that is currently executing. /// public static AssemblyInfo ExecutingAssembly { get { if ((object)s_executingAssembly == null) // Caller's assembly will be the executing assembly for the caller. s_executingAssembly = new AssemblyInfo(Assembly.GetCallingAssembly()); return s_executingAssembly; } } // Static Methods /// /// Loads the specified assembly that is embedded as a resource in the assembly. /// /// Name of the assembly to load. /// This cannot be used to load GSF.Core itself. [SecurityCritical] public static void LoadAssemblyFromResource(string assemblyName) { // Hooks into assembly resolve event for current domain so it can load assembly from embedded resource. if (!s_addedResolver) { AppDomain.CurrentDomain.AssemblyResolve += ResolveAssemblyFromResource; s_addedResolver = true; } // Loads the assembly (This will invoke event that will resolve assembly from resource.). AppDomain.CurrentDomain.Load(assemblyName); } private static Assembly ResolveAssemblyFromResource(object sender, ResolveEventArgs e) { Assembly resourceAssembly; string shortName = e.Name.Split(',')[0]; if ((object)s_assemblyCache == null) s_assemblyCache = new Dictionary(); resourceAssembly = s_assemblyCache[shortName]; if ((object)resourceAssembly == null) { // Loops through all of the resources in the executing assembly. foreach (string name in Assembly.GetEntryAssembly().GetManifestResourceNames()) { // Sees if the embedded resource name matches the assembly it is trying to load. if (string.Compare(FilePath.GetFileNameWithoutExtension(name), EntryAssembly.RootNamespace + "." + shortName, StringComparison.OrdinalIgnoreCase) == 0) { // If so, loads embedded resource assembly into a binary buffer. Stream resourceStream = Assembly.GetEntryAssembly().GetManifestResourceStream(name); if ((object)resourceStream != null) { byte[] buffer = new byte[resourceStream.Length]; resourceStream.Read(buffer, 0, (int)resourceStream.Length); resourceStream.Close(); // Loads assembly from binary buffer. resourceAssembly = Assembly.Load(buffer); // Add assembly to the cache s_assemblyCache.Add(shortName, resourceAssembly); } break; } } } return resourceAssembly; } #endregion } }