Obtenir le numéro de version d'une DLL par programme

151

Est-il possible d'obtenir le numéro de version par programme à partir de n'importe quelle DLL .NET?

Si oui, comment?

JL.
la source
10
Je ne peux pas croire que cela a été demandé il y a 6 minutes, était sur le point de demander la même chose!
tpower
2
consultez également ce lien pour la version à incrémentation automatique - blog.mbcharbonneau.com/2007/03/13
JL.

Réponses:

119
Assembly assembly = Assembly.LoadFrom("MyAssembly.dll");
Version ver = assembly.GetName().Version;

Important: il convient de noter que ce n'est pas la meilleure réponse à la question initiale. N'oubliez pas de lire plus sur cette page.

Kris
la source
28
Cela charge MyAssembly.dll dans le AppDomain en cours d'exécution ... mauvaise idée.
staafl
12
Je recommande Assemblyname.GetAssemblyNamed'éviter ces problèmes
staafl
7
le chargement d'un assembly dans le domaine d'application est lent, irréversible (vous ne pouvez pas le décharger sans tuer le domaine), nécessite des autorisations et est susceptible de provoquer des effets secondaires, tels que l'exécution d' beforefieldinitinitialiseurs de type, et n'est tout simplement pas nécessaire dans ce cas. Ces raisons sont-elles suffisantes?
staafl
7
@staafl: Oui; pas seulement pour moi, mais aussi pour tous ceux qui liront cette page à l'avenir.
Kris
6
FileVersionInfo.GetVersionInfo("foo.dll").FileVersionfait bien le travail et ne charge pas la dll dans l'application.
Jack
181

Cela fonctionne si la dll est .net ou Win32 . Les méthodes de réflexion ne fonctionnent que si la dll est .net. De plus, si vous utilisez la réflexion, vous avez la charge de charger la dll entière en mémoire. La méthode ci-dessous ne charge pas l'assembly en mémoire.

// Get the file version.
FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo(@"C:\MyAssembly.dll");

// Print the file name and version number.
Console.WriteLine("File: " + myFileVersionInfo.FileDescription + '\n' +
                  "Version number: " + myFileVersionInfo.FileVersion);

De: http://msdn.microsoft.com/en-us/library/system.diagnostics.fileversioninfo.fileversion.aspx

source primaire

Ben Anderson
la source
5
J'aime ça. Pourquoi voudriez-vous charger la dll et ensuite utiliser la réflexion juste pour obtenir la version, alors que tout ce que vous voulez vraiment faire, c'est ça ???
aggieNick02
@ben, pouvez-vous modifier le message? J'ai vu que j'avais perdu -1 représentant en ajoutant un vote négatif, ce que je ne me souviens pas avoir fait. cela ne me laissera pas le changer, sauf si vous modifiez le message. à votre santé!
Luke Duddridge
9
Si vous voulez vous assurer d' obtenir l'exécutable / dll fait actuellement utilisé: au lieu d'un nom de fichier statique ( @"C:\MyAssembly.dll"ci - dessus), vous pouvez utiliser System.Reflection.Assembly.GetExecutingAssembly().Location(ou si une dll: Assembly.GetAssembly(typeof(AClassInTheDll)).Location)
Conrad
4
C'est la différence entre les attributs AssemblyVersion et AssemblyFileVersion. AssemblyFileVersion est estampillé de la manière dont l'API Windows peut obtenir la valeur. AssemblyVersion fait partie du nom fort et n'est pas nécessairement identique à AssemblyFileVersion.
daughey
51

Tout d'abord, il existe deux `` versions '' possibles qui pourraient vous intéresser:

  • Version du fichier du système de fichiers Windows, applicable à tous les fichiers exécutables

  • Version de build d'assembly, qui est incorporée dans un assembly .NET par le compilateur (évidemment uniquement applicable aux fichiers DLL et exe de l'assembly .NET)

Dans le premier cas, vous devriez utiliser la réponse de Ben Anderson; dans ce dernier cas, utilisezAssemblyName.GetAssemblyName(@"c:\path\to\file.dll").Version , ou la réponse de Tataro, au cas où l'assemblage serait référencé par votre code.

Notez que vous pouvez ignorer toutes les réponses qui utilisent .Load()/ .LoadFrom()methods, car elles chargent en fait l'assembly dans l'AppDomain actuel - ce qui revient à couper un arbre pour voir son âge.

staafl
la source
32

Voici une belle façon d'utiliser un peu de réflexion pour obtenir une version d'une DLL contenant une classe particulière:

