• Intégrer ClickOnce à une compilation TeamBuild

    Eh bien, pour une journée de réunions, on peut dire que le résultat est plus productif que d’habitude ! Entre deux réunions de gestion de projet, j’ai en effet pu mettre en place une chose qui manquait depuis plusieurs mois à l’un de mes partenaires : une automatisation complète de son processus de Build, allant jusqu’à l’élaboration de la release ClickOnce.

    Voici donc un petit guide, basé sur les “découvertes” de cette journées pour obtenir un déploiement ClickOnce au cours d’un Build automatisé. Ces informations sont plus qu’inspirées par Tim Hibbard, en fait on pourrait presque dire qu’il s’agit d’une version traduite et mise à jour de ses instructions.

    Premier point important, récupérez le MSBuild Extension pack à partir de Codeplex et installez les sur chacun des serveurs/postes que vous utiliserez pour compiler vos projets.

    Une fois ce composant indispensable récupéré, il va falloir modifier le fichier tfsbuild.proj correspondant à votre build :

    • pour ajouter des références aux extensions. Ici deux solutions : soit se conformer aux instructions de Tim Hibbard, et créer un PropertyGroup spécifique à ClickOnce, soit – et c’est cette solution qui sera détaillé ci-après – utiliser la tâche AssemblyInfo et ses dérivés pour gérer à la fois ClickOnce et les versions des assemblies. Il vous faudra donc ajouter deux lignes, dans la partie “imports”
       1: <Import Project="$(MSBuildExtensionsPath)\ExtensionPack\MSBuild.
    ExtensionPack.tasks"
    />
       2: <Import Project="$(MSBuildExtensionsPath)\ExtensionPack\MSBuild.
    ExtensionPack.VersionNumber.targets"
    />
    • Puis définir le property group nécessaire à mettre à jours les versions des assemblies (et de click once)
       1: <!-- Properties for controlling the Assembly Version -->
       2: <PropertyGroup>
       3:   <AssemblyMajorVersion>9</AssemblyMajorVersion>
       4:   <AssemblyMinorVersion>0</AssemblyMinorVersion>
       5:   <AssemblyBuildNumber>0</AssemblyBuildNumber>
       6:   <AssemblyRevision>1</AssemblyRevision>
       7: </PropertyGroup>
       8:  
       9: <!-- Properties for controlling the Assembly File Version -->
      10: <PropertyGroup>
      11:   <AssemblyFileMajorVersion>9</AssemblyFileMajorVersion>
      12:   <AssemblyFileMinorVersion>0</AssemblyFileMinorVersion>
      13:   <AssemblyFileBuildNumber>0</AssemblyFileBuildNumber>
      14:   <AssemblyFileRevision>1</AssemblyFileRevision>
      15: </PropertyGroup>
    • Nous allons ensuite un peu ruser pour mettre à jour le FileRevision, en effet, le partenaire en question utilise un schéma de numéros du type “année”.”release”.”itération interne”.”version de compilation” depuis un certain temps (par exemple 9.0.3.228 signifie “version 2009, release 1, itération N°3 du 28/02). Il a donc fallu contourner les limitations de la tâche AssemblyInfo :
       1: <Target Name="VersionPublish">
       2:   <MSBuild.ExtensionPack.Framework.DateAndTime TaskAction="Get" 
       3:                                                Format="MMdd">
       4:     <Output TaskParameter="Result" 
       5:           PropertyName="AssemblyFileRevision" />
       6:   </MSBuild.ExtensionPack.Framework.DateAndTime>
       7: </Target>
       8:  
       9: <Target Name="BeforeCompile" DependsOnTargets="VersionPublish">
      10:   <Message Text="FileVersion générée par le VersionNumber.Targets 
      11:            $(AssemblyFileMajorVersion).$(AssemblyFileMinorVersion).
      12:            $(AssemblyFileBuildNumber).$(AssemblyFileRevision)" />
      13: </Target>

    Comme vous devez vous en douter, le deuxième noeud ne sert qu’à tracer dans le fichier de génération le numéro généré… c’est assez pratique pour débugger, donc autant le mettre :)

    • reste ensuite à dire à TeamBuild de publier une version de l’application :
       1: <Target Name="AfterCompile">
       2:   <MSBuild Projects="$(SolutionRoot)\project.csproj"
       3:   Properties="PublishDir=$(OutDir)publish\;InstallFrom=Web;
       4:     UpdateRequired=true;InstallUrl=...;
       5:     MinimumRequiredVersion=$(AssemblyFileMajorVersion)
       6:     .$(AssemblyFileMinorVersion)
       7:     .$(AssemblyFileBuildNumber).$(AssemblyFileRevision);
       8:     ApplicationVersion=$(AssemblyFileMajorVersion)
       9:     .$(AssemblyFileMinorVersion).
      10:     $(AssemblyFileBuildNumber).$(AssemblyFileRevision)"
      11:   Targets="Publish" />
      12: </Target>

    Si vous avez besoin de modifier des options de publication, le plus simple est probablement d’ouvrir votre fichier .csproj dans un notepad et de regarder le nom des différents paramètres, en tout cas, c’est comme cela que j’ai trouvé les “MinimumRequiredVersion” ou autre “InstallUrl”.

    Voila, avec ces quelques lignes en plus, vous aurez un très joli dossier publish/ dans le dossier de sortie de votre définition de build. Il existe peut-être une solution plus pratique que le “<MSBuild… Targets=’publish’ />”, mais c’est ce que j’ai trouvé de plus pratique et de plus facile à mettre en place pour le moment…

  • snifff, IE 8 ne permet plus un bug que j’aimais bien…

    Si vous venez sur ce site avec un navigateur comme Chrome, Firefox ou autre, vous ne saurez pas de quoi je parle, mais une des différences d’affichage entre IE7 et le reste du monde était sa “capacité” à tronquer un texte en exploitant un bug CSS… IE8 semble avoir corrigé ce bug, il ne me reste donc plus qu’a chercher si on peut faire la même chose en CSS valide…

    Le rendu sous IE7 :

    sousie7

    Sous IE8 :

    sousie8

  • Microsoft Expression Web SuperPreview for Internet Explorer

    Ehhhh bah, si ca c’est pas du nom made in Microsoft, je ne vois pas ce que c’est ! il manque un petit “R2 with service pack 1” pour compléter le titre du nom d’application le plus long de l’histoire !

    Microsoft Expression Web SuperPreview for Internet Explorer R2 with Service Pack 2 Release Candidate 1, ca en jetterai un max !! d’autant plus que ca donne une super abréviation : MEWSPIER2SP2RC1 !

    Tout ça pour dire que vous devriez lire le post de Long Zheng, sur le futur ajout à Expression Web (à ce propos, il trouve ce nom particulièrement bon aussi !).

  • Jeudi… on doit être jeudi…

    D’aucuns abhorrent le lundi, mais moi c’est surtout le jeudi que j’ai du mal à supporter… Et encore une fois, aujourd'hui, ce jour maudit m’a donné des raisons de le haïr :)

    Un petit résumé de la situation, histoire de vous faire rire un peu… Nous possédons 3 serveurs que l’on pourraient qualifier de serveurs d’infrastructure : black, blue et orange. Le premier (black) est notre serveur ActiveDirectory principal, serveur DHCP et DNS; il s’agit d’une  machine assez ancienne, qui ne fait donc pas grand chose… Blue, en plus de son rôle de serveur “secondaire” AD fait aussi office de serveur de fichiers. Enfin, orange est notre serveur Exchange. Imaginez maintenant que, suite à une coupure électrique et à un problème d’onduleur, black fasse un drôle de bruit et blue n’en fasse absolument plus (alimentation grillée)…. Vous avez compris, nous sommes bel et bien jeudi ! :)

    Tout cela pour dire que, si vous avez besoin un jour de transférer en urgence la responsabilité d’ActiveDirectory à partir d’un serveur qui n’est plus en ligne, vous aurez besoin des articles de base de connaissance suivants :
    - 216498 : Comment faire pour supprimer des données dans Active Directory après l'échec d'une rétrogradation de contrôleur de domaine
    - 255504 : Utilisation de Ntdsutil.exe pour prendre ou transférer des rôles FSMO vers un contrôleur de domaine
    - 324801 : Comment faire pour afficher et transférer des rôles FSMO dans Windows Server 2003

    Vous aurez certainement aussi besoin de l’outil DCDIAG.exe et peut être de nltest.exe…

    Bonne chance :)

  • Pourquoi continuer à conserver l’edit and continue dans Visual Studio ?

    Je me demande vraiment si quelqu’un arrive encore à se servir de l’edit&continue dans VS, et si cela vaut donc encore la peine de le conserver… Voici quelques exemples de cas où il est impossible de s’en servir :

    • le code est compilé en 64bits (en anyCPU si vous êtes sur une machine 64bits)
    • le code est “optimisé” (elle me fait toujours rire celle-la…)
    • vous avez changé une classe d’un projet dépendant depuis une autre instance de VS ou notepad ou autre
    • la solution contient un projet Silverlight
    • vous venez de modifier une méthode intégrant une expression lambda ou une méthode anonyme (de plus en plus fréquent, surtout si vous faites du WPF et avez donc beaucoup de traitements asynchrones)
    • la Lune est en conjonction avec Saturne (ouais, non, pas celle là en fait…)

    Grosso modo, neuf fois sur dix, quand on veux modifier une méthode ça coince, la question est donc posée : à quoi cela sert-il ?