DSL Factory

La communauté francophone autour des DSL Tools, et de l'extensibilité Visual Studio
The French-speaking community about DSL Tools and Visual Studio Extensibility
Bienvenue à DSL Factory Identification | Inscription | Aide
dans
Accueil Blogs Forums Photos Fichiers Roller

Jean-Marc

Migrer un DSL de Visual Studio 2005 vers Visual Studio 2008

Les DSL çà se migre bien !

Tout d'abord, je voudrais vous souhaiter une excellente année 2008. Nous avons été un peu négligents, ces temps-ci, vis à vis de la communauté. Nous étions, Alain, Sébastien et moi en train de nous remettre du VSX Day (et çà vous a laissé le temps d'en digirer tout le contenu ;-)).

Mais il était prévu qu'on aborde un peu plus en détails le VS SDK de VS 2008 en début d'année, alors allons-y !

 

Nico a demandé, (fin novembre - honte à nous !),

"Est ce que l'on a une idée de la compatibilité des DSL fait en VS 2005 avec VS 2008 ?
Pour l'instant, l'installation ne fonctionne pas (le setup généré réclame VS 2005).
Faut-il recompiler le projet en VS 2008 ? Est ce que tout le méta-modèle est compatible ?
"

Je viens seulement de m'intéresser à la migration de mon plus gros DSL (en terme de classes, mais çà, ce n'est pas très important, puisque c'est du code qui est généré généré, mais surtout en terme de volume code custom).  En supposant que le SDK 2008 est installé dans C:\Program Files\Microsoft Visual Studio 2008 SDK, j'ai suivi la procédure expliquée dans le fichier C:\Program Files\Microsoft Visual Studio 2008 SDK\VisualStudioIntegration\Tools\DSLTools\MigrationGuide.htm, et çà m'a pris même pas deux heures, j'ai eu une nouvelle PLK en 5 minutes, et çà a parfaitement marché du premier coup. Mes modèles existants se sont parfaitement ouverts dans VS 2008, et tout fonctionne comme avant. Je m'y attendais, pour tout vous dire, mais l'équipe DSLTools a encore fait fort.

Je suis donc en mesure de répondre :

"Est ce que l'on a une idée de la compatibilité des DSL fait en VS 2005 avec VS 2008 ? " oui : elle me semble parfaite.

"Faut-il recompiler le projet en VS 2008 ?" Oui, mais c'est un peu plus compliqué que çà.

"Est ce que tout le méta-modèle est compatible ?" le .dsl l'est. Le méta-modèle aussi, il le semble !

La procédure de migration - retour d'expérience

Alors pourquoi çà m'a pris quand même deux heures ? je vais l'expliquer, et pour çà je vais migrer avec vous un autre DSL que vous connaissez : le DSL WCF Language.

Le guide de migration nous dit qu'il faut :

Première étape : créer un nouveau DSL minimal avec Visual Studio 2008 en lui donnant le même nom de DSL et le même nom de namespace que le DSL à migrer. Ces informations peuvent se trouver dans le fichier dsldefinition.dsl original (ou encore dans les propriétés du DSL que vous trouverez dans la fenêtre des propriétés en cliquant sur le fond diagramme que constitue la définition de votre DSL  : propriétés Name (WcfLanguage) et Namespace (DslFactory.WcfLanguage)).

 

 


    • Première surprise : la solution a changé, on a des fichiers en plus :
      • ils concernent la suppression de warning lors de l'analyse statique de code.
      • Par ailleurs, le répertoire CtcComponents et son horrible fichier Commands.ctc du projet DslPackage a été remplacé par un fichier Commands.vsct qui décrit les menus au format XML.



    • Deuxième surprise : si vous exécutez le DSL, vous verrez que les formes sont plus belles, et plus fines qu'auparavant (les icônes par défaut ont également changé)

 


 

Deuxième étape : remplacer les fichiers dsldefinition.dsl et dsldefinition.dsl.diagram de la nouvelle solution sous Visual Studio 2008, par ceux de la version 2005, ainsi que le contenu des répertoires Resources des deux projets Dsl et DslPackage. C'est important parce que les ressources, notamment les images, seront référencées par le code généré à partir du .dsl.

