web-dev-qa-db-fra.com

Comment afficher le numéro de version de ClickOnce sur Windows Forms

J'ai une application Windows Forms qui est déployée à deux endroits différents.

  • Intranet - ClickOnce
  • Internet - installé sur une batterie de serveurs Citrix via le programme d'installation de Windows

J'affiche le numéro de version de ClickOnce pour la version déployée en une seule foisApplicationDeployment.IsNetworkDeployed.

if (ApplicationDeployment.IsNetworkDeployed)
        return ApplicationDeployment.CurrentDeployment.CurrentVersion;

Mais pour l'application sans clic, je ne sais pas comment récupérer la version de clickonce à moins que je code en dur le numéro de version dans les informations d'assemblage.

Existe-t-il un moyen automatique de récupérer le numéro de version de ClickOnce pour la version déployée non-clickonce?

62
Sung M. Kim

Non, je ne crois pas qu'il existe un moyen. Je crois que les informations ClickOnce proviennent du manifeste qui ne sera disponible que dans un déploiement ClickOnce. Je pense que coder en dur le numéro de version est votre meilleure option.

11
JaredPar
  1. Ajoutez une référence d'assembly à System.Deployment à votre projet.

  2. Importez l'espace de noms dans votre fichier de classe:

    VB.NET:

    Imports System.Deployment
    

    C #:

    using System.Deployment;
    
  3. Récupérez la version ClickOnce de la propriété CurrentVersion.

    Vous pouvez obtenir la version actuelle à partir du ApplicationDeployment.CurrentDeployment.CurrentVersion propriété. Cela renvoie un System.Version objet.

    Remarque (à partir de MSDN):

    CurrentVersion sera différent de UpdatedVersion si une nouvelle mise à jour a été installée mais que vous n'avez pas encore appelé Restart. Si le manifeste de déploiement est configuré pour effectuer des mises à jour automatiques, vous pouvez comparer ces deux valeurs pour déterminer si vous devez redémarrer l'application.

    REMARQUE: la propriété statique CurrentDeployment n'est valide que lorsque l'application a été déployée avec ClickOnce. Par conséquent, avant d'accéder à cette propriété, vous devez vérifier le ApplicationDeployment.IsNetworkDeployed propriété en premier. Il retournera toujours un faux dans l'environnement de débogage.

    VB.NET:

    Dim myVersion as Version
    
    If ApplicationDeployment.IsNetworkDeployed Then
       myVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion
    End If
    

    C #:

    Version myVersion;
    
    if (ApplicationDeployment.IsNetworkDeployed)
       myVersion = ApplicationDeployment.CurrentDeployment.CurrentVersion;
    
  4. Utilisez l'objet Version:

    À partir de là, vous pouvez utiliser les informations de version dans une étiquette, par exemple sur un formulaire "À propos", de cette manière:

    VB.NET:

    versionLabel.Text = String.Concat("ClickOnce published Version: v", myVersion)
    

    C #:

    versionLabel.Text = string.Concat("ClickOnce published Version: v", myVersion);
    

    (Version les objets sont formatés comme un numéro en quatre parties (major.minor.build.revision).)

96
cpg

Je voudrais simplement rendre la version Assembly de l'assembly principal identique à la version CLickOnce chaque fois que vous sortez une nouvelle version. Ensuite, lorsqu'il s'exécute en tant qu'application non-clickonce, utilisez simplement Reflection pour choisir la version de l'assembly.

8
RobinDotNet

Essayez la vérification des threads:

if (ApplicationDeployment.IsNetworkDeployed)
{
    if (ApplicationDeployment.CurrentDeployment.CurrentVersion != ApplicationDeployment.CurrentDeployment.UpdatedVersion)
    {
        Application.ExitThread();
        Application.Restart();
    }
}
4
Vitor Guerreiro

pas que cela compte trois ans plus tard, mais j'ai fini par analyser le fichier manifeste avec un lecteur xml.

2
gev

Code dur, ou ... Gardez une trace de vos versions (Fichier, Assemblage, Déployer) dans une base de données. Appelez la base de données avec votre assembly et obtenez la version Deploy.