var ver = System.Reflection.Assembly.GetAssembly(typeof(!Class!)).GetName().Version;

Remplacez simplement! Classe! avec le nom d'une classe qui est définie dans la DLL dont vous souhaitez obtenir la version.

C'est ma méthode préférée car si je déplace les DLL pour différents déploiements, je n'ai pas à modifier le chemin du fichier.

Totero
la source
3
Notez que cela ne fonctionne que si l'assemblage en question est référencé statiquement par celui en cours.
staafl
2
C'est la meilleure réponse car la DLL n'est pas nécessairement l'assemblage d'entrée, pas même l'assemblage à partir
duquel
1
Consultez stackoverflow.com/a/909583/492 pour obtenir différents types d'informations sur la version. par exempleFileVersionInfo
CAD bloke
22

Pour l'obtenir pour l'assembly qui a été démarré (winform, application console, etc ...)

using System.Reflection;
...
Assembly.GetEntryAssembly().GetName().Version
Agent_9191
la source
6
GetExecutingAssembly () peut également aider.
Bolt Thunder
10

Kris, votre version fonctionne très bien lorsque vous avez besoin de charger l'assembly à partir du fichier DLL réel (et si la DLL est là!), Cependant, on obtiendra une erreur très indésirable si la DLL est EMBEDDED (c'est-à-dire, pas un fichier mais un intégré DLL).

L'autre chose est que si l'on utilise un schéma de version avec quelque chose comme " 1.2012.0508.0101 ", quand on obtient la chaîne de version, vous obtiendrez en fait " 1.2012.518.101 "; notez les zéros manquants .

Alors, voici quelques fonctions supplémentaires pour obtenir la version d'une DLL (intégrée ou à partir du fichier DLL):

    public static System.Reflection.Assembly GetAssembly(string pAssemblyName)
    {
        System.Reflection.Assembly tMyAssembly = null;

        if (string.IsNullOrEmpty(pAssemblyName)) { return tMyAssembly; }
        tMyAssembly = GetAssemblyEmbedded(pAssemblyName);
        if (tMyAssembly == null) { GetAssemblyDLL(pAssemblyName); }

        return tMyAssembly;
    }//System.Reflection.Assembly GetAssemblyEmbedded(string pAssemblyDisplayName)


    public static System.Reflection.Assembly GetAssemblyEmbedded(string pAssemblyDisplayName)
    {
        System.Reflection.Assembly tMyAssembly = null;

        if(string.IsNullOrEmpty(pAssemblyDisplayName)) { return tMyAssembly; }
        try //try #a
        {
            tMyAssembly = System.Reflection.Assembly.Load(pAssemblyDisplayName);
        }// try #a
        catch (Exception ex)
        {
            string m = ex.Message;
        }// try #a
        return tMyAssembly;
    }//System.Reflection.Assembly GetAssemblyEmbedded(string pAssemblyDisplayName)


    public static System.Reflection.Assembly GetAssemblyDLL(string pAssemblyNameDLL)
    {
        System.Reflection.Assembly tMyAssembly = null;

        if (string.IsNullOrEmpty(pAssemblyNameDLL)) { return tMyAssembly; }
        try //try #a
        {
            if (!pAssemblyNameDLL.ToLower().EndsWith(".dll")) { pAssemblyNameDLL += ".dll"; }
            tMyAssembly = System.Reflection.Assembly.LoadFrom(pAssemblyNameDLL);
        }// try #a
        catch (Exception ex)
        {
            string m = ex.Message;
        }// try #a
        return tMyAssembly;
    }//System.Reflection.Assembly GetAssemblyFile(string pAssemblyNameDLL)


    public static string GetVersionStringFromAssembly(string pAssemblyDisplayName)
    {
        string tVersion = "Unknown";
        System.Reflection.Assembly tMyAssembly = null;

        tMyAssembly = GetAssembly(pAssemblyDisplayName);
        if (tMyAssembly == null) { return tVersion; }
        tVersion = GetVersionString(tMyAssembly.GetName().Version.ToString());
        return tVersion;
    }//string GetVersionStringFromAssemblyEmbedded(string pAssemblyDisplayName)


    public static string GetVersionString(Version pVersion)
    {
        string tVersion = "Unknown";
        if (pVersion == null) { return tVersion; }
        tVersion = GetVersionString(pVersion.ToString());
        return tVersion;
    }//string GetVersionString(Version pVersion)


    public static string GetVersionString(string pVersionString)
    {
        string tVersion = "Unknown";
        string[] aVersion;

        if (string.IsNullOrEmpty(pVersionString)) { return tVersion; }
        aVersion = pVersionString.Split('.');
        if (aVersion.Length > 0) { tVersion = aVersion[0]; }
        if (aVersion.Length > 1) { tVersion += "." + aVersion[1]; }
        if (aVersion.Length > 2) { tVersion += "." + aVersion[2].PadLeft(4, '0'); }
        if (aVersion.Length > 3) { tVersion += "." + aVersion[3].PadLeft(4, '0'); }

        return tVersion;
    }//string GetVersionString(Version pVersion)


    public static string GetVersionStringFromAssemblyEmbedded(string pAssemblyDisplayName)
    {
        string tVersion = "Unknown";
        System.Reflection.Assembly tMyAssembly = null;

        tMyAssembly = GetAssemblyEmbedded(pAssemblyDisplayName);
        if (tMyAssembly == null) { return tVersion; }
        tVersion = GetVersionString(tMyAssembly.GetName().Version.ToString());
        return tVersion;
    }//string GetVersionStringFromAssemblyEmbedded(string pAssemblyDisplayName)


    public static string GetVersionStringFromAssemblyDLL(string pAssemblyDisplayName)
    {
        string tVersion = "Unknown";
        System.Reflection.Assembly tMyAssembly = null;

        tMyAssembly = GetAssemblyDLL(pAssemblyDisplayName);
        if (tMyAssembly == null) { return tVersion; }
        tVersion = GetVersionString(tMyAssembly.GetName().Version.ToString());
        return tVersion;
    }//string GetVersionStringFromAssemblyEmbedded(string pAssemblyDisplayName)