Il est possible que vous ayiez également à ajouter des références au projets si vous utilisez des Domain Types externes (c'est le cas pour le WcfLanguage où nous utilisons les types AdressFilterMode de System.ServiceModel et IsolationLevel de System.Transactions, il nous faut donc référencer ces deux assemblages.

Si vous avez des propriétés dont le Kind est CustomStorage, vous devrez aussi recopier du code custom. Comme le WCF Language est bien structuré, il nous suffit d'ajouter le répertoire "CustomCode", ainsi que le fichier Resources.resX que nous avions ajouté dans le répertoire de solution Properties en lui donnant comme propriété "Custom Tool" la valeur ResXFileCodeGenerator

 

 

 

Troisième étape : l'ajout de références

Si votre projet était simple, vous n'auriez éventuellement aucune référence à ajouter, ou bien uniquement des références à des assemblages qui ne sont pas concernés par le changement de Visual Studio. Par contre, dans le cas du WcfLanguage, nous avons des références à DslFactory.Utilities (qui aura été migré de la même façon), EnvDTE, et EnvDTE80. Il faut donc ajouter ces références aux assemblages EnvDTE, mais en prenant bien garde à ce que cela soit ceux de Program Files\Microsoft Visual Studio 9 et pas de Visual Studio 8. Dans le cas du WCF Language, il faut aussi ajouter VSLangProj en prenant les mêmes précautions (même si l'assemblage de même numéro de version peut aussi se trouver en d'autres endroits, comme dans Visual Studio 8) [il faut vous dire que sur ma machine, j'ai encore conservé Visual Studio 2005 et son VS SDK 4.0 à coté de Visual Studio 2008 et son VS SDK 1.0, c'est pourquoi je pourrais me tromper en ajoutant les références. Si vous n'avez que le VS SDK 2008, vous n'aurez pas ce problème]

 

Quatrième étape : transformer tous les templates, générer le DSL et l'exécuter.

Et çà marche !

 

Quatrième étape : Migrer les boutons, menus contextuels.

Il nous reste une chose à faire : notre DSL n'a pas encore retrouvé les menus contextuels sur ses formes. Dans la solution pour Visual Studio 2005, deux fichiers étaient concernés :

GeneratedCmd.tt qui contenait la définition des ids des boutons (generate, showAsRole, etc ...)

<#@ Dsl processor="DslDirectiveProcessor" requires="fileName='..\..\Dsl\DslDefinition.dsl'" #>

<#@ include file="DslPackage\GeneratedCmd.tt" #>

#define guidCmdSet { 0xe642d46e, 0x89bf, 0x4dd6, { 0xbe, 0x00, 0x81, 0x8f, 0x27, 0x92, 0xfc, 0x1b } }

#define generate 0x100

#define showAsRole 0x101

#define showAsMember 0x102

#define hide 0x103

#define showHiddenMembers 0x104
#define showUsedConcepts 0x105

 

et Commands.ctc du répertoire CtcComponents

#include "stdidcmd.h"

#include "vsshlids.h"

#include "msobtnid.h"

#include "virtkeys.h"

#include "DSLToolsCmdID.h"

#include "..\GeneratedCode\GeneratedCmd.h"

 

CMDS_SECTION guidPkg

 

 MENUS_BEGIN

  GENERATED_MENUS

           // Add additional menu definitions here.

           // NewMenu, Relative to Group, Priority, Type, Name, Text;

 MENUS_END

 

 NEWGROUPS_BEGIN

  GENERATED_GROUPS

           // Add additional menu group definitions here.

           // NewGroup, Parent Group, Priority;

 NEWGROUPS_END

 

  BUTTONS_BEGIN

   GENERATED_BUTTONS

   // Add additional button definitions here.

   // Command, Parent Group, Priority, Image, Type, Visibility, Text;

   guidCmdSet:generate, guidCmdSet:grpidContextMain,  0x0200, OI_NOID, BUTTON,      DIS_DEF, "Generate code" ;

   guidCmdSet:showAsRole, guidCmdSet:grpidContextMain,  0x0200, OI_NOID,      BUTTON,      DIS_DEF, "Show as a role" ;

   guidCmdSet:showAsMember, guidCmdSet:grpidContextMain,  0x0200, OI_NOID,    BUTTON,      DIS_DEF, "Show as a member" ;

   guidCmdSet:hide, guidCmdSet:grpidContextMain,  0x0200, OI_NOID,     BUTTON,      DIS_DEF, "Hide the member" ;

   guidCmdSet:showHiddenMembers, guidCmdSet:grpidContextMain,  0x0200, OI_NOID,      BUTTON,    DIS_DEF, "Show hidden members" ;      

   guidCmdSet:showUsedConcepts, guidCmdSet:grpidContextMain,  0x0200, OI_NOID,       BUTTON,    DIS_DEF, "Show used concepts" ;

   guidCmdSet:showAsRole, guidCmdSet:grpidExplorerMenuGroup,  0x0200, OI_NOID,       BUTTON,    DIS_DEF, "Show as a role" ;

   guidCmdSet:showAsMember, guidCmdSet:grpidExplorerMenuGroup,  0x0200, OI_NOID,     BUTTON,    DIS_DEF, "Show as a member" ;

   guidCmdSet:hide, guidCmdSet:grpidExplorerMenuGroup,  0x0200, OI_NOID,      BUTTON,      DIS_DEF, "Hide the member" ;

 

 BUTTONS_END

 

BITMAPS_BEGIN

BITMAPS_END

 

CMDS_END

 

CMDUSED_SECTION

CMDUSED_END

 

CMDPLACEMENT_SECTION

    GENERATED_CMDPLACEMENT

    // Add additional command placements here.

    // Command, Group, Priority;

CMDPLACEMENT_END

 

VISIBILITY_SECTION

    GENERATED_VISIBILITY

    // Add additional visibility definitions here.

    // Command, GUID when visible;

VISIBILITY_END

 

KEYBINDINGS_SECTION

    // Command, when available, emulation, keystate;

KEYBINDINGS_END

 

 

Ces deux fichiers étaient assez embêtants à maintenir parce que non seulement le format du fichier .ctc n'était pas très intuitif, mais en plus il fallait garder la cohérence entre les deux.

 

Avec le VS SDK 2008, le fichier .ctc a été remplacé par le fichier Commands.vsct qu'il nous faut donc remplir

Avant d'ajouter les commandes, ce fichier a le contenu suivant :

<?xml version="1.0" encoding="utf-8"?>

<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <!-- -->

  <!-- This file contains custom command definitions. -->

  <!-- -->

  <!-- NOTE: Each time commands are added or changed, the "version" parameter to the -->

  <!-- ProvideMenuResource attribute in Shell\Package.tt should be incremented. -->

  <!-- This causes Visual Studio to re-merge the menu definitions for the package. -->

  <!-- Otherwise, changes won't take effect until the next time devenv /setup is run. -->

  <!-- -->

  <Extern href="stdidcmd.h"/>

  <Extern href="vsshlids.h"/>

  <Extern href="msobtnid.h"/>

  <Extern href="virtkeys.h"/>

  <Extern href="DSLToolsCmdID.h"/>

  <Include href="GeneratedCode\GeneratedVsct.vsct"/>

  <Commands package="guidPkg">

  </Commands>

</CommandTable>

 

Il nous suffit donc de migrer le contenu du .ctc et du .h dans le .vsct :

  • D'abord les identifiants des commandes.En s'aidant du fichier GeneratedVSCT.vsct généré, on obtient la fin du fichier suivante où les #define ont été remplacés par des IDSymbol. Le guid du guidCmdSet est recopié tel quel du GeneratedVSCT.vsct :

  <Commands package="guidPkg">

  </Commands>

  <Symbols>

    <GuidSymbol name="guidCmdSet" value="{78ec39e2-7285-479d-8796-f465a1f4563e}" >

      <IDSymbol name="generate" value="0x100"/>

      <IDSymbol name="showAsRole" value="0x101"/>

      <IDSymbol name="hide" value="0x103"/>

      <IDSymbol name="showHiddenMembers" value="0x104"/>

      <IDSymbol name="showUsedConcepts" value="0x105"/>

    </GuidSymbol>

  </Symbols>

</CommandTable>

 

Ensuite, nous écrivons les boutons :

 

A titre d'exemple, la ligne suivante du .ctc :

  guidCmdSet:generate, guidCmdSet:grpidContextMain,  0x0200, OI_NOID,    BUTTON,    DIS_DEF, "Generate code" ;

 

devient le texte en gras suivant :

 

  <Commands package="guidPkg">

    <Buttons>

      <Button guid="guidCmdSet" id="generate" priority="0x0200" type="Button">

        <Parent guid="guidCmdSet" id="grpidContextMain"/>

        <CommandFlag>DefaultDisabled</CommandFlag>

        <CommandFlag>DefaultInvisible</CommandFlag>

        <CommandFlag>DynamicVisibility</CommandFlag>

        <Strings>

          <ButtonText>Generate code</ButtonText>

        </Strings>

      </Button>

 

    </Buttons>

 

Pour finir, le fichier devient :

<?xml version="1.0" encoding="utf-8"?>

<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <!-- -->

  <!-- This file contains custom command definitions. -->

  <!-- -->

  <!-- NOTE: Each time commands are added or changed, the "version" parameter to the -->

  <!-- ProvideMenuResource attribute in Shell\Package.tt should be incremented. -->

  <!-- This causes Visual Studio to re-merge the menu definitions for the package. -->

  <!-- Otherwise, changes won't take effect until the next time devenv /setup is run. -->

  <!-- -->

  <Extern href="stdidcmd.h"/>

  <Extern href="vsshlids.h"/>

  <Extern href="msobtnid.h"/>

  <Extern href="virtkeys.h"/>

  <Extern href="DSLToolsCmdID.h"/>

  <Include href="GeneratedCode\GeneratedVsct.vsct"/>

  <Commands package="guidPkg">

    <Buttons>

      <Button guid="guidCmdSet" id="generate" priority="0x0200" type="Button">

        <Parent guid="guidCmdSet" id="grpidContextMain"/>

        <CommandFlag>DefaultDisabled</CommandFlag>

        <CommandFlag>DefaultInvisible</CommandFlag>

        <CommandFlag>DynamicVisibility</CommandFlag>

        <Strings>

          <ButtonText>Generate code</ButtonText>

        </Strings>

      </Button>

 

      <Button guid="guidCmdSet" id="showAsRole" priority="0x0200" type="Button">

        <Parent guid="guidCmdSet" id="grpidContextMain"/>

        <CommandFlag>DefaultDisabled</CommandFlag>

        <CommandFlag>DefaultInvisible</CommandFlag>

        <CommandFlag>DynamicVisibility</CommandFlag>

        <Strings>

          <ButtonText>Show as a role</ButtonText>

        </Strings>

      </Button>

 

 

      <Button guid="guidCmdSet" id="showAsMember" priority="0x0200" type="Button">

        <Parent guid="guidCmdSet" id="grpidContextMain"/>

        <CommandFlag>DefaultDisabled</CommandFlag>

        <CommandFlag>DefaultInvisible</CommandFlag>

        <CommandFlag>DynamicVisibility</CommandFlag>

        <Strings>

          <ButtonText>Show as a member</ButtonText>

        </Strings>

      </Button>

 

      <Button guid="guidCmdSet" id="hide" priority="0x0200" type="Button">

        <Parent guid="guidCmdSet" id="grpidContextMain"/>

        <CommandFlag>DefaultDisabled</CommandFlag>

        <CommandFlag>DefaultInvisible</CommandFlag>

        <CommandFlag>DynamicVisibility</CommandFlag>

        <Strings>

          <ButtonText>Hide this member</ButtonText>

        </Strings>

      </Button>

 

      <Button guid="guidCmdSet" id="showHiddenMembers" priority="0x0200" type="Button">

        <Parent guid="guidCmdSet" id="grpidContextMain"/>

        <CommandFlag>DefaultDisabled</CommandFlag>

        <CommandFlag>DefaultInvisible</CommandFlag>

        <CommandFlag>DynamicVisibility</CommandFlag>

        <Strings>

          <ButtonText>Show hidden members</ButtonText>

        </Strings>

      </Button>

 

 

      <Button guid="guidCmdSet" id="showUsedConcepts" priority="0x0200" type="Button">

        <Parent guid="guidCmdSet" id="grpidContextMain"/>

        <CommandFlag>DefaultDisabled</CommandFlag>

        <CommandFlag>DefaultInvisible</CommandFlag>

        <CommandFlag>DynamicVisibility</CommandFlag>

        <Strings>

          <ButtonText>Show used concepts</ButtonText>

        </Strings>

      </Button>

 

 

      <Button guid="guidCmdSet" id="showAsRole" priority="0x0200" type="Button">

        <Parent guid="guidCmdSet" id="grpidContextMain"/>

        <CommandFlag>DefaultDisabled</CommandFlag>

        <CommandFlag>DefaultInvisible</CommandFlag>

        <CommandFlag>DynamicVisibility</CommandFlag>

        <Strings>

          <ButtonText>Show as a role</ButtonText>

        </Strings>

      </Button>

 

 

      <Button guid="guidCmdSet" id="showAsMember" priority="0x0200" type="Button">

        <Parent guid="guidCmdSet" id="grpidContextMain"/>

        <CommandFlag>DefaultDisabled</CommandFlag>

        <CommandFlag>DefaultInvisible</CommandFlag>

        <CommandFlag>DynamicVisibility</CommandFlag>

        <Strings>

          <ButtonText>Show as a member</ButtonText>

        </Strings>

      </Button>

 

 

      <Button guid="guidCmdSet" id="showAsMember" priority="0x0200" type="Button">

        <Parent guid="guidCmdSet" id="grpidContextMain"/>

        <CommandFlag>DefaultDisabled</CommandFlag>

        <CommandFlag>DefaultInvisible</CommandFlag>

        <CommandFlag>DynamicVisibility</CommandFlag>

        <Strings>

          <ButtonText>Show as a member</ButtonText>

        </Strings>

      </Button>

    </Buttons>

  </Commands>

  <Symbols>

    <GuidSymbol name="guidCmdSet" value="{78ec39e2-7285-479d-8796-f465a1f4563e}" >

      <IDSymbol name="generate" value="0x100"/>

      <IDSymbol name="showAsRole" value="0x101"/>

      <IDSymbol name="hide" value="0x103"/>

      <IDSymbol name="showHiddenMembers" value="0x104"/>

      <IDSymbol name="showUsedConcepts" value="0x105"/>

    </GuidSymbol>

  </Symbols>

</CommandTable>

 

Et vous voyez, le temps d'écrire tout çà ... c'est l'essentiel du temps pris.

 

Pensez bien, dans Package.tt à incrémenter le numéro de menu et de toolboxItems, pour que Visual Studio prenne en compte les nouveautés :

[VSShell::ProvideMenuResource("1000.ctmenu", 2)]
[VSShell::ProvideToolboxItems(2)]

Construisez le DSL, exécutez le : çà marche immédiatement :-) !

 