Cela suppose que vous incrémentez vos versions de manière logique de sorte que chaque type de version ait une relation. C'est beaucoup de travail pour un problème aussi mineur. J'irais personnellement avec la solution de Jared; même si je déteste tout codage dur.

2
Billy Coover

Pour étendre la solution de RobinDotNet:

Protip: vous pouvez exécuter automatiquement un programme ou un script pour le faire à votre place depuis la configuration MSBuild du fichier .csproj à chaque génération. J'ai fait cela pour une application Web que je gère actuellement, exécutant un script Shell Cygwin bash pour effectuer un contrôle de version h4x pour calculer un numéro de version à partir de l'historique Git, puis prétraiter le fichier source d'informations d'assemblage compilé dans la sortie de la génération.

Une opération similaire pourrait être effectuée pour analyser le numéro de version ClickOnce du fichier de projet, c'est-à-dire Project.PropertyGroup.ApplicationRevision Et Project.PropertyGroup.ApplicationVersion (Bien que je ne sache pas ce que signifie la chaîne de version, mais vous pouvez simplement deviner jusqu'à ce qu'il se casse et le réparer ensuite) et insérez ces informations de version dans les informations d'assemblage.

Je ne sais pas quand la version ClickOnce est déclenchée, mais probablement après le processus de construction, vous devrez peut-être bricoler avec cette solution pour obtenir le nouveau numéro compilé. Je suppose qu'il y a toujours /*h4x*/ +1.

J'ai utilisé Cygwin parce que les scripts * nix sont bien meilleurs que Windows et le code interprété vous évite de construire votre programme de pré-construction avant de construire , mais vous pourrait écrire le programme en utilisant la technologie que vous vouliez (y compris C # /. NET). La ligne de commande du préprocesseur va dans le PreBuildEvent:

<PropertyGroup>
  <PreBuildEvent>
    $(CYGWIN_ROOT)bin\bash.exe --login -c refresh-version
  </PreBuildEvent>
</PropertyGroup>

Comme vous pouvez l'imaginer, cela se produit avant l'étape de génération afin que vous puissiez prétraiter efficacement votre code source juste avant de le compiler. Je ne voulais pas éditer automatiquement le fichier Properties\AssemblyInfo.cs Donc pour jouer en toute sécurité, j'ai créé un fichier Properties\VersionInfo.base.cs Qui contenait un modèle de texte d'une classe avec des informations de version et était marqué comme BuildAction=None Dans les paramètres du projet afin qu'il ne soit pas compilé avec le projet:

using System.Reflection;
using EngiCan.Common.Properties;

[Assembly: AssemblyVersion("0.$REVNUM_DIV(100)$.$REVNUM_MOD(100)$.$DIRTY$")]
[Assembly: AssemblyRevisionIdentifier("$REVID$")]

(Une syntaxe d'espace réservé très pauvre et pauvre ressemblant aux variables d'environnement de Windows avec quelques h4x supplémentaires a été utilisée pour des raisons de simplicité/complexité)

AssemblyRevisionIdentifierAttribute était un attribut personnalisé que j'ai créé pour contenir le Git SHA1 car il est beaucoup plus significatif pour les développeurs que a.b.c.d .

Mon programme refresh-version Copiera alors ce fichier dans Properties\VersionInfo.cs, Puis effectuera la substitution des informations de version qu'il a déjà calculées/analysées (j'ai utilisé sed(1) pour la substitution, qui était un autre avantage à utiliser Cygwin). Properties\VersionInfo.cs A été compilé dans le programme. Ce fichier peut commencer vide et vous devez l'ignorer par votre système de contrôle de version car il change automatiquement et les informations pour le générer sont déjà stockées ailleurs.

2
bambams

Faire une vérification de thread, insérer du code harded ...

1
Lg999

À l'aide d'un composant de génération, vous pouvez lire la version à clic unique du fichier de projet et l'écrire automatiquement dans les informations d'assemblage afin que les deux soient synchronisés.

1
Wilhelm