Comment puis-je définir la version du programme d'installation WiX sur la version actuelle de la version?

134

J'ai écrit une application et son installeur WiX et je l'ai mise sous contrôle de version en utilisant subversion. Lorsque le programme d'installation de WiX se construit, je veux que son numéro de version soit la version actuelle de l'application. Comment faire cela? J'ai utilisé c # pour coder l'application.

NB J'utilise ccnet pour construire ce projet

Draco
la source

Réponses:

181

Vous pouvez utiliser Product/@Version="!(bind.FileVersion.FileId)"(remplacer FileIdpar le Idfichier à partir duquel vous souhaitez obtenir le numéro de version) et light.exe remplira la valeur avec la version du fichier référencée par le FileId.

Rob Mensching
la source
4
Exactement ce que je cherchais! Bien que j'aie dû utiliser "! (Bind.FileVersion.FileId)" (un "!" Au lieu de "$"), sinon j'ai eu une erreur de directive de préprocesseur.
Nicholas Piasecki
8
Ouais, désolé, erreur mentale constante que je fais. $ est une variable de préprocesseur et! est la variable du liant.
Rob Mensching
20
Notez que "Fileid" doit être la valeur d'un élément <File Id = "Fileid" ...>, et peut apparemment inclure le caractère point (.).
James Hugard
6
Est-il possible de faire cela pour un bundle / bootstrapper aussi?
noelicus
6
Un lien vers la documentation connexe, section: Variables du classeur
mcdon
39

J'ai fait cela dans l'un de mes projets en écrivant une extension de préprocesseur pour lire la version du fichier à partir de mon exécutable. Le fichier WiX ressemble donc à quelque chose comme:

<?define ProductName="$(fileVersion.ProductName($(var.MyApp.TargetPath)))" ?>
<?define CompanyName="$(fileVersion.CompanyName($(var.MyApp.TargetPath)))" ?>
<?define ProductVersion="$(fileVersion.ProductVersion($(var.MyApp.TargetPath)))" ?>
<Product 
    Id="<product ID>" 
    Name="$(var.ProductName)" 
    Version="$(var.ProductVersion)" 
    Manufacturer="$(var.CompanyName)" 
    Language="1033" 
    UpgradeCode="<upgrade code>">

J'ai posté le code pour dans sur CodePlex: http://wixfileversionext.codeplex.com/

Chris Kaczor
la source
Votre extension fonctionne-t-elle toujours? J'ai essayé de l'ajouter comme référence et j'ai eu une erreur.
Stefan Vasiljevic
Cette extension a très bien fonctionné avec Wix 3.5, après la mise à jour vers Wix 3.9, elle lève une NullPointerException. De toute évidence, quelque chose s'est brisé entre ces versions.
Gigo
2
@Gigo Je l'ai fait fonctionner via <?define ProductName="!(bind.property.ProductName)" ?><?define CompanyName="!(bind.property.Manufacturer)" ?><?define ProductVersion=!(bind.FileVersion.FileId) ?>FileIdest la valeur de l' Idattribut de l'un de vos Fileéléments dans un fichier Component.
Jared
Le lien CodePlex ne s'ouvre pas pour moi. Existe-t-il un autre moyen que d'écrire votre propre extension de pré-processeur?
RDV
28

Dans le cas où quelqu'un recherche un exemple XML réel, cela fonctionne avec les assemblys .NET (et vous n'avez pas à faire les attributs Assembly ou KeyPath). J'ai éliminé le code sans rapport avec [...] des espaces réservés:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product [...] Version="!(bind.fileVersion.MyDLL)">
        [...]
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder" Name="PFiles">
                <Directory Id="INSTALLDIR" Name="MyDLLInstallLocation">
                    <Component Id="MainLib" Guid="[...]">
                        <File Id="MyDLL" Name="MyDll.dll" Source="MyDll.dll" />
                        [...]
                    </Component>
                    [...]
                </Directory>
            </Directory>
        </Directory>
    </Product>
</Wix>
K0D4
la source
1
C'est une bien meilleure réponse. Merci pour l'exemple de travail.
lance le
où récupère-t-il le numéro de version réel?
foobar
@foobar Cela fait un moment que je n'étais pas ici, mais si vous regardez la chaîne, !(bind.fileVersion.MyDLL)il utilise la 3ème partie en référence à la <File Id="MyDLL"...section
K0D4
Cela a bien fonctionné pour moi. Fonctionne pour les exécutables compilés ainsi que pour les dll, ce qui est idéal pour épingler la version du programme d'installation et le contenu de l'interface utilisateur aux informations d'assemblage exe, sans avoir à changer les choses à plusieurs endroits
rcbevans
21