MacSpudster
la source
2
var versionAttrib = new AssemblyName(Assembly.GetExecutingAssembly().FullName);
Invincible
la source
2

La réponse de @Ben s'est avérée utile pour moi. Mais j'avais besoin de vérifier la version du produit car c'était le principal incrément qui se passait dans mon logiciel et suivait le versionnage sémantique.

myFileVersionInfo.ProductVersion

Cette méthode a répondu à mes attentes

Mise à jour: au lieu de mentionner explicitement le chemin de la dll dans le programme (comme nécessaire dans la version de production), nous pouvons obtenir la version du produit en utilisant Assembly.

Assembly assembly = Assembly.GetExecutingAssembly();
FileVersionInfo fileVersionInfo =FileVersionInfo.GetVersionInfo(assembly.Location); 
string ProdVersion= fileVersionInfo.ProductVersion;
Prasan Dutt
la source
Remarque: si la version contient un astérisque pour la valeur auto-incrémentée, cette méthode renverra l'astérisque au lieu du nombre réel généré (c'est-à-dire ne fonctionne pas si vous mettez 1.0. * Dans vos informations d'assemblage).
Ronen Ness
Oui! Cependant, j'ai choisi l'automatisation Jeniks pour la mise à niveau de la version, donc l'assemblage a toujours une combinaison parfaite de version dll.
Prasan Dutt
1

Vous pouvez utiliser les méthodes System.Reflection.Assembly.Load * (), puis récupérer leur AssemblyInfo.

Ariel
la source
0

Bien que la question d'origine ne soit pas spécifique à un service Web, voici un testWebService complet que vous pouvez ajouter pour afficher une réponse de service Web non mise en cache plus la version du fichier. Nous utilisons la version fichier au lieu de la version d'assembly parce que nous voulons connaître une version, mais avec toutes les versions d'assembly 1.0.0.0, le site Web peut être facilement patché (signature et lien de demande toujours actifs!). Remplacez @ Class @ par le nom du contrôleur de l'API Web dans lequel ce service est intégré. C'est bon pour un go / nogo sur un service Web plus une vérification rapide de la version.

  [Route("api/testWebService")]
  [AllowAnonymous]
  [HttpGet]
  public HttpResponseMessage TestWebService()
  {
      HttpResponseMessage responseMessage = Request.CreateResponse(HttpStatusCode.OK);
      string loc = Assembly.GetAssembly(typeof(@Class@)).Location;
      FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(loc);
      responseMessage.Content = new StringContent($"<h2>The XXXXX web service GET test succeeded.</h2>{DateTime.Now}<br/><br/>File Version: {versionInfo.FileVersion}");
      responseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
      Request.RegisterForDispose(responseMessage);
      return responseMessage;
  }

J'ai trouvé qu'il était également nécessaire d'ajouter ce qui suit à web.config sous configuration pour le rendre vraiment anonyme

<location path="api/testwebservice">
    <system.web>
        <authorization>
            <allow users="*" />
        </authorization>
    </system.web>
</location>
Wray Smallwood
la source