.net 如何读取程序集属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/187495/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 10:17:34  来源:igfitidea点击:

How to read assembly attributes

.netreflectionassembliesattributes

提问by Sam

In my program, how can I read the properties set in AssemblyInfo.cs:

在我的程序中,如何读取 AssemblyInfo.cs 中设置的属性:

[assembly: AssemblyTitle("My Product")]
[assembly: AssemblyDescription("...")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Radeldudel inc.")]
[assembly: AssemblyProduct("My Product")]
[assembly: AssemblyCopyright("Copyright @ me 2008")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

I'd like to display some of these values to the user of my program, so I'd like to know how to load them from the main program and from komponent assemblies I'm using.

我想向我的程序的用户显示其中一些值,所以我想知道如何从主程序和我正在使用的组件程序集中加载它们。

回答by Jeff Yates

This is reasonably easy. You have to use reflection. You need an instance of Assembly that represents the assembly with the attributes you want to read. An easy way of getting this is to do:

这相当容易。你必须使用反射。您需要一个Assembly 实例来表示具有您要读取的属性的程序集。一个简单的方法是这样做:

typeof(MyTypeInAssembly).Assembly

Then you can do this, for example:

然后你可以这样做,例如:

object[] attributes = assembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false);

AssemblyProductAttribute attribute = null;
if (attributes.Length > 0)
{
   attribute = attributes[0] as AssemblyProductAttribute;
}

Referencing attribute.Productwill now give you the value you passed to the attribute in your AssemblyInfo.cs. Of course, if the attribute you look for can occur more than once, you may get multiple instances in the array returned by GetCustomAttributes, but this is not usually an issue for assembly level attributes like the ones you hope to retrieve.

引用attribute.Product现在将为您提供传递给 AssemblyInfo.cs 中的属性的值。当然,如果您查找的属性可能出现多次,您可能会在 GetCustomAttributes 返回的数组中获得多个实例,但这对于您希望检索的程序集级别属性通常不是问题。

回答by dmihailescu

I've created this extension method that uses Linq:

我创建了这个使用 Linq 的扩展方法:

public static T GetAssemblyAttribute<T>(this System.Reflection.Assembly ass) where T :  Attribute
{
    object[] attributes = ass.GetCustomAttributes(typeof(T), false);
    if (attributes == null || attributes.Length == 0)
        return null;
    return attributes.OfType<T>().SingleOrDefault();
}

and then you can conveniently use it like that:

然后你可以方便地使用它:

var attr = targetAssembly.GetAssemblyAttribute<AssemblyDescriptionAttribute>();
if(attr != null)
     Console.WriteLine("{0} Assembly Description:{1}", Environment.NewLine, attr.Description);

回答by dmihailescu

Ok, perhaps a bit out of date now for the original question but I will present this for future reference anyway.

好的,对于最初的问题,现在可能有点过时了,但无论如何我都会提出这个以供将来参考。

If you want to do it from inside the assembly itself then use the following :

如果要从程序集本身内部执行此操作,请使用以下命令:

using System.Runtime.InteropServices;
using System.Reflection;

object[] customAttributes = this.GetType().Assembly.GetCustomAttributes(false);

You can then iterate through all of the custom attributes to find the one(s) you require e.g.

然后,您可以遍历所有自定义属性以找到您需要的属性,例如

foreach (object attribute in customAttributes)
{
  string assemblyGuid = string.Empty;    

  if (attribute.GetType() == typeof(GuidAttribute))
  {
    assemblyGuid = ((GuidAttribute) attribute).Value;
    break;
  }
}

回答by Kavindu Dodanduwa

Okay, I'm tried to go through many resources to find a method to extract .dll attributes for a Assembly.LoadFrom(path). But unfortunately I couldn't find any good resource. And this question was the top most result for searching on c# get assembly attributes(For me at least) So I thought of sharing my work.

好的,我试图通过许多资源找到一种方法来提取 .dll 文件的 .dll 属性Assembly.LoadFrom(path)。但不幸的是我找不到任何好的资源。这个问题是搜索的最高结果c# get assembly attributes(至少对我来说)所以我想分享我的工作。

I wrote following simple Console Program to retrieve general assembly attributes after many hours of struggle. Here I have provided the code so anyone can use it for further reference work.

经过数小时的努力,我编写了以下简单的控制台程序来检索常规程序集属性。我在这里提供了代码,以便任何人都可以将其用于进一步的参考工作。

I use CustomAttributesproperty for this. Feel free to comment on this approach

CustomAttributes为此使用财产。随意评论这种方法

Code :

代码 :

using System;
using System.Reflection;

namespace MetaGetter
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly assembly = Assembly.LoadFrom("Path to assembly");

            foreach (CustomAttributeData attributedata in assembly.CustomAttributes)
            {
                Console.WriteLine(" Name : {0}",attributedata.AttributeType.Name);

                foreach (CustomAttributeTypedArgument argumentset in attributedata.ConstructorArguments)
                {
                    Console.WriteLine("   >> Value : {0} \n" ,argumentset.Value);
                }
            }

            Console.ReadKey();
        }
    }
}

