development

어셈블리 (ASP.NET/C#)에서 웹 응용 프로그램 버전 번호 사용

big-blog 2021. 1. 9. 11:29
반응형

어셈블리 (ASP.NET/C#)에서 웹 응용 프로그램 버전 번호 사용


참조 된 어셈블리에서 호출 웹 응용 프로그램의 버전 번호를 얻으려면 어떻게합니까?

System.Reflection.Assembly.GetCallingAssembly (). GetName ()을 사용해 보았지만 동적으로 컴파일 된 어셈블리를 제공합니다 (버전 번호 0.0.0.0 반환).

업데이트 : 제 경우에는 웹 응용 프로그램 어셈블리 내의 클래스에 대한 참조가 필요하지 않은 솔루션이 필요했습니다. 아래 Jason의 답변 (수락 된 것으로 표시됨)은이 요구 사항을 충족합니다. 여기에 제출 된 다른 많은 사람들은 그렇지 않습니다.


다음은 웹 또는 비웹 앱에서 응용 프로그램의 "주"어셈블리를 가져 오는 것을 지원하는 몇 가지 코드입니다. 그런 다음 GetName (). Version을 사용하여 버전을 가져올 수 있습니다.

먼저 웹 앱이 아닌 경우 GetEntryAssembly ()를 시도합니다. 이것은 ASP.NET에서 null을 반환합니다. 그런 다음 HttpContext.Current를 살펴보고 이것이 웹 응용 프로그램인지 확인합니다. 그런 다음 현재 HttpHandler의 Type을 사용합니다. 그러나 ASPX 페이지에서 호출이 이루어지면이 형식의 어셈블리는 생성 된 ASP.NET 어셈블리 일 수 있으므로 해당 형식에없는 형식을 찾을 때까지 HttpHandler의 BaseType 체인을 탐색합니다 ASP.NET이 생성 된 형식 ( "ASP")에 사용하는 네임 스페이스 일반적으로 주 어셈블리의 유형입니다 (예 : 코드 숨김 파일의 페이지). 그런 다음 해당 유형의 어셈블리를 사용할 수 있습니다. 다른 모든 방법이 실패하면 GetExecutingAssembly ()로 돌아갑니다.

이 접근 방식에는 여전히 잠재적 인 문제가 있지만 응용 프로그램에서 작동합니다.

    private const string AspNetNamespace = "ASP";

    private static Assembly getApplicationAssembly()
    {
        // Try the EntryAssembly, this doesn't work for ASP.NET classic pipeline (untested on integrated)
        Assembly ass = Assembly.GetEntryAssembly();

        // Look for web application assembly
        HttpContext ctx = HttpContext.Current;
        if (ctx != null)
            ass = getWebApplicationAssembly(ctx);

        // Fallback to executing assembly
        return ass ?? (Assembly.GetExecutingAssembly());
    }

    private static Assembly getWebApplicationAssembly(HttpContext context)
    {
        Guard.AgainstNullArgument(context);

        object app = context.ApplicationInstance;
        if (app == null) return null;

        Type type = app.GetType();
        while (type != null && type != typeof(object) && type.Namespace == AspNetNamespace)
            type = type.BaseType;

        return type.Assembly;
    }

업데이트 :이 코드를 GitHubNuGet 의 작은 프로젝트로 롤업했습니다 .


동적 어셈블리 대신 "주"어셈블리의 버전을 얻는 가장 간단한 한 줄짜리 방법은 다음과 같습니다.

typeof(MyMainClass).Assembly.GetName().Version

"의미를 변경"하지 않거나 리팩토링 노력의 일부로 대체 될 가능성이없는 최상위 클래스를 MyMainClass. 이 클래스가 어떤 어셈블리에 정의되어 있는지 알고 있으며 버전 번호가 어디에서 왔는지 더 이상 혼동 할 수 없습니다.


현재 사이트 버전을 저장하는 데 Web.Config를 선호합니다.

다음이 포함 된 웹 응용 프로그램 루트에서 AssemblyInfo.cs 파일을 만들 수도 있습니다.

using System.Reflection;
using System.Runtime.CompilerServices;
...
[assembly: AssemblyVersion("1.0.*")]
...

그런 다음 다음과 같은 코드를 통해 값에 액세스하십시오.

System.Reflection.Assembly.GetExecutingAssembly()

다음은 AssemblyInfo 클래스에 대한 자세한 정보 입니다.


이미 게시 한 응답자에 추가합니다. ASP.Net 웹 응용 프로그램에서 어셈블리 버전을 가져 오려면 다음과 유사한 파일 뒤에있는 코드에 메서드를 배치해야합니다.

protected string GetApplicationVersion() {
    return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
}

ASPX 페이지에서 버전 번호를 표시하려면 다음을 입력하십시오.

<%= GetApplicationVersion() %>

누군가가 여전히 관심이있는 경우를 대비하여 이 트릭을 할해야 그냥 복용보다 약간 더 안전해야한다 BaseType의를 ApplicationInstanceGlobal.asax에 구현에 손을 얻을 수 있습니다.

Global.asax는 항상 AssemblyInfo.cs의 어셈블리 특성과 동일한 어셈블리로 컴파일되므로 Global.asax를 정의하는 모든 웹 응용 프로그램에서 작동합니다.

자체 Global.asax를 정의하지 않는 경우 생성 된 global_asax유형 의 버전 ( 항상 0.0.0.0)으로 대체되고 웹 응용 프로그램이 아닌 응용 프로그램의 경우 버전이 전혀 반환되지 않습니다. .

보너스; BuildManager클래스를 사용하는 데는 활성 인스턴스가 필요 하지 않습니다.HttpContext 즉, 애플리케이션 시작 코드에서도 사용할 수 있어야합니다.

public static Version GetHttpApplicationVersion() {
  Type lBase = typeof(HttpApplication);
  Type lType = BuildManager.GetGlobalAsaxType();

  if (lBase.IsAssignableFrom(lType))
  {
    while (lType.BaseType != lBase) { lType = lType.BaseType; }
    return lType.Assembly.GetName().Version;
  }
  else
  {
    return null;
  }
}

HttpContext.Current.ApplicationInstance는 global.asax.cs의 클래스에서 파생됩니다. 다음을 수행 할 수 있습니다.

 var instance = HttpContext.Current.ApplicationInstance;
 Assembly asm = instance.GetType().BaseType.Assembly;
 System.Version asmVersion = asm.GetName().Version;

ASP.NET (ASPX) 및 ASP.NET MVC에서 모두 작동합니다.


비슷한 문제가 발생하여 솔루션이 유용하다고 생각했습니다.

I needed to report the current application version (of a web application project) from a custom server control, where the server control was contained in a different library. The problem was that the "easiest" assembly getters did not provide the right assembly.

  • Assembly.GetExecutingAssembly() returned the assembly containing the control; not the application assembly.
  • Assembly.GetCallingAssembly() returned different assemblies depending on where I was at in the call tree; usually System.Web, and sometimes the assembly containing the control.
  • Assembly.GetEntryAssembly() returned null.
  • new StackTrace().GetFrames()[idx].GetMethod().DeclaringType.Assembly retrieves the assembly of a frame in the stack trace at index idx; however, besides being inelegant, expensive, and prone to miscalculation on the frame index, it is possible for the stack trace to not contain any calls to the application assembly.
  • Assembly.GetAssembly(Page.GetType()) scored me the App_Web_@#$@#$%@ assembly containing the dynamically generated page. Of course, the dynamic page inherits a class from my application assembly, so that led to the final solution:

Assembly.GetAssembly(Page.GetType().BaseType)

With the assembly reference in hand, you can drill to the version through its name:

var version = Assembly.GetAssembly(Page.GetType().BaseType)
                      .GetName()
                      .Version;

Now, this solution works because I had a reference to a type from the application assembly. We don't use any pages that do not inherit from a code behind, so it happens to be effective for us, but your mileage may vary if your organization's coding practices are different.

Happy coding!


Version version = new Version(Application.ProductVersion);
string message = version.ToString();

Some info here: http://www.velocityreviews.com/forums/showpost.php?p=487050&postcount=8

in asp.net 2.0 each page is built into it own assembly, so only the dll the AssemblyInfo.cs is built into will return the correct answer. just add a static method to AssemblyInfo.cs that returns the version info, and call this method from your other pages.

-- bruce (sqlwork.com)

But I wrote a simple method to do that:

    public static string GetSystemVersion(HttpServerUtility server)
    {
        System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
        doc.Load(server.MapPath("~/web.config"));
        System.Xml.XmlNamespaceManager ns = new System.Xml.XmlNamespaceManager(doc.NameTable);
        ns.AddNamespace("bla", "http://schemas.microsoft.com/.NetConfiguration/v2.0");

        System.Xml.XmlNode node = doc.SelectSingleNode("/bla:configuration/bla:system.web/bla:authentication/bla:forms[@name]", ns);

        string projectName = "";
        if (node != null && node.Attributes != null && node.Attributes.GetNamedItem("name") != null)
            projectName = node.Attributes.GetNamedItem("name").Value; //in my case, that value is identical to the project name (projetname.dll)
        else
            return "";

        Assembly assembly = Assembly.Load(projectName);
        return assembly.GetName().Version.ToString();
    }

If you are looking for this from a web control, one hack is to find the type of the code-behind Page (ie. the class that inherits from System.Web.UI.Page). This is normally in the consumer's web assembly.

Type current, last;
current = Page.GetType();
do
{
    last = current;
    current = current.BaseType;
} while (current != null && current != typeof(System.Web.UI.Page));
return last;

I hope there is a better way.


The question states with no reference (instances) it did not (originally) say with no knowledge of web application types.

EDIT the OP clarified to state that yes they do really require no knowledge of types within the calling web assembly, so the answer is appropriate. However I would seriously consider refactoring such a solution such that the version is passed into the other assembly.

For most people in this scenario if you know the custom HttpApplication type:

 typeof(MyHttpApplication).Assembly.GetName().Version

and if you only have a dynamic generated type:

 typeof(DynamiclyGeneratedTypeFromWebApp).BaseType.Assembly.GetName().Version

Stop voting me down for this answer :)

ReferenceURL : https://stackoverflow.com/questions/756031/using-the-web-application-version-number-from-an-assembly-asp-net-c

반응형