IT TIP

어셈블리 특성을 읽는 방법

itqueen 2020. 12. 30. 20:00
반응형

어셈블리 특성을 읽는 방법


내 프로그램에서 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("")]

이 값 중 일부를 내 프로그램 사용자에게 표시하고 싶으므로 기본 프로그램과 내가 사용중인 komponent 어셈블리에서 값을로드하는 방법을 알고 싶습니다.


이것은 합리적으로 쉽습니다. 반사를 사용해야합니다. 읽으려는 특성이있는 어셈블리를 나타내는 Assembly 인스턴스가 필요합니다. 이를 얻는 쉬운 방법은 다음과 같습니다.

typeof(MyTypeInAssembly).Assembly

그런 다음이를 수행 할 수 있습니다. 예를 들면 다음과 같습니다.

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

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

attribute.Product이제 참조 하면 AssemblyInfo.cs의 특성에 전달한 값이 제공됩니다. 물론 찾는 속성이 두 번 이상 발생할 수있는 경우 GetCustomAttributes에서 반환 된 배열에 여러 인스턴스가있을 수 있지만 일반적으로 검색하려는 속성과 같은 어셈블리 수준 속성에 대해서는 문제가되지 않습니다.


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();
}

다음과 같이 편리하게 사용할 수 있습니다.

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

좋아, 원래 질문에 대해 지금은 약간 구식이지만 어쨌든 나중에 참조하기 위해 이것을 제시 할 것입니다.

어셈블리 내부에서 수행하려면 다음을 사용하십시오.

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

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

그런 다음 모든 사용자 정의 속성을 반복하여 필요한 속성을 찾을 수 있습니다.

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

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

좋아, .dll 속성을 추출하는 방법을 찾기 위해 많은 리소스를 살펴 보았습니다 Assembly.LoadFrom(path). 하지만 안타깝게도 좋은 자료를 찾을 수 없었습니다. 그리고이 질문은 c# get assembly attributes(적어도 저 에게는) 검색 결과 가장 많은 결과를 얻었습니다. 그래서 제 작업을 공유 할 생각을했습니다.

몇 시간의 노력 끝에 일반 어셈블리 속성을 검색하기 위해 다음과 같은 간단한 콘솔 프로그램을 작성했습니다. 여기에서는 누구나 추가 참조 작업에 사용할 수 있도록 코드를 제공했습니다.

나는 이것을 위해 CustomAttributes재산을 사용 합니다. 이 접근 방식에 대해 자유롭게 의견을 말하십시오.

코드 :

using System;
using System.Reflection;

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

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

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

            Console.ReadKey();
        }
    }
}

샘플 출력 :

Name : AssemblyTitleAttribute
   >> Value : "My Product"

나는 이것을 사용한다 :

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

참고로 :

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;
            }
        }

    }

}

나는 개인적으로 lance Larsen과 그의 정적 AssemblyInfo 클래스 의 구현을 정말 좋아합니다 .

하나는 기본적으로 자신의 어셈블리에 클래스를 붙여 넣습니다 (일반적으로 이름 지정 규칙에 맞기 때문에 기존 AssemblyInfo.cs 파일을 사용합니다).

붙여 넣을 코드는 다음과 같습니다.

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);
    }
}

사용 시스템을 추가합니다. 파일 맨 위로 이동하면됩니다.

내 응용 프로그램의 경우이 클래스를 사용하여 다음을 사용하여 로컬 사용자 설정을 설정 / 가져 오기 / 작업합니다.

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;
}

Larsens 웹 사이트 (MVP)를 살펴보면 영감을 얻을 수있는 멋진 기능이 있습니다.


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 Attribute class:

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 inherit parameter. You just get the single attribute value directly, or null if none exists.


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;

ReferenceURL : https://stackoverflow.com/questions/187495/how-to-read-assembly-attributes

반응형