67 votes

Déterminer la version de l’assemblage lors d’un événement post-build?

Disons que j'ai voulu créer un fichier texte statique qui est livré avec chaque version. Je veux que le fichier soit mis à jour avec le numéro de version (comme spécifié dans l' AssemblyInfo.cs), mais je ne veux pas avoir à le faire manuellement.

J'espérais que je pourrais utiliser un post-événement de construction et de nourrir le numéro de version d'un fichier de commandes comme ceci:

call foo.bat $(AssemblyVersion)

Cependant je ne peux pas trouver tout de la variable ou de la macro à utiliser.

Est-il possible de réaliser ce que j'ai manqué?

104voto

Brent Arias Points 7104

Si (1) vous ne voulez pas télécharger ou créer un exécutable qui permet de récupérer la version de l'assembly et (2) vous n'avez pas l'esprit de l'édition du fichier de projet Visual Studio, alors il existe une solution simple qui vous permet d'utiliser une macro qui ressemble à ceci:

@(Cibles->'%(Version)')

@(VersionNumber)

Pour ce faire, décharger votre projet. Si le projet quelque part définit un <PostBuildEvent> propriété, le couper de la le projet et l'enregistrer ailleurs temporairement (le bloc-notes?). Puis à la fin du projet, juste avant la balise de fin, le lieu ce:

<Target Name="PostBuildMacros">
  <GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
    <Output TaskParameter="Assemblies" ItemName="Targets" />
  </GetAssemblyIdentity>
  <ItemGroup>
    <VersionNumber Include="@(Targets->'%(Version)')"/>
  </ItemGroup>
</Target>
<PropertyGroup>
  <PostBuildEventDependsOn>
    $(PostBuildEventDependsOn);
    PostBuildMacros;
  </PostBuildEventDependsOn>    
  <PostBuildEvent>echo HELLO, THE ASSEMBLY VERSION IS: @(VersionNumber)</PostBuildEvent>
</PropertyGroup>

Cet extrait a un exemple <PostBuildEvent> déjà en elle. Pas de soucis, vous pouvez le réinitialiser votre véritable événement post-build après avoir re-chargé du projet.

Maintenant, comme promis, la version de l'assembly est disponible pour votre événement post-construction avec cette macro:

@(VersionNumber)

Fait!

17voto

Tuinstoelen Points 691

Si vous préférez les scripts de ces méthodes peut également travailler pour vous:

Si vous utilisez l'après-créer un événement, vous pouvez utiliser le filever.exe outil de le saisir de la déjà construit assemblée:

for /F "tokens=4" %%F in ('filever.exe /B /A /D bin\debug\myapp.exe') do (
  set VERSION=%%F
)
echo The version is %VERSION%

Obtenez de l'filever.exe à partir d'ici: http://support.microsoft.com/kb/913111

Si vous utilisez le pré-créer un événement, vous pouvez le sortir de la AssemblyInfo.cs fichier comme suit:

set ASMINFO=Properties\AssemblyInfo.cs
FINDSTR /C:"[assembly: AssemblyVersion(" %ASMINFO% | sed.exe "s/\[assembly: AssemblyVersion(\"/SET CURRENT_VERSION=/g;s/\")\]//g;s/\.\*//g" >SetCurrVer.cmd
CALL SetCurrVer.cmd
DEL SetCurrVer.cmd
echo Current version is %CURRENT_VERSION%

Il utilise la ligne de commande unix outil sed, que vous pouvez télécharger à partir de nombreux endroits, comme ici: http://unxutils.sourceforge.net/ - iirc que l'on travaille sur ok.

12voto

Winston Smith Points 12029

Pour contourner le problème, j'ai écrit une application de console gérée qui prend la cible en tant que paramètre et renvoie le numéro de version.

Je suis toujours intéressé par une solution plus simple - mais je l’affiche au cas où quelqu'un le trouverait utile.

 using System;
using System.IO;
using System.Diagnostics;
using System.Reflection;

namespace Version
{
    class GetVersion
    {
        static void Main(string[] args)
        {
            if (args.Length == 0 || args.Length > 1) ShowUsage();

            string target = args[0];

            string path = Path.IsPathRooted(target) 
                                ? target 
                                : Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + Path.DirectorySeparatorChar + target;

            Console.Write( Assembly.LoadFile(path).GetName().Version.ToString(2) );
        }

        static void ShowUsage()
        {
            Console.WriteLine("Usage: version.exe <target>");
        }
    }
}
 

1voto

Rohan West Points 5914

Je pense que la meilleure chose que vous pouvez faire est de regarder la MSBuild et MsBuild Pack d'Extension vous devriez être en mesure d'éditer le fichier de solution, de sorte qu'un poste de créer un événement se produit et écrit pour votre fichier de test.

Si c'est trop compliqué alors vous pouvez simplement créer un petit programme qui inspecte toutes les assemblées de la sortie de répertoire et de l'exécuter sur le post de construire, vous pouvez passer dans le répertoire de sortie à l'aide de la variable nom de la... par exemple dans le post-construction de l'événement...

AssemblyInspector.exe "$(TargetPath)"

class Program
{
    static void Main(string[] args)
    {
        var assemblyFilename = args.FirstOrDefault();
        if(assemblyFilename != null && File.Exists(assemblyFilename))
        {
            try
            {
                var assembly = Assembly.ReflectionOnlyLoadFrom(assemblyFilename);
                var name = assembly.GetName();

                using(var file = File.AppendText("C:\\AssemblyInfo.txt"))
                {
                    file.WriteLine("{0} - {1}", name.FullName, name.Version);
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }
    }
}

Vous pouvez également passer dans le texte à l'emplacement du fichier...

1voto

Joshua Evensen Points 545

J'ai commencé à ajouter un projet séparé qui se construit en dernier et à ajouter un événement post-génération à ce projet qui s'exécute. Ensuite, je viens d’effectuer mes étapes de post-build par programme.

Il est beaucoup plus facile de faire ce genre de choses. Ensuite, vous pouvez simplement inspecter les attributs d’assemblage de l’ensemble que vous souhaitez. Jusqu'à présent, ça fonctionne plutôt bien.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X