web-dev-qa-db-ja.com

アセンブリのWebアプリケーションバージョン番号を使用する(ASP.NET/C#)

参照アセンブリの呼び出し元Webアプリケーションのバージョン番号を取得するにはどうすればよいですか?

System.Reflection.Assembly.GetCallingAssembly()。GetName()を使用してみましたが、動的にコンパイルされたアセンブリ(バージョン番号0.0.0.0を返す)を提供するだけです。

更新:私の場合、Webアプリケーションアセンブリ内のクラスへの参照を必要としないソリューションが必要でした。以下のJasonの回答(承認済みとしてマークされています)はこの要件を満たします。 。

53
David Duffett

Webアプリまたは非Webアプリのいずれかからアプリケーションの「メイン」アセンブリの取得をサポートするコードを次に示します。GetName()。Versionを使用してバージョンを取得できます。

最初に、非Webアプリに対してGetEntryAssembly()を試行します。これは、ASP.NETでnullを返します。次に、HttpContext.Currentを調べて、これがWebアプリケーションかどうかを判断します。次に、現在の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;
    }

更新:このコードを GitHub および NuGet の小さなプロジェクトにまとめました。

49
Jason Duffett

動的なものではなく、「メイン」アセンブリのバージョンを取得する最も簡単なワンライナーの方法は次のとおりです。

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

MyMainClassのように、最上位クラスを使用してください。これは、「その意味を変更する」ことも、リファクタリングの一環として置き換えられることもほとんどありません。このクラスが定義されているアセンブリを知っているので、バージョン番号がどこから来たのか混乱することはもうありません。

40
Yodan Tauber

Web.Configがサイトの現在のバージョンを保存することを好みます。

以下を含むWebアプリケーションルートにAssemblyInfo.csファイルを作成することもできます。

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

次に、次のようなコードを介して値にアクセスします。

System.Reflection.Assembly.GetExecutingAssembly()

AssemblyInfoクラスの詳細は 情報 です。

27

すでに投稿したレスポンダーに追加します。 ASP.Net Webアプリケーションでアセンブリバージョンを取得するには、コードビハインドファイルに次のようなメソッドを配置する必要があります。

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

ASPXページでは、単にバージョン番号を表示したいだけです。

<%= GetApplicationVersion() %>
14
Amir Khawaja

誰かがまだ興味がある場合に備えて。これは、トリックを行う必要があり、Global [asaxの実装を理解するためにBaseTypeApplicationInstanceを取得するよりも少し安全である必要があります。

Global.asaxは常にAssemblyInfo.csのAssembly属性と同じAssemblyにコンパイルされるため、Global.asaxを定義するすべてのWebアプリケーションで機能するはずです。

独自のGlobal.asaxを定義していない場合、生成されるglobal_asaxタイプのバージョン(常に0.0.0.0)にフォールバックし、Webアプリケーションではないアプリケーションの場合は、バージョンをまったく返しません。

ボーナス; BuildManagerクラスを使用するとnotアクティブな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;
  }
}
8
Ron Otten

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の両方で機能します

6

同様の問題が発生したため、このソリューションが役立つと思うかもしれません。

サーバーコントロールが別のライブラリに含まれているカスタムサーバーコントロールから、(Webアプリケーションプロジェクトの)現在のアプリケーションバージョンを報告する必要がありました。問題は、「最も簡単な」アセンブリゲッターが適切なアセンブリを提供しなかったことです。

  • Assembly.GetExecutingAssembly()は、コントロールを含むアセンブリを返しました。アプリケーションアセンブリではありません。
  • Assembly.GetCallingAssembly()は、コールツリーのどこにいるかによって異なるアセンブリを返しました。通常、System.Web、および場合によってはコントロールを含むアセンブリ。
  • Assembly.GetEntryAssembly()nullを返しました。
  • new StackTrace().GetFrames()[idx].GetMethod().DeclaringType.Assemblyは、インデックスidxのスタックトレース内のフレームのアセンブリを取得します。ただし、エレガントで高価であり、フレームインデックスの計算を誤る傾向があることに加えて、スタックトレースがnot containアプリケーションアセンブリの呼び出しになる可能性があります。
  • Assembly.GetAssembly(Page.GetType())App_Web_@#$@#$%@動的に生成されたページを含むアセンブリ。もちろん、動的ページはアプリケーションアセンブリからクラスを継承するため、最終的なソリューションにつながります。

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

アセンブリ参照を使用すると、その名前を介してバージョンにドリルできます。

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

現在、このソリューションは、アプリケーションAssemblyからの型への参照を持っているため機能します。 notを継承するページは使用しないため、コードビハインドから効果的ですが、組織のコーディング慣行が異なる場合、マイレージは異なる場合があります。

ハッピーコーディング!

4
kbrimington
Version version = new Version(Application.ProductVersion);
string message = version.ToString();
2
noname

ここにいくつかの情報: http://www.velocityreviews.com/forums/showpost.php?p=487050&postcount=8

asp.net 2.0では、各ページは独自のアセンブリに組み込まれているため、AssemblyInfo.csが組み込まれているdllのみが正しい答えを返します。バージョン情報を返す静的メソッドをAssemblyInfo.csに追加し、他のページからこのメソッドを呼び出すだけです。

-ブルース(sqlwork.com)

しかし、私はそれを行う簡単な方法を書きました:

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

質問は参照なし(インスタンス)であり、Webアプリケーションの種類の知識がないと(元々)言わなかった。

[〜#〜] edit [〜#〜] OPは、呼び出し元のWebアセンブリ内の型の知識を本当に必要としないことを明確にするため、OPを明確にしました。したがって、答えは適切です。ただし、バージョンが他のアセンブリに渡されるように、このようなソリューションをリファクタリングすることを真剣に検討します。

このシナリオのほとんどの人は、カスタムHttpApplicationタイプを知っている場合:

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

そして、動的に生成されたタイプしかない場合:

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

この答えに私を投票するのをやめてください:)

1
Tom Deloford

Webコントロールからこれを探している場合、ハッキングの1つは分離コードページのタイプ(つまり、System.Web.UI.Pageを継承するクラス)を見つけることです。これは通常、消費者のWebアセンブリにあります。

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

もっと良い方法があるといいのですが。

1
Matt Woodard