Voici un moyen très simple d'obtenir la version de votre bundle Bootstrapper pour qu'elle corresponde à votre version d'assembly MyApp en utilisant un BeforeBuild Targetet DefineConstants.

Bundle.wxs:

<Bundle Name="$(var.ProductName) Bootstrapper v$(var.BuildVersion)"
     Version="$(var.BuildVersion)"

Bootstrapper.wixproj:

<Target Name="BeforeBuild">
  <GetAssemblyIdentity AssemblyFiles="..\MyApp\bin\$(Configuration)\MyApp.exe">
    <Output TaskParameter="Assemblies" ItemName="AssemblyVersion" />
  </GetAssemblyIdentity>
  <PropertyGroup>
    <DefineConstants>BuildVersion=%(AssemblyVersion.Version)</DefineConstants>
  </PropertyGroup>
</Target>
Brock Hensley
la source
@AliKazmi Avez-vous défini votre var.ProductNameet var.BuildVersionquelque part au-dessus de votre <Bundle>?
Brock Hensley
2
J'ai essayé cela et je ne peux pas le recommander assez - combinez-le avec le patcher d'assemblage pour TeamCity et vous avez une formule gagnante. Je n'ai pas utilisé l'élément Bundle mais un élément produit à la place et j'ai toujours travaillé pour moi.
IbrarMumtaz
VS aime juste ignorer la BeforeBuildcible, il peut donc être nécessaire de spécifier explicitement AfterTargets="AfterResolveReferences"si vous construisez dans l'EDI
Dmitry
J'ai ajouté le code Bootstrapper.wixproj dans mon fichier * .wixproj et dans le fichier Product.wxs, j'ai défini la variable buildversion comme suit:
RDV
4

Vous pouvez transmettre la version au script MSBuild pour votre projet d'installation de la même manière que vous pouvez transmettre le script de génération de l'application.

Par exemple, si votre système CI définit des variables AppVersionet BuildNumber, et les transmet à vos scripts MSBuild, votre wixproj peut créer une Versionpropriété correspondante qu'il transmet à Wix comme ceci:

<PropertyGroup>
    <Version Condition=" '$(BuildNumber)' == '' ">0.0.1</Version>
    <Version Condition=" '$(BuildNumber)' != '' ">$(AppVersion).$(BuildNumber)</Version>
    <DefineConstants>Version=$(Version)</DefineConstants>
</PropertyGroup>

La première définition de Versionfournit une valeur par défaut lorsque vous créez localement. Tout ce qu'il finit par devient une Versionvariable dans Wix. Utilisez-le dans un fichier wsx comme celui-ci:

<Product Version="$(var.Version)" ...>
    <Package Description="$(var.ProductName) $(var.Version): $(var.ProductDescription)" ... />

J'aime inclure la version dans la description afin qu'il soit facile de rechercher dans l'Explorateur de fenêtres (sous forme de colonne dans la vue détaillée ou sur la page Propriétés) indépendamment du nom du fichier.

Passer la version en tant que variable vous donne plus de contrôle que de la lire à partir d'un fichier. Lorsque vous lisez un fichier, vous obtenez les 4 parties de la version programmatique. Cependant, ProductVersion est uniquement conçu pour utiliser les 3 premières parties.

Edward Brey
la source
Merci, cela m'a sauvé ma journée. BTW: Le code supérieur extrait entre dans votre projet (* .wxiproj). Avoir à gérer un Devops / VSTS CI-Build, c'est la meilleure réponse. Puisque j'ai déjà ma variable de version finale prête. Cela s'est transformé dans mon cas en: <Version Condition=" '$(BuildVersionOfAsm)' != '' ">$(BuildVersionOfAsm)</Version>alors que BuildVersionOfAsm est une variable dans les pipelines devops.
Robetto
Je veux choisir Version dynamiquement, cette méthode m'obligera à continuer à mettre à jour la version dans * .wixproj. Existe-t-il un moyen d'accéder à une version de dll dans ce domaine?
RDV
@RDV L'intention de cette approche est de ne modifier aucun fichier dans le contrôle de code source, y compris le .wixproj. Le numéro de version dynamique est fourni par votre système CI (AppVersion et BuildNumber dans cet exemple). En règle générale, vous définissez les numéros de version majeure et mineure en tant que variables CI et laissez le système CI générer le numéro de version de manière dynamique.
Edward Brey
Excellent - juste le type de solution dont j'avais besoin, y compris une valeur par défaut pour les versions locales.
ColH