Sample Output :

示例输出:

Name : AssemblyTitleAttribute
   >> Value : "My Product"

回答by Stefan Steiger

I use this:

我用这个:

public static string Title
{
    get
    {
        return GetCustomAttribute<AssemblyTitleAttribute>(a => a.Title);
    }
}

for reference:

以供参考:

using System;
using System.Reflection;
using System.Runtime.CompilerServices;



namespace Extensions
{


    public static class AssemblyInfo
    {


        private static Assembly m_assembly;

        static AssemblyInfo()
        {
            m_assembly = Assembly.GetEntryAssembly();
        }


        public static void Configure(Assembly ass)
        {
            m_assembly = ass;
        }


        public static T GetCustomAttribute<T>() where T : Attribute
        {
            object[] customAttributes = m_assembly.GetCustomAttributes(typeof(T), false);
            if (customAttributes.Length != 0)
            {
                return (T)((object)customAttributes[0]);
            }
            return default(T);
        }

        public static string GetCustomAttribute<T>(Func<T, string> getProperty) where T : Attribute
        {
            T customAttribute = GetCustomAttribute<T>();
            if (customAttribute != null)
            {
                return getProperty(customAttribute);
            }
            return null;
        }

        public static int GetCustomAttribute<T>(Func<T, int> getProperty) where T : Attribute
        {
            T customAttribute = GetCustomAttribute<T>();
            if (customAttribute != null)
            {
                return getProperty(customAttribute);
            }
            return 0;
        }



        public static Version Version
        {
            get
            {
                return m_assembly.GetName().Version;
            }
        }


        public static string Title
        {
            get
            {
                return GetCustomAttribute<AssemblyTitleAttribute>(
                    delegate(AssemblyTitleAttribute a)
                    {
                        return a.Title;
                    }
                );
            }
        }

        public static string Description
        {
            get
            {
                return GetCustomAttribute<AssemblyDescriptionAttribute>(
                    delegate(AssemblyDescriptionAttribute a)
                    {
                        return a.Description;
                    }
                );
            }
        }


        public static string Product
        {
            get
            {
                return GetCustomAttribute<AssemblyProductAttribute>(
                    delegate(AssemblyProductAttribute a)
                    {
                        return a.Product;
                    }
                );
            }
        }


        public static string Copyright
        {
            get
            {
                return GetCustomAttribute<AssemblyCopyrightAttribute>(
                    delegate(AssemblyCopyrightAttribute a)
                    {
                        return a.Copyright;
                    }
                );
            }
        }



        public static string Company
        {
            get
            {
                return GetCustomAttribute<AssemblyCompanyAttribute>(
                    delegate(AssemblyCompanyAttribute a)
                    {
                        return a.Company;
                    }
                );
            }
        }


        public static string InformationalVersion
        {
            get
            {
                return GetCustomAttribute<AssemblyInformationalVersionAttribute>(
                    delegate(AssemblyInformationalVersionAttribute a)
                    {
                        return a.InformationalVersion;
                    }
                );
            }
        }



        public static int ProductId
        {
            get
            {
                return GetCustomAttribute<AssemblyProductIdAttribute>(
                    delegate(AssemblyProductIdAttribute a)
                    {
                        return a.ProductId;
                    }
                );
            }
        }


        public static string Location
        {
            get
            {
                return m_assembly.Location;
            }
        }

    }

}

回答by Walter Vehoeven

I personally really like the implementation of lance Larsen and his static AssemblyInfo class.

我个人非常喜欢lance Larsen 和他的静态 AssemblyInfo 类的实现

One basically pastes the class in his assembly (I usually use the already existing AssemblyInfo.cs file as it fits naming convention)