Cinquième étape demander une PLK.

Cette étape aussi a été grandement améliorée : il faut toujours aller sur le site www.vsipmembers.com, comme auparavant, pour demander la PLK. Par contre la grande nouveauté c'est que maintenant, on obtient la PLK immédiatement, et pas au bout de quelques jours.

 

Sixième étape, recréer un programme d'installation

Comme auparavant, on recrée un setup pour DSL, et on recopie éventuellement dans le contenu spécial du .dslsetup. Dans notre cas, il ne faut pas oublier DslFactory.Utilities comme SupportingAssembly, et les vsItemTemplate sont ajoutés avec plusieurs localeId (au moins l'américain et le Français ! : 1033 et 1036).

 

 

Un autre conseil

En recopiant le code custom du projet dslpackage, ne pas oublier les ProjectItemTemplates du projet dslpackage.

Conclusion

J'ai essayé de montré dans ce billet qu'il était vraiment simple de migrer un DSL de Visual Studio 2005 à Visual Studio 2008. Simple, et sans mauvaise surprise. J'ai apprécié le .vsct qui, notamment grâce à l'Intellisense, sont faciles à écrire, et faciles à lire ... très intuitifs.

 

Publié Saturday, January 12, 2008 11:21 AM par Jean-Marc
Classé sous : ,
Les commentaires anonymes sont désactivés

About Jean-Marc

Jean-Marc Prieur [MSFT - Visual Studio Ecosystem] Il est passionné de génie logiciel, de modélisation et de technologies informatiques, de réutilisation et de méthodologies

Calendrier des messages

<January 2008>
SuMoTuWeThFrSa
303112345
6789101112
13141516171819
20212223242526
272829303112
3456789

Abonnements

Propulsé par Community Server, par Telligent Systems