一个人基本上将类粘贴到他的程序集中(我通常使用已经存在的 AssemblyInfo.cs 文件,因为它符合命名约定)

The code to paste is:

要粘贴的代码是:

internal static class AssemblyInfo
{
    public static string Company { get { return GetExecutingAssemblyAttribute<AssemblyCompanyAttribute>(a => a.Company); } }
    public static string Product { get { return GetExecutingAssemblyAttribute<AssemblyProductAttribute>(a => a.Product); } }
    public static string Copyright { get { return GetExecutingAssemblyAttribute<AssemblyCopyrightAttribute>(a => a.Copyright); } }
    public static string Trademark { get { return GetExecutingAssemblyAttribute<AssemblyTrademarkAttribute>(a => a.Trademark); } }
    public static string Title { get { return GetExecutingAssemblyAttribute<AssemblyTitleAttribute>(a => a.Title); } }
    public static string Description { get { return GetExecutingAssemblyAttribute<AssemblyDescriptionAttribute>(a => a.Description); } }
    public static string Configuration { get { return GetExecutingAssemblyAttribute<AssemblyDescriptionAttribute>(a => a.Description); } }
    public static string FileVersion { get { return GetExecutingAssemblyAttribute<AssemblyFileVersionAttribute>(a => a.Version); } }

    public static Version Version { get { return Assembly.GetExecutingAssembly().GetName().Version; } }
    public static string VersionFull { get { return Version.ToString(); } }
    public static string VersionMajor { get { return Version.Major.ToString(); } }
    public static string VersionMinor { get { return Version.Minor.ToString(); } }
    public static string VersionBuild { get { return Version.Build.ToString(); } }
    public static string VersionRevision { get { return Version.Revision.ToString(); } }

    private static string GetExecutingAssemblyAttribute<T>(Func<T, string> value) where T : Attribute
    {
        T attribute = (T)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(T));
        return value.Invoke(attribute);
    }
}

You add a using System; to the top of the file and you're good to go.

您添加一个使用系统;到文件的顶部,你就可以开始了。

For my applications i use this class to set/get/work with my local users settings using:

对于我的应用程序,我使用这个类来设置/获取/使用我的本地用户设置:

internal class ApplicationData
{

    DirectoryInfo roamingDataFolder;
    DirectoryInfo localDataFolder;
    DirectoryInfo appDataFolder;

    public ApplicationData()
    {
        appDataFolder = new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AssemblyInfo.Product,"Data"));
        roamingDataFolder = new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),AssemblyInfo.Product));
        localDataFolder   = new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AssemblyInfo.Product));

        if (!roamingDataFolder.Exists)            
            roamingDataFolder.Create();

        if (!localDataFolder.Exists)
            localDataFolder.Create();
        if (!appDataFolder.Exists)
            appDataFolder.Create();

    }

    /// <summary>
    /// Gets the roaming application folder location.
    /// </summary>
    /// <value>The roaming data directory.</value>
    public DirectoryInfo RoamingDataFolder => roamingDataFolder;


    /// <summary>
    /// Gets the local application folder location.
    /// </summary>
    /// <value>The local data directory.</value>
    public DirectoryInfo LocalDataFolder => localDataFolder;

    /// <summary>
    /// Gets the local data folder location.
    /// </summary>
    /// <value>The local data directory.</value>
    public DirectoryInfo AppDataFolder => appDataFolder;
}

Have a look at Larsens website (MVP), he has cool stuff to draw Inspiration from.

看看 Larsens 网站 (MVP),他有很酷的东西可以从中汲取灵感。

回答by Randall Deetz

This is a great way to retrieve specific attributes in a single line of code. No special class required.

这是在一行代码中检索特定属性的好方法。不需要特殊课程。

string company = ((AssemblyCompanyAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(AssemblyCompanyAttribute), false)).Company;

回答by glopes

If you know the attribute you are looking for is unique, it is much easier to use this often overlooked static helper method of the Attributeclass:

如果您知道要查找的属性是唯一的,那么使用Attribute该类的这个经常被忽视的静态帮助器方法要容易得多:

var attribute = Attribute.GetCustomAttribute(assembly, typeof(AssemblyTitleAttribute))

This is easier because you don't need to mess around with arrays, or worry about that pesky inheritparameter. You just get the single attribute value directly, or nullif none exists.

这更容易,因为您不需要弄乱数组,或者担心那个讨厌的inherit参数。您只需直接获取单个属性值,或者null如果不